db2z 12 Apsgbook
db2z 12 Apsgbook
IBM
SC27-8845-02
Notes
Before using this information and the product it supports, be sure to read the general information under
"Notices" at the end of this information.
Subsequent editions of this PDF will not be delivered in IBM Publications Center. Always download the
latest edition from IBM Documentation.
2023-10-24 edition
This edition applies to Db2® 12 for z/OS® (product number 5650-DB2), Db2 12 for z/OS Value Unit Edition (product
number 5770-AF3), and to any subsequent releases until otherwise indicated in new editions. Make sure you are using
the correct edition for the level of the product.
Specific changes are indicated by a vertical bar to the left of a change. A vertical bar to the left of a figure caption
indicates that the figure has changed. Editorial changes that have no technical significance are not noted.
© Copyright International Business Machines Corporation 1983, 2022.
US Government Users Restricted Rights – Use, duplication or disclosure restricted by GSA ADP Schedule Contract with
IBM Corp.
Contents
iii
Forcing restricted system rules in your program.................................................................................33
iv
Determining which tables you have access to.................................................................................. 350
Displaying information about the columns for a given table............................................................ 351
Retrieving data by using the SELECT statement............................................................................... 352
Retrieving a set of rows by using a cursor......................................................................................... 396
Specifying direct row access by using row IDs................................................................................. 427
Ways to manipulate LOB data............................................................................................................428
Referencing a sequence object..........................................................................................................442
Retrieving thousands of rows............................................................................................................ 442
Determining when a row was changed..............................................................................................442
Checking whether an XML column contains a certain value.............................................................443
Accessing Db2 data that is not in a table.......................................................................................... 444
Ensuring that queries perform sufficiently........................................................................................444
Items to include in a batch DL/I program......................................................................................... 445
Invoking a user-defined function............................................................................................................ 447
How Db2 determines the authorization for invoking user-defined functions.................................. 448
Ensuring that Db2 executes the intended user-defined function.....................................................449
How Db2 resolves functions.............................................................................................................. 450
Checking how Db2 resolves functions by using DSN_FUNCTION_TABLE .......................................452
Restrictions when passing arguments with distinct types to functions........................................... 453
Cases when Db2 casts arguments for a user-defined function........................................................ 454
v
Dynamically executing an SQL statement by using PREPARE and EXECUTE...................................517
Dynamically executing a data change statement..............................................................................519
Dynamically executing a statement with parameter markers by using the SQLDA......................... 522
Checking the execution of SQL statements............................................................................................ 523
Checking the execution of SQL statements by using the SQLCA...................................................... 524
Checking the execution of SQL statements by using SQLCODE and SQLSTATE...............................528
Checking the execution of SQL statements by using the WHENEVER statement............................529
Checking the execution of SQL statements by using the GET DIAGNOSTICS statement ...............530
Handling SQL error codes........................................................................................................................536
Arithmetic and conversion errors...................................................................................................... 537
Writing applications that enable users to create and modify tables......................................................537
Saving SQL statements that are translated from user requests............................................................ 538
XML data in embedded SQL applications............................................................................................... 538
Host variable data types for XML data in embedded SQL applications............................................538
XML column updates in embedded SQL applications.......................................................................544
XML data retrieval in embedded SQL applications........................................................................... 546
Example programs that call stored procedures..................................................................................... 548
Assembler applications that issue SQL statements............................................................................... 548
Assembler programming examples...................................................................................................551
Defining the SQL communications area, SQLSTATE, and SQLCODE in assembler...........................551
Defining SQL descriptor areas (SQLDA) in assembler.......................................................................553
Declaring host variables and indicator variables in assembler........................................................ 554
Equivalent SQL and assembler data types........................................................................................ 560
Macros for assembler applications....................................................................................................567
Handling SQL error codes in assembler applications....................................................................... 567
C and C++ applications that issue SQL statements................................................................................568
C and C++ programming examples................................................................................................... 570
Defining the SQL communications area, SQLSTATE, and SQLCODE in C and C++........................... 579
Defining SQL descriptor areas (SQLDA) in C and C++....................................................................... 580
Declaring host variables and indicator variables in C and C++.........................................................580
Equivalent SQL and C data types....................................................................................................... 608
Handling SQL error codes in C and C++ applications........................................................................615
COBOL applications that issue SQL statements..................................................................................... 617
COBOL programming examples.........................................................................................................621
Defining the SQL communications area, SQLSTATE, and SQLCODE in COBOL................................ 646
Defining SQL descriptor areas (SQLDA) in COBOL............................................................................ 647
Declaring host variables and indicator variables in COBOL.............................................................. 648
Equivalent SQL and COBOL data types..............................................................................................675
Object-oriented extensions in COBOL...............................................................................................681
Handling SQL error codes in Cobol applications............................................................................... 681
Fortran applications that issue SQL statements.....................................................................................683
Defining the SQL communications area, SQLSTATE, and SQLCODE in Fortran................................ 685
Defining SQL descriptor areas in (SQLDA) Fortran............................................................................ 686
Declaring host variables and indicator variables in Fortran..............................................................686
Equivalent SQL and Fortran data types............................................................................................. 691
PL/I applications that issue SQL statements..........................................................................................694
PL/I programming examples............................................................................................................. 697
Defining the SQL communications area, SQLSTATE, and SQLCODE in PL/I..................................... 702
Defining SQL descriptor areas (SQLDA) in PL/I................................................................................. 703
Declaring host variables and indicator variables in PL/I...................................................................703
Equivalent SQL and PL/I data types.................................................................................................. 718
REXX applications that issue SQL statements........................................................................................724
REXX programming examples........................................................................................................... 726
Defining the SQL communications area, SQLSTATE, and SQLCODE in REXX................................... 741
Defining SQL descriptor areas (SQLDA) in REXX............................................................................... 742
Equivalent SQL and REXX data types................................................................................................ 742
Accessing the Db2 REXX language support application programming interfaces...........................744
Ensuring that Db2 correctly interprets character input data in REXX programs..............................746
vi
Passing the data type of an input data type to Db2 for REXX programs.......................................... 746
Setting the isolation level of SQL statements in a REXX program.................................................... 747
Retrieving data from Db2 tables in REXX programs..........................................................................748
Cursors and statement names in REXX............................................................................................. 749
Handling SQL error codes in REXX applications................................................................................749
vii
V11R1 application compatibility level.................................................................................................... 826
V10R1 application compatibility level.................................................................................................... 826
Managing application incompatibilities.................................................................................................. 829
Enabling default application compatibility with function level 500 or higher....................................... 830
viii
Chapter 10. Running an application on Db2 for z/OS........................................... 935
DSN command processor........................................................................................................................ 935
DB2I Run panel........................................................................................................................................936
Running a program in TSO foreground....................................................................................................937
Running a Db2 REXX application.............................................................................................................938
Invoking programs through the Interactive System Productivity Facility..............................................938
ISPF.................................................................................................................................................... 938
Invoking a single SQL program through ISPF and DSN.................................................................... 940
Invoking multiple SQL programs through ISPF and DSN..................................................................940
Loading and running a batch program.................................................................................................... 941
Authorization for running a batch DL/I program............................................................................... 942
Restarting a batch program............................................................................................................... 943
Running stored procedures from the command line processor.............................................................944
Command line processor CALL statement........................................................................................ 945
Example of running a batch Db2 application in TSO.............................................................................. 946
Example of calling applications in a command procedure.....................................................................947
Chapter 11. Testing and debugging an application program on Db2 for z/OS........ 949
Designing a test data structure............................................................................................................... 949
Analyzing application data needs...................................................................................................... 949
Authorization for test tables and applications.................................................................................. 951
Example SQL statements to create a comprehensive test structure............................................... 951
Populating the test tables with data....................................................................................................... 952
Methods for testing SQL statements.......................................................................................................952
Executing SQL by using SPUFI................................................................................................................ 953
Content of a SPUFI input data set..................................................................................................... 956
The SPUFI panel.................................................................................................................................957
Changing SPUFI defaults................................................................................................................... 958
Setting the SQL terminator character in a SPUFI input data set...................................................... 963
Controlling toleration of warnings in SPUFI...................................................................................... 964
Output from SPUFI.............................................................................................................................964
Testing an external user-defined function.............................................................................................. 966
Testing a user-defined function by using the Debug Tool for z/OS...................................................966
Testing a user-defined function by routing the debugging messages to SYSPRINT........................968
Testing a user-defined function by using driver applications........................................................... 968
Testing a user-defined function by using SQL INSERT statements..................................................968
Debugging stored procedures................................................................................................................. 969
Debugging stored procedures by using the Unified Debugger......................................................... 970
Debugging stored procedures with the Debug Tool for z/OS............................................................971
Recording stored procedure debugging messages in a file.............................................................. 972
Driver applications for debugging procedures.................................................................................. 973
Db2 tables that contain debugging information................................................................................973
Debugging an application program......................................................................................................... 973
Locating the problem in an application............................................................................................. 974
Techniques for debugging programs in TSO......................................................................................978
Techniques for debugging programs in IMS......................................................................................979
Techniques for debugging programs in CICS.................................................................................... 980
Finding a violated referential or check constraint.................................................................................. 983
Chapter 12. Sample data and applications supplied with Db2 for z/OS................ 985
Db2 sample tables...................................................................................................................................985
Activity table (DSN8C10.ACT)........................................................................................................... 985
Department table (DSN8C10.DEPT)..................................................................................................986
Employee table (DSN8C10.EMP).......................................................................................................988
Employee photo and resume table (DSN8C10.EMP_PHOTO_RESUME).......................................... 992
Project table (DSN8C10.PROJ)..........................................................................................................993
ix
Project activity table (DSN8C10.PROJACT)...................................................................................... 994
Employee-to-project activity table (DSN8C10.EMPPROJACT)........................................................ 995
Unicode sample table (DSN8C10.DEMO_UNICODE)........................................................................ 996
Relationships among the sample tables........................................................................................... 997
Views on the sample tables............................................................................................................... 998
Storage of sample application tables.............................................................................................. 1002
SYSDUMMYx tables..........................................................................................................................1005
Db2 productivity-aid sample programs................................................................................................ 1006
DSNTIAUL sample program.............................................................................................................1007
DSNTIAD sample program...............................................................................................................1012
DSNTEP2 and DSNTEP4 sample programs.....................................................................................1015
Sample applications supplied with Db2 for z/OS................................................................................. 1022
Types of sample applications.......................................................................................................... 1022
Application languages and environments for the sample applications......................................... 1024
Sample applications in TSO............................................................................................................. 1025
Sample applications in IMS............................................................................................................. 1344
Sample applications in CICS............................................................................................................1390
Information resources for Db2 for z/OS and related products............................ 1451
Notices............................................................................................................1453
Programming interface information......................................................................................................1454
Trademarks............................................................................................................................................1454
Terms and conditions for product documentation............................................................................... 1455
Privacy policy considerations................................................................................................................1455
Glossary.......................................................................................................... 1457
Index.............................................................................................................. 1459
x
About this information
This information discusses how to design and write application programs that access Db2 for z/OS (Db2),
a highly flexible relational database management system (DBMS).
Throughout this information, "Db2" means "Db2 12 for z/OS". References to other Db2 products use
complete names or specific abbreviations.
Important: To find the most up to date content for Db2 12 for z/OS, always use IBM® Documentation
or download the latest PDF file from PDF format manuals for Db2 12 for z/OS (Db2 for z/OS in IBM
Documentation).
Most documentation topics for Db2 12 for z/OS assume that the highest available function level is
activated and that your applications are running with the highest available application compatibility level,
with the following exceptions:
• The following documentation sections describe the Db2 12 migration process and how to activate new
capabilities in function levels:
– Migrating to Db2 12 (Db2 Installation and Migration)
– What's new in Db2 12 (Db2 for z/OS What's New?)
– Adopting new capabilities in Db2 12 continuous delivery (Db2 for z/OS What's New?)
• FL 501 A label like this one usually marks documentation changed for function level 500 or higher,
with a link to the description of the function level that introduces the change in Db2 12. For more
information, see How Db2 function levels are documented (Db2 for z/OS What's New?).
The availability of new function depends on the type of enhancement, the activated function level, and
the application compatibility levels of applications. In the initial Db2 12 release, most new capabilities are
enabled only after the activation of function level 500 or higher.
Virtual storage enhancements
Virtual storage enhancements become available at the activation of the function level that introduces
them or higher. Activation of function level 100 introduces all virtual storage enhancements in
the initial Db2 12 release. That is, activation of function level 500 introduces no virtual storage
enhancements.
Subsystem parameters
New subsystem parameter settings are in effect only when the function level that introduced them or
a higher function level is activated. Many subsystem parameter changes in the initial Db2 12 release
take effect in function level 500. For more information about subsystem parameter changes in Db2
12, see Subsystem parameter changes in Db2 12 (Db2 for z/OS What's New?).
Optimization enhancements
Optimization enhancements become available after the activation of the function level that introduces
them or higher, and full prepare of the SQL statements. When a full prepare occurs depends on the
statement type:
• For static SQL statements, after bind or rebind of the package
• For non-stabilized dynamic SQL statements, immediately, unless the statement is in the dynamic
statement cache
• For stabilized dynamic SQL statements, after invalidation, free, or changed application compatibility
level
Activation of function level 100 introduces all optimization enhancements in the initial Db2 12
release. That is, function level 500 introduces no optimization enhancements.
SQL capabilities
New SQL capabilities become available after the activation of the function level that introduces them
or higher, for applications that run at the equivalent application compatibility level or higher. New SQL
capabilities in the initial Db2 12 release become available in function level 500 for applications that
Accessibility features
The following list includes the major accessibility features in z/OS products, including Db2 for z/OS. These
features support:
• Keyboard-only operation.
• Interfaces that are commonly used by screen readers and screen magnifiers.
• Customization of display attributes such as color, contrast, and font size
Tip: IBM Documentation (which includes information for Db2 for z/OS) and its related publications are
accessibility-enabled for the IBM Home Page Reader. You can operate all features using the keyboard
instead of the mouse.
Keyboard navigation
For information about navigating the Db2 for z/OS ISPF panels using TSO/E or ISPF, refer to the z/OS
TSO/E Primer, the z/OS TSO/E User's Guide, and the z/OS ISPF User's Guide. These guides describe how
to navigate each interface, including the use of keyboard shortcuts or function keys (PF keys). Each guide
includes the default settings for the PF keys and explains how to modify their functions.
If an optional item appears above the main path, that item has no effect on the execution of the
statement and is used only for readability.
optional_item
required_item
• If you can choose from two or more items, they appear vertically, in a stack.
If you must choose one of the items, one item of the stack appears on the main path.
required_item required_choice1
required_choice2
If choosing one of the items is optional, the entire stack appears below the main path.
required_item
optional_choice1
optional_choice2
If one of the items is the default, it appears above the main path and the remaining choices are shown
below.
default_choice
required_item
optional_choice
optional_choice
• An arrow returning to the left, above the main line, indicates an item that can be repeated.
required_item repeatable_item
If the repeat arrow contains a comma, you must separate repeated items with a comma.
required_item repeatable_item
A repeat arrow above a stack indicates that you can repeat the items in the stack.
• Sometimes a diagram must be split into fragments. The syntax fragment is shown separately from the
main syntax diagram, but the contents of the fragment should be read as if they are on the main path of
the diagram.
required_item fragment-name
fragment-name
required_item
optional_name
• For some references in syntax diagrams, you must follow any rules described in the description for that
diagram, and also rules that are described in other syntax diagrams. For example:
– For expression, you must also follow the rules described in Expressions (Db2 SQL).
– For references to fullselect, you must also follow the rules described in fullselect (Db2 SQL).
– For references to search-condition, you must also follow the rules described in Search conditions
(Db2 SQL).
• With the exception of XPath keywords, keywords appear in uppercase (for example, FROM). Keywords
must be spelled exactly as shown.
• XPath keywords are defined as lowercase names, and must be spelled exactly as shown.
• Variables appear in all lowercase letters (for example, column-name). They represent user-supplied
names or values.
• If punctuation marks, parentheses, arithmetic operators, or other such symbols are shown, you must
enter them as part of the syntax.
Related concepts
Commands in Db2 (Db2 Commands)
Db2 online utilities (Db2 Utilities)
Db2 stand-alone utilities (Db2 Utilities)
The following incompatible changes apply at any Db2 12 function level, including when you first migrate
to Db2 12. For incompatible changes that might impact your Db2 12 environment when you activate
function levels 501 and higher, see Incompatible changes summary for function levels 501 and higher
(Db2 for z/OS What's New?).
SQL capabilities
New SQL capabilities become available after the activation of the function level that introduces them
or higher, for applications that run at the equivalent application compatibility level or higher. New SQL
capabilities in the initial Db2 12 release become available in function level 500 for applications that
run at the equivalent application compatibility level or higher. You can continue to run SQL statements
compatibly with lower function levels, or previous Db2 releases, including Db2 11 and DB2 10. For
details, see Chapter 8, “Application compatibility levels in Db2,” on page 815
Release incompatibilities that were changed or added since the first edition of this Db2 12 publication are
indicated by a vertical bar in the left margin. In other areas of this publication, a vertical bar in the margin
indicates a change or addition that has occurred since the Db2 11 release of this publication.
Actions to take
In Db2 12, before you set the SUBSTR_COMPATIBILITY subsystem parameter to CURRENT, identify
applications that are incompatible with this change by starting a trace for IFCID 0376 and then running
the applications. Review the trace output for incompatible changes with the identifier 14. Correct affected
applications so that they will be compatible if the SUBSTR_COMPATIBILITY subsystem parameter is set
to CURRENT in the future.
Related reference
SUBSTR COMPATIBILITY field (SUBSTR_COMPATIBILITY subsystem parameter) (Db2 Installation and
Migration)
Actions to take
If the storage group specified in a CREATE DATABASE statement does not exist, take one of the following
actions:
• Specify a USING clause at the table space or index level in any CREATE TABLESPACE or CREATE INDEX
statement that creates a table space or index in that database.
• Issue an ALTER DATABASE statement and specify STOGROUP clause that identifies a storage group that
exists.
Related reference
CREATE TABLESPACE (Db2 SQL)
CREATE INDEX (Db2 SQL)
CREATE DATABASE (Db2 SQL)
ALTER DATABASE (Db2 SQL)
2 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
New maximum number of parameter markers or host variables in a single
SQL statement
Db2 12 enforces the maximum number of parameter markers or host variables in a single SQL statement.
Starting in function level 100, Db2 12 issues SQLCODE -101 for any SQL statement that contains more
than 16,000 parameter markers or host variables.
Actions to take
Identify and modify any existing SQL statement that contains more than 16,000 parameter markers or
host variables.
Related reference
Limits in Db2 for z/OS (Db2 SQL)
Actions to take
Change the expected output for queries that reference this column.
Actions to take
Change the expected output for queries that reference this column.
Actions to take
Modify any applications that use the DSVOLSER column in the SYSCOPY catalog table to tolerate the
checkpoint information for cataloged, sequential, full image copies. For details, see the description of
DSVOLSER in SYSCOPY catalog table.
4 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Actions to take
By preparing for migration to Db2 12 in Db2 11, you can reduce the change and risk for packages that
are subject to automatic binds in Db2 12. To do that, you rebind all packages that were last bound
before DB2 10 in Db2 11, before you migrate to Db2 12. For more information about the impacts that
migration-related automatic rebinds can have in your Db2 environment and actions that you can take to
avoid them, see Rebind old plans and packages in Db2 11 to avoid disruptive autobinds in Db2 12 (Db2
Installation and Migration).
Related reference
AUTO BIND field (ABIND subsystem parameter) (Db2 Installation and Migration)
Related information
-908 (Db2 Codes)
-923 (Db2 Codes)
Actions to take
As you migrate to Db2 12, review packages that use the KEEPDYNAMIC(YES) bind option. You can
make dynamic SQL programs that are bound with KEEPDYNAMIC(YES) run more efficiently by removing
PREPARE statements that prepare SQL statements again, following execution of ROLLBACK statements.
Do not take this action until you are sure that you no longer need to run the programs in Db2 11 or earlier.
After migrating to Db2 12, if you take this action (to remove PREPARE statements after ROLLBACK),
programs will not work properly if you subsequently set application compatibility to V11R1 or earlier.
Related reference
KEEPDYNAMIC bind option (Db2 Commands)
Explanation
Before DB2 10, if a Java client called a Db2 for z/OS stored procedure, the data types of output arguments
matched the data types of the corresponding CALL statement arguments. Starting in DB2 10, the data
types of the output arguments match the data types of the parameters in the stored procedure definition.
In Db2 12, when application compatibility is set to V10R1, you can set the DDF_COMPATIBILITY
subsystem parameter to SP_PARMS_JV to keep the behavior that existed before DB2 10. However, when
application compatibility is set to V11R1 or V12R1M100, or to V12R1M500 or higher, SP_PARMS_JV is no
longer supported.
In Db2 12 with application compatibility set to V11R1 or V12R1M100, or to V12R1M500 or higher,
if the version of the IBM Data Server Driver for JDBC and SQLJ is lower than 3.63 or 4.13, a
java.lang.ClassCastException might be thrown when an output argument value is retrieved.
Actions to take
Take one of the following actions:
• Upgrade the IBM Data Server Driver for JDBC and SQLJ to version 3.63 or 4.13, or later.
• Modify the data types in CallableStatement.registerOutParameter method calls to match
the parameter data types in the stored procedure definitions. You can set application compatibility
to V10R1 and run a trace for IFCID 0376 to identify affected applications. Trace records for those
applications have a QW0376FN field value of 8.
Related concepts
Application compatibility levels in Db2
The application compatibility level of your applications controls the adoption and use of new capabilities
and enhancements, and the impact of incompatible changes. The advantage is that you can complete the
Db2 12 migration process without the need to update your applications immediately.
6 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Actions to take
Identify any packages that use UNION or UNION ALL in the from-clause of a SELECT INTO statement and
correct them as necessary. You can temporarily specify that Db2 continues to tolerate the invalid syntax
NO for the DISALLOW_SEL_INTO_UNION subsystem parameter. However, this subsystem parameter is
deprecated and expected to be removed in the future.
You can identify affected packages while DISALLOW_SEL_INTO_UNION is set to NO by binding suspected
packages into a dummy collection ID with EXPLAIN(ONLY) and monitoring IFCID 0376 records. Trace
records for the affected applications have a QW0376FN field value of 11.
Use the following procedure:
1. Issue the following SQL statement to generate a list of BIND commands.
2. Copy the results of the SELECT statement into a bind job. If any BIND subcommands are longer than
72 bytes, formatting is required.
3. Start and collect a trace for IFCID 0376.
4. Run the bind job that you created.
5. Stop the IFCID 0376 trace and analyze the output.
Related reference
DISALLOW_SEL_INTO_UNION in macro DSN6SPRM (Db2 Installation and Migration)
Related information
-109 (Db2 Codes)
Change in SQLCODE when the POWER built-in function result is out of range
After the activation of function level 500 or higher in Db2 12, the SQLCODE that is returned when the
result of the POWER® built-in function is out of range is changed in some cases.
Previously, when Db2 executed the POWER built-in function, and the result was a DOUBLE data type that
was out of range, Db2 returned SQLCODE -802. In Db2 12 with function level 500 or higher activated,
SQLCODE +802 is returned.
For example, the following query returns SQLCODE +802:
Invocations of the POWER function that have DOUBLE arguments and return out-of-range results return
SQLCODE +802 instead of SQLCODE -802.
Actions to take
In Db2 12, before function level 500 or higher is activated, identify applications with this incompatibility
by starting a trace for IFCID 0376, and then running the applications. Review the trace output for
incompatible changes with the identifier 1201. Adjust error processing to account for the change in the
returned SQLCODE from an error to a warning.
Actions to take
Review your setting for the BIF_COMPATIBILITY subsystem parameter. If the value is not CURRENT, and
you have applications that require decimal to string output in the pre-DB2 10 format, you can rewrite SQL
statements to use the CHAR9 and VARCHAR9 functions instead. This approach enables the development
of new applications that can accept the current string formatting of decimal data.
To modify your applications to take advantage of the CHAR9, VARCHAR9 functions:
1. Use an IFCID 0376 trace to identify applications that depend on the pre-DB2 10 formats.
2. Rewrite the SQL statements in the identified applications to use the CHAR9 and VARCHAR9 functions
instead of the CHAR and VARCHAR functions.
3. Set the BIF_COMPATIBILITY value to CURRENT.
Related reference
BIF COMPATIBILITY field (BIF_COMPATIBILITY subsystem parameter) (Db2 Installation and Migration)
Actions to take
To modify your applications to handle the DB2 10 and later behavior for CHAR, VARCHAR, and CAST:
1. Identify applications that need to be modified to handle this change. Run a trace for IFCID 0376 to
identify affected applications.
2. Ensure that the BIF_COMPATIBILITY subsystem parameter is set to V9_DECIMAL_VARCHAR.
8 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
To handle the change for the CHAR function only, you can set BIF_COMPATIBILITY to V9, and complete
the following steps for the CHAR function.
3. Change any affected applications to handle the DB2 10 and later CHAR and VARCHAR behavior,
including stored procedures, non-inline user-defined functions, and trigger packages. Rewrite affected
CAST specifications with the appropriate CHAR or VARCHAR function and a CAST to the correct length
if needed.
4. Rebind and prepare packages with the PATH(SYSCURRENT,SYSIBM) rebind option. Putting the
SYSCURRENT schema at the beginning of the SQL path causes the DB2 10 and later behavior to
be used for the CHAR and VARCHAR built-in functions.
Repeat this step for native stored procedures (SQLPL) and non-inline SQL scalar functions.
5. For views that reference these casts or built-in functions, determine whether the view
needs to be changed to have the expected output. Drop and re-create the views with the
PATH(SYSCURRENT,SYSIBM) rebind option only if necessary. Rebind any applications that reference
the views with the PATH(SYSCURRENT,SYSIBM) option to use the DB2 10 and later CHAR and
VARCHAR built-in functions. Repeat this step for inline SQL scalar functions.
6. For materialized query tables or indexes on expressions that reference these casts or built-in
functions, drop and re-create the materialized query tables or indexes on expressions with the
PATH(SYSCURRENT,SYSIBM) rebind option. Issue the REFRESH TABLE statement for materialized
query tables. Rebind any applications that reference the materialized query tables or indexes on
expressions with the PATH(SYSCURRENT,SYSIBM) option to use the DB2 10 and later CHAR and
VARCHAR built-in functions.
7. Change the value of the BIF_COMPATIBILITY subsystem parameter to CURRENT. When the subsystem
parameter value is CURRENT, new applications, rebinds, and CREATE statements use the DB2 10 and
later CHAR, VARCHAR, and CAST behavior.
Materialized query tables and expression-based indexes use the CHAR, VARCHAR, and CAST behavior
that is specified during its creation. If a reference statement has a different behavior that is specified by
the BIF_COMPATIBILITY parameter or a different path, the materialized query table or expression-based
index is not used.
Related reference
BIF COMPATIBILITY field (BIF_COMPATIBILITY subsystem parameter) (Db2 Installation and Migration)
EBCDIC mixed string input to the RTRIM, TRIM, LTRIM, and STRIP built-in
functions must be valid
Starting at application compatibility level V12R1M500 or higher, Db2 12 applies more validation checking
for EBCDIC mixed-string input to the RTRIM, TRIM, LTRIM, and STRIP built-in functions.
Generally, Db2 has required valid EBCDIC mixed-string data for input to these functions since version 10,
but Db2 12 now detects more cases than earlier releases.
With the new validation checking, when Db2 12 performs a trim operation, and the string-expression
argument of the RTRIM, TRIM, LTRIM, or STRIP built-in function contains invalid EBCDIC mixed data, Db2
issues SQLCODE -171.
Actions to take
Check whether EBCDIC mixed data that is specified for the string-expression argument of an RTRIM,
TRIM, LTRIM, or STRIP built-in function is valid, and resolve the invalid data.
In valid mixed data, the double-byte portions of the input strings begin with X'0E' (shift-out character),
end with X'0F' (shift-in character), and have an even number of bytes between the X'0E' and X'0F'
characters. Data that does not meet these criteria is invalid mixed data. When invalid mixed data is
specified for the string-expression argument of an RTRIM, TRIM, LTRIM, or STRIP built-in function,
SQLCODE -171 is returned in some cases. If Db2 trims the specified characters before it reaches an
invalid portion of a mixed string, the trim operation is successful.
Actions to take
If an application contains SQL statements that invoke user-defined external scalar functions, and one of
those SQL statements is rejected with SQLCODE -904 and reason code 00E70082, increase the MAX_UDF
subsystem parameter value, or change the application to run fewer functions concurrently in a Db2
thread.
Related reference
MAX UDFS field (MAX_UDF subsystem parameter) (Db2 Installation and Migration)
Related information
00E70082 (Db2 Codes)
Db2 12 introduces several new SQL reserved words, which are listed in Reserved words (Db2 SQL).
In some cases, the use of these reserved words might cause an incompatibility before new function is
activated in Db2 12 , regardless of the setting of the APPLCOMPAT flag.
Actions to take
Collect IFCID 0376 trace records in Db2 11. Values 4, 5, and 6 for the QW0376FN field indicate instances
of reserved words in applications that will cause an incompatibility in Db2 12. Adjust these applications
by changing the reserved word to a delimited identifier or by using a word that is not reserved in Db2
12.
10 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
GUPI
V12R1M502 GRAPHIC (Db2 SQL) The first argument now accepts numeric No
data types, including SMALLINT, INTEGER,
BIGINT, DECIMAL, REAL, DOUBLE, FLOAT,
and DECFLOAT.
V12R1M502 VARGRAPHIC (Db2 SQL) The first argument accepts numeric data No
types, including SMALLINT, INTEGER,
BIGINT, DECIMAL, REAL, DOUBLE, FLOAT,
and DECFLOAT.
V12R1M501 LISTAGG (Db2 SQL) New built-in function. No
V12R1M500 ARRAY_AGG (Db2 SQL) Newly supported built-in function when No
used for associative array aggregation.
12 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
APPLCOMPA Function name Change introduced Incompatibl
T level e change?
V12R1M500 GENERATE_UNIQUE_BINAR New built-in function. No
Y
V12R1M500 HASH_CRC32, HASH_MD5, New built-in functions. No
HASH_SHA1, and
HASH_SHA256
V12R1M500 LOWER (Db2 SQL) The following locales can now be specified:
• UNI_60
• UNI_90
V12R1M500 UPPER (Db2 SQL) The following locales can now be specified: No
• UNI_60
• UNI_90
GUPI
Actions to take
To continue to execute a user-defined function with the same name or signature as a new built-in
function or signature, qualify the name of the existing user defined function in your application. For more
information about Db2 resolves qualified and unqualified references to functions, see Function resolution
(Db2 SQL).
SQLCODE changes
Some SQLCODE numbers and message text might have changed in Db2 12. Also, the conditions under
which some SQLCODEs are issued might have changed. For more information, see New, changed, and
deleted codes (Db2 Codes).
GUPI
Procedure
Review the list of SQL processing options and decide the values for any options that affect the way that
you write your program.
For example, you need to know if you are using NOFOR or STDSQL(YES) before you begin coding.
Related tasks
Processing SQL statements for program preparation
The first step in preparing an SQL application to run is to process the SQL statements in the program.
To process the statements, use the Db2 coprocessor or the Db2 precompiler. During this step, the SQL
statements are replaced with calls to Db2 language interface modules, and a DBRM is created.
Related reference
Descriptions of SQL processing options
You can specify any SQL processing options regardless of whether you use the Db2 precompiler or the
Db2 coprocessor. However, the Db2 coprocessor might ignore certain options because host language
compiler options exist that provide the same information.
14 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
– Adding a TIME, TIMESTAMP, or DATE column when the default value for added rows is CURRENT
DATE, CURRENT TIME, CURRENT TIMESTAMP (p) WITHOUT TIME ZONE, or CURRENT TIMESTAMP
(p) WITH TIME ZONE respectively
– Adding a constraint with a delete rule of SET NULL or CASCADE. Packages that depend on tables that
cascade deletes to the altered parent table are also invalidated.
– Adding a security label
– Altering a column
– Renaming a column (Cascading effects apply. See “Cascading effects on packages of renaming a
column” on page 16.)
– Altering a column such that a view cannot regenerate
– Altering the AUDIT attribute
– Dropping a column. For pending definition changes, the package invalidation occurs when the
pending definition change is applied to the table.
– Altering for hash organization, or dropping hash organization
– Adding or removing a BUSINESS_TIME period for temporal versioning
– Enabling or disabling transparent archiving
– Adding, altering, or dropping a materialized query table (MQT) definition
– Dropping a clone table
– Activating or deactivating row-level access control
– Activating column-level access control if the table has an enabled column, or deactivating column-
level access control
– For created temporary tables, adding a column
• Altering views:
– Altering a view to regenerate it
• Altering table spaces:
– Changing the SBCS CCSID attribute
– Increasing the MAXPARTITIONS attribute
– Changing the SEGSIZE attribute to convert the table space to a partition-by-range (UTS) table space
– Changing the DSSIZE attribute of a partitioned table space
– Changing the buffer pool page size
• Altering partitions of partition-by-range (PBR) or partitioned (non-UTS) table spaces:
– Adding partitions
– Altering limit keys
– Rotating partitions
• Materializing pending definition changes to table spaces with the REORG TABLESPACE utility. For more
information, see Pending data definition changes (Db2 Administration Guide).
• Altering indexes:
– Adding a column
– Altering an index to regenerate it
– Altering the PADDED or NOT PADDED attribute
– Altering a limit key value of a partitioning index
– Specifying NOT CLUSTER for the partitioning index of a table that uses index-controlled partitioning,
to convert the table to use table controlled partitioning
• Materializing pending definition changes to indexes with the REORG INDEX utility. For more information,
see Pending data definition changes (Db2 Administration Guide).
16 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
-- a value of 1
ALTER TABLE MYTABLE
RENAME COLUMN
MYCOL1 TO MYCOL2; -- MYPACKAGE is invalidated
-- and automatic rebind
-- of MYPACKAGE will fail
-- at this point
ALTER TABLE MYTABLE
ADD COLUMN MYCOL1 VARCHAR(10); -- automatic rebind
-- of MYPACKAGE
-- will be successful
INSERT INTO TABLE MYTABLE (MYCOL1)
VALUES ('ABCD');
At this point an application executes MYPACKAGE, which results in a successful automatic rebind.
However, the statement in the package will return 'ABCD' instead of the expected '1'.
Related concepts
Automatic rebinds
Automatic rebinds (sometimes called "autobinds") occur when an authorized user runs a package or
plan and the runtime structures in the plan or package cannot be used. This situation usually results
from changes to the attributes of the data on which the package or plan depends, or changes to the
environment in which the package or plan runs.
“Trigger packages” on page 159
A trigger package is a special type of package that is created only when you execute a CREATE TRIGGER
statement. A trigger package executes only when the associated trigger is activated.
Invalidation of cached dynamic statements (Db2 Performance)
Related tasks
Identifying packages with characteristics that affect performance, concurrency, or the ability to run (Db2
Performance)
“Rebinding applications” on page 885
You must rebind applications to change bind options. You also need to rebind applications when you make
changes that affect the plan or package, such as creating an index, but you have not changed the SQL
statements.
Related reference
Invalid and inoperative packages (Managing Security)
Related information
00E30305 (Db2 Codes)
Procedure
To identify all packages that will be invalidated by a change to a specific object, run the following query:
object_qualifier
The qualifier of the object
Results
The query returns a table that contains package information based on the selected values in the query.
For details about the selected values, see SYSPACKDEP catalog table (Db2 SQL).
Determining the value of any bind options that affect the design of
your program
Several options of the BIND PACKAGE and BIND PLAN commands can affect your program design. For
example, you can use a bind option to ensure that a package or plan can run only from a particular CICS
connection or IMS region. Your code does not need to enforce this situation.
Procedure
Review the list of bind options and decide the values for any options that affect the way that you write
your program.
18 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
For example, you should decide the values of the ACQUIRE and RELEASE options before you write your
program. These options determine when your application acquires and releases locks on the objects it
uses.
Related reference
BIND and REBIND options for packages, plans, and services (Db2 Commands)
Procedure
To improve the performance of application programs that access data in Db2, use the following
approaches when writing and preparing your programs:
• Program your applications for concurrency.
The goal is to program and prepare applications in a way that:
– Protects the integrity of the data that is being read or updated from being changed by other
applications.
– Minimizes the length of time that other access to the data is prevented.
For more information about data concurrency in Db2 and recommendations for improving concurrency
in your application programs, see the following topics:
– Programming for concurrency (Db2 Performance)
– Designing databases for concurrency (Db2 Performance)
– Concurrency and locks (Db2 Performance)
– Improving concurrency (Db2 Performance)
– Improving concurrency in data sharing environments (Db2 Data Sharing Planning and
Administration)
• Write SQL statements that access data efficiently.
The predicates, subqueries, and other structures in SQL statements affect the access paths that Db2
uses to access the data.
For information about how to write SQL statements that access data efficiently, see the following
topics:
– Ways to improve query performance (Introduction to Db2 for z/OS)
– Writing efficient SQL queries (Db2 Performance)
• Use EXPLAIN or SQL optimization tools to analyze the access paths that Db2 chooses to process your
SQL statements.
By analyzing the access path that Db2 uses to access the data for an SQL statement, you can discover
potential problems. You can use this information to modify your statement to perform better.
For information about how you can use EXPLAIN tables to analyze the access paths for your SQL
statements, see the following topics:
– Investigating access path problems (Db2 Performance)
– 00C200A4 (Db2 Codes)
– Investigating SQL performance by using EXPLAIN (Db2 Performance)
– Interpreting data access by using EXPLAIN (Db2 Performance)
– EXPLAIN tables (Db2 Performance)
– EXPLAIN (Db2 SQL)
• Consider performance in the design of applications that access distributed data.
Procedure
To design your application for recovery:
1. Put any changes that logically need to be made at the same time in the same unit of work. This action
ensures that in case Db2 terminates abnormally or your application fails, the data is left in a consistent
state.
A unit of work is a logically distinct procedure that contains steps that change the data. If all the steps
complete successfully, you want the data changes to become permanent. But, if any of the steps fail,
you want all modified data to return to the original value before the procedure began. For example,
suppose two employees in the sample table DSN8C10.EMP exchange offices. You need to exchange
their office phone numbers in the PHONENO column. You need to use two UPDATE statements to
make each phone number current. Both statements, taken together, are a unit of work. You want both
statements to complete successfully. For example, if only one statement is successful, you want both
phone numbers rolled back to their original values before attempting another update.
2. Consider how often you should commit any changes to the data.
If your program abends or the system fails, Db2 backs out all uncommitted data changes. Changed
data returns to its original condition without interfering with other system activities.
20 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
For IMS and CICS applications, if the system fails, Db2 data does not always return to a consistent
state immediately. Db2 does not process indoubt data (data that is neither uncommitted nor
committed) until you restart IMS or the CICS attachment facility. To ensure that Db2 and IMS are
synchronized, restart both Db2 and IMS. To ensure that Db2 and CICS are synchronized, restart both
Db2 and the CICS attachment facility.
3. Consider whether your application should intercept abends.
If your application intercepts abends, Db2 commits work, because it is unaware that an abend has
occurred. If you want Db2 to roll back work automatically when an abend occurs in your program, do
not let the program or run time environment intercept the abend. If your program uses Language
Environment®, and you want Db2 to roll back work automatically when an abend occurs in the
program, specify the run time options ABTERMENC(ABEND) and TRAP(ON).
4. For TSO applications only: Issue COMMIT statements before you connect to another DBMS.
If the system fails at this point, Db2 cannot know whether your transaction is complete. In this case,
as in the case of a failure during a one-phase commit operation for a single subsystem, you must make
your own provision for maintaining data integrity.
5. For TSO applications only: Determine if you want to provide an abend exit routine in your program.
If you provide this routine, it must use tracking indicators to determine if an abend occurs during
Db2 processing. If an abend does occur when Db2 has control, you must allow task termination to
complete. Db2 detects task termination and terminates the thread with the ABRT parameter. Do not
re-run the program.
Allowing task termination to complete is the only action that you can take for abends that are caused
by the CANCEL command or by DETACH. You cannot use additional SQL statements at this point. If
you attempt to execute another SQL statement from the application program or its recovery routine,
unexpected errors can occur.
Related concepts
Unit of work (Introduction to Db2 for z/OS)
Procedure
To plan for program recovery in IMS programs:
1. For a program that processes messages as its input, decide whether to specify single-mode or
multiple-mode transactions on the TRANSACT statement of the APPLCTN macro for the program.
Single-mode
Indicates that a commit point in Db2 occurs each time the program issues a call to retrieve a new
message. Specifying single-mode can simplify recovery; if the program abends, you can restart
the program from the most recent call for a new message. When IMS restarts the program, the
program starts by processing the next message.
Multiple-mode
Indicates that a commit point occurs when the program issues a checkpoint call or when it
terminates normally. Those two events are the only times during the program that IMS sends the
program's output messages to their destinations. Because fewer commit points are processed in
multiple-mode programs than in single-mode programs, multiple-mode programs could perform
22 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
slightly better than single-mode programs. When a multiple-mode program abends, IMS can
restart it only from a checkpoint call. Instead of having only the most recent message to reprocess,
a program might have several messages to reprocess. The number of messages to process
depends on when the program issued the last checkpoint call.
Db2 does some processing with single- and multiple-mode programs. When a multiple-mode program
issues a call to retrieve a new message, Db2 performs an authorization check and closes all open
cursors in the program.
2. Decide whether to issue checkpoint calls (CHKP) and if so, how often to issue them.
Each call indicates to IMS that the program has reached a sync point and establishes a place in the
program from which you can restart the program.
Consider the following factors when deciding when to use checkpoint calls:
• How long it takes to back out and recover that unit of work. The program must issue checkpoints
frequently enough to make the program easy to back out and recover.
• How long database resources are locked in Db2 and IMS.
• For multiple-mode programs: How you want the output messages grouped. Checkpoint calls
establish how a multiple-mode program groups its output messages. Programs must issue
checkpoints frequently enough to avoid building up too many output messages.
Restriction: You cannot use SQL COMMIT and ROLLBACK statements in the Db2 DL/I batch support
environment, because IMS coordinates the unit of work.
3. Issue CLOSE CURSOR statements before any checkpoint calls or GU calls to the message queue, not
after.
4. After any checkpoint calls, set the value of any special registers that were reset if their values are
needed after the checkpoint:
A CHKP call causes IMS to sign on to Db2 again, which resets the special registers that are shown in
the following table.
Table 2. Effects of ROLL and ROLLB calls on DL/I changes in a batch environment
Options specified
Rollback call System log option Backout option Result
ROLL tape any DL/I does not back
out updates, and abend
disk BKO=NO U0778 occurs. Db2
backs out updates
to the previous
checkpoint.
disk BKO=YES DL/I backs out updates,
and abend U0778
occurs. Db2 backs out
updates to the previous
checkpoint.
24 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 2. Effects of ROLL and ROLLB calls on DL/I changes in a batch environment (continued)
Options specified
Rollback call System log option Backout option Result
ROLB tape any DL/I does not back out
updates, and an AL
disk BKO=NO status code is returned
in the PCB. Db2 backs
out updates to the
previous checkpoint.
The Db2 DL/I support
causes the application
program to abend when
ROLB fails.
disk BKO=YES DL/I backs out
database updates, and
control is passed back
to the application
program. Db2 backs out
updates to the previous
checkpoint.
Restriction: You cannot
specify the address of
an I/O area as one
of the options on the
call; if you do, your
program receives an AD
status code. However,
you must have an I/O
PCB for your program.
Specify CMPAT=YES on
the CMPAT keyword in
the PSBGEN statement
for your program's PSB.
Related concepts
Checkpoints in IMS programs
Issuing checkpoint calls releases locked resources and establishes a place in the program from which you
can restart the program. The decision about whether your program should issue checkpoints (and if so,
how often) depends on your program.
Procedure
To specify checkpoint frequency in IMS programs:
1. Use a counter in your program to keep track of one of the following items:
• Elapsed time
• The number of root segments that your program accesses
• The number of updates that your program performs
26 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
2. Issue a checkpoint call after a certain time interval, number of root segments, or number of updates.
Procedure
Take one or more of the following actions depending on the type of program:
Program type Recommended action
DL/I batch applications Use the DL/I batch backout utility to back out DL/I changes. Db2
automatically backs out changes whenever the application program
abends.
Applications that use Use a restart call (XRST) to restart a program after an abend. This
symbolic checkpoints call restores the program's data areas to the way they were when the
program terminated abnormally, and it restarts the program from the last
checkpoint call that the program issued before terminating abnormally.
BMP programs that access Restart the program from the latest checkpoint.
Db2 databases
28 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Program type Recommended action
Restriction: You can restart the program only from the latest checkpoint
and not from any checkpoint, as in IMS.
Applications that use online No action needed. Recovery and restart are part of the IMS system
IMS systems
Applications that reside in Follow your location's operational procedures to control recovery and
the batch region restart.
Procedure
To undo selected changes within a unit of work by using savepoints:
1. Set any savepoints by using SQL SAVEPOINT statements.
Savepoints set a point to which you can undo changes within a unit of work.
Consider the following abilities and restrictions when setting savepoints:
• You can set a savepoint with the same name multiple times within a unit of work. Each time that you
set the savepoint, the new value of the savepoint replaces the old value.
• If you do not want a savepoint to have different values within a unit of work, use the UNIQUE option
in the SAVEPOINT statement. If an application executes a SAVEPOINT statement with the same
name as a savepoint that was previously defined as unique, an SQL error occurs.
• If you set a savepoint before you execute a CONNECT statement, the scope of that savepoint is
the local site. If you set a savepoint after you execute the CONNECT statement, the scope of that
savepoint is the site to which you are connected.
• When savepoints are active, which they are until the unit of work completes, you cannot access
remote sites by using three-part names or aliases for three-part names. You can, however, use DRDA
access with explicit CONNECT statements.
• You cannot use savepoints in global transactions, triggers, user-defined functions, or stored
procedures that are nested within triggers or user-defined functions.
2. Specify the changes that you want to undo within a unit of work by using the SQL ROLLBACK TO
SAVEPOINT statement.
Db2 undoes all changes since the specified savepoint. If you do not specify a savepoint name, Db2
rolls back work to the most recently created savepoint.
3. Optional: If you no longer need a savepoint, delete it by using the SQL RELEASE SAVEPOINT
statement.
Recommendation: If you no longer need a savepoint before the end of a transaction, release it.
Otherwise, savepoints are automatically released at the end of a unit of work. Releasing savepoints is
essential if you need to use three-part names to access remote locations, because you cannot perform
this action while savepoints are active.
Examples
Example: Rolling back to the most recently created savepoint
When the ROLLBACK TO SAVEPOINT statement is executed in the following code, Db2 rolls back work
to savepoint B.
Procedure
To plan for recovery of table spaces that are not logged:
1. Ensure that you can recover lost data by performing one of the following actions:
• Ensure that you have a data recovery source that does not rely on a log record to re-create any lost
data.
• Limit modifications that are not logged to easily repeatable changes that can be quickly repeated.
2. Avoid placing a table space that is not logged in a RECOVER-pending status.
The following actions place a table space in RECOVER-pending status:
• Issuing a ROLLBACK statement or ROLLBACK TO SAVEPOINT statement after modifying a table in a
table space that is not logged.
30 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
• Causing duplicate keys or referential integrity violations when you modify a table space that is not
logged.
If the table space is placed in RECOVER-pending status, it is unavailable until you manually fix it.
3. For table spaces that are not logged and have associated LOB or XML table spaces, take image copies
as a recovery set.
This action ensures that the base table space and all the associated LOB or XML table spaces are
copied at the same point in time. A subsequent RECOVER TO LASTCOPY operation for the entire set
results in consistent data across the base table space and all of the associated LOB and XML table
spaces.
Related tasks
Clearing the RECOVER-pending status (Db2 Administration Guide)
Related reference
RECOVER (Db2 Utilities)
Procedure
To design your application to access distributed data:
1. Ensure that the appropriate authorization ID has been granted authorization at the remote server to
connect to that server and use resources from it.
2. If your application contains SQL statements that run at the requester, include at the requester a
database request module (DBRM) that is bound directly into a package that is included in the plan's
package list.
3. Copy the requester package to any remote server that is accessed by the application via a bind
package copy command and include the remote packages in the application plan's package list.
Recommendation: Specify an asterisk (*) instead of a specific name in the location name of any
package entry of a plan so that the plan does not have to be rebound whenever a new location is
accessed by the application or a different location is to be accessed.
4. For TSO and batch applications that update data at a remote server, ensure that one of the following
conditions is true:
• No other connections exist.
• All existing connections are to servers that are restricted to read-only operations.
Restriction: If neither of these conditions are met, the application is restricted to read-only
operations.
If one of these conditions is met, and if the first connection in a logical unit of work is to a server that
supports two-phase commit, that server and all servers that support two-phase commit can update
data. However, if the first connection is to a server that does not support two-phase commit, only that
server is allowed to update data.
5. For programs that access at least one restricted system, ensure that your program does not violate any
of the limitations for accessing restricted systems.
A restricted system is a DBMS that does not implement two-phase commit processing.
Accessing restricted systems has the following limitations:
• For programs that access CICS or IMS, you cannot update data on restricted systems.
• Within a unit of work, you cannot update a restricted system after updating a non-restricted system.
• Within a unit of work, if you update a restricted system, you cannot update any other systems.
Procedure
Ensure that all systems that your program accesses implement two-phase commit processing. This
processing ensures that updates to two or more DBMSs are coordinated automatically.
For example, Db2 and IMS, and Db2 and CICS, jointly implement a two-phase commit process. You can
update an IMS database and a Db2 table in the same unit of work. If a system or communication failure
occurs between committing the work on IMS and on Db2, the two programs restore the two systems to a
consistent point when activity resumes.
You cannot do true coordinated updates within a DBMS that does not implement two-phase commit
processing, because Db2 prevents you from updating such a DBMS and any other system within the same
unit of work. In this context, update includes the statements INSERT, UPDATE, MERGE, DELETE, CREATE,
ALTER, DROP, GRANT, REVOKE, RENAME, COMMENT, and LABEL.
32 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
However, if you cannot implement two-phase commit processing on all systems that your program
accesses, you can simulate the effect of coordinated updates by performing the following actions:
a. Update one system and commit that work.
b. Update the second system and commit its work.
c. Ensure that your program has code to undo the first update if a failure occurs after the first update is
committed and before the second update is committed. No automatic provision exists for bringing the
two systems back to a consistent point.
Related concepts
Two-phase commit process (Db2 Administration Guide)
Procedure
When you prepare your program, specify the SQL processing option CONNECT(1).
This option applies type 1 CONNECT statement rules.
Restriction: Do not use packages that are precompiled with the CONNECT(1) option and packages that
are precompiled with the CONNECT(2) option in the same package list. The first CONNECT statement that
is executed by your program determines which rules are in effect for the entire execution: type 1 or type
2. If your program attempts to execute a later CONNECT statement that is precompiled with the other
type, Db2 returns an error.
Related concepts
Options for SQL statement processing
Use SQL processing options to specify how the Db2 precompiler and the Db2 coprocessor interpret and
process input, and how they present output.
Procedure
Perform one of the following actions:
• Explicitly invoke CAF by including in your program CALL DSNALI statements with the appropriate
options.
The first option is a CAF connection function, which describes the action that you want CAF to take. The
effect of any function depends in part on what functions the program has already run.
Requirement: For C and PL/I applications, you must also include in your program the compiler
directives that are listed in the following table, because DSNALI is an assembler language program.
36 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 3. Compiler directives to include in C and PL/I applications that contain CALL DSNALI statements
Language Compiler directive to include
• Implicitly invoke CAF by including SQL statements or IFI calls in your program just as you would in any
program. The CAF facility establishes the connections to Db2 with the default values for the subsystem
name and plan name.
Restriction: If your program can make its first SQL call from different modules with different DBRMs,
you cannot use a default plan name and thus, you cannot implicitly invoke CAF. Instead, you must
explicitly invoke CAF by using the OPEN function.
Requirement: If your application includes both SQL and IFI calls, you must issue at least one SQL call
before you issue any IFI calls. This action ensures that your application uses the correct plan.
Although doing so is not recommended, you can run existing DSN applications with CAF by allowing
them to make implicit connections to Db2. For Db2 to make an implicit connection successfully, the
plan name for the application must be the same as the member name of the database request module
(DBRM) that Db2 produced when you precompiled the source program that contains the first SQL call.
You must also substitute the DSNALI language interface module for the TSO language interface module,
DSNELI.
If you do not specify the return code and reason code parameters in your CAF calls or you invoked CAF
implicitly, CAF puts a return code in register 15 and a reason code in register 0.
To determine if an implicit connection was successful, the application program should examine the return
and reason codes immediately after the first executable SQL statement in the application program by
performing one of the following actions:
• Examining registers 0 and 15 directly.
• Examining the SQLCA, and if the SQLCODE is -991, obtain the return and reason code from the message
text. The return code is the first token, and the reason code is the second token.
If the implicit connection was successful, the application can examine the SQLCODE for the first, and
subsequent, SQL statements.
Examples
Example of a CAF configuration
The following figure shows an conceptual example of invoking and using CAF. The application contains
statements to load DSNALI, DSNHLI2, and DSNWLI2. The application accesses Db2 by using the CAF
Language Interface. It calls DSNALI to handle CAF requests, DSNWLI to handle IFI calls, and DSNHLI
to handle SQL calls.
CALL DSNWLI
(IFI calls) (Process
CALL DSNHLI connection
(SQL calls) requests)
DSNWLI (dummy
application
entry point)
38 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
• Run with or without the TSO terminal monitor program (TMP).
• Run without being a subtask of the DSN command processor or of any Db2 code.
• Run above or below the 16-MB line. (The CAF code resides below the line.)
• Establish an explicit connection to Db2, through a CALL interface, with control over the exact state of
the connection.
• Establish an implicit connection to Db2, by using SQL statements or IFI calls without first calling CAF,
with a default plan name and subsystem identifier.
• Verify that the application is using the correct release of Db2.
• Supply event control blocks (ECBs), for Db2 to post, that signal startup or termination.
• Intercept return codes, reason codes, and abend codes from Db2 and translate them into messages.
Any task in an address space can establish a connection to Db2 through CAF. Only one connection
can exist for each task control block (TCB). A Db2 service request that is issued by a program that is
running under a given task is associated with that task's connection to Db2. The service request operates
independently of any Db2 activity under any other task.
Each connected task can run a plan. Multiple tasks in a single address space can specify the same plan,
but each instance of a plan runs independently from the others. A task can terminate its plan and run a
different plan without fully breaking its connection to Db2.
CAF does not generate task structures.
When you design your application, consider that using multiple simultaneous connections can increase
the possibility of deadlocks and Db2 resource contention.
A tracing facility provides diagnostic messages that aid in debugging programs and diagnosing errors in
the CAF code. In particular, attempts to use CAF incorrectly cause error messages in the trace stream.
Restriction: CAF does not provide attention processing exits or functional recovery routines. You can
provide whatever attention handling and functional recovery your application needs, but you must use
ESTAE/ESTAI type recovery routines and not Enabled Unlocked Task (EUT) FRR routines.
If a connected task terminates normally before the CLOSE function deallocates the plan, Db2 commits
any database changes that the thread made since the last commit point. If a connected task abends
before the CLOSE function deallocates the plan, Db2 rolls back any database changes since the last
commit point. In either case, Db2 deallocates the plan, if necessary, and terminates the task's connection
before it allows the task to terminate.
If Db2 abnormally terminates while an application is running, the application is rolled back to the last
commit point. If Db2 terminates while processing a commit request, Db2 either commits or rolls back
any changes at the next restart. The action taken depends on the state of the commit request when Db2
terminates.
Related concepts
Connection routines and sign-on routines (Managing Security)
40 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Recovery routines for CAF
You can use abend recovery routines and functional recovery routines (FRRs) to handle unexpected
errors. An abend recovery routine controls what happens when an abend occurs while Db2 has control. A
functional recovery routine can obtain information about and recover from program errors.
The CAF has no abend recovery routines, but you can provide your own. Any abend recovery routines that
you provide must use tracking indicators to determine if an abend occurred during Db2 processing. If an
abend occurs while Db2 has control, the recovery routine can take one of the following actions:
• Allow task termination to complete. Do not try the program again. Db2 detects task termination and
terminates the thread with the ABRT parameter. You lose all database changes back to the last sync
point or commit point.
This action is the only action that you can take for abends that are caused by the CANCEL command
or by DETACH. You cannot use additional SQL statements. If you attempt to execute another SQL
statement from the application program or its recovery routine, you receive a return code of +256 and a
reason code of X'00F30083'.
• In an ESTAE routine, issue a CLOSE function call with the ABRT parameter followed by a DISCONNECT
function call. The ESTAE exit routine can try again so that you do not need to reinstate the application
task.
FRRs must comply with the following requirements and restrictions:
• You can use only enabled unlocked task (EUT) FRRs in your routines that call Db2. The standard z/OS
functional recovery routines (FRRs) apply to only code that runs in service request block (SRB) mode,
and Db2 does not support calls from SRB mode routines.
• Do not have an EUT FRR active when using CAF, processing SQL requests, or calling IFI. With z/OS, if
you have an active EUT FRR, all Db2 requests fail, including the initial CONNECT or OPEN request. The
requests fail because Db2 always creates an ARR-type ESTAE, and z/OS does not allow the creation of
ARR-type ESTAEs when an FRR is active.
• An EUT FRR cannot retry failing Db2 requests. An EUT FRR retry bypasses ESTAE routines from Db2.
The next Db2 request of any type, including a DISCONNECT request, fails with a return code of +256
and a reason code of X'00F30050'.
Procedure
To make DSNALI available:
1. Decide which of the following methods you want to use to make DSNALI available:
• Explicitly issuing LOAD requests when your program runs.
42 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
To create a single load module that can be used in more than one attachment environment, you can
link-edit your program or stored procedure with the Universal Language Interface module (DSNULI)
instead of with one of the environment-specific language interface modules (DSNELI, DSNALI, DSNRLI,
DSNCLI, or DFSLI000).
Saving storage when manipulating LOBs by using LOB locators
LOB locators let you manipulate LOB data without retrieving the data from the Db2 table. By using
locators, you avoid needing to allocate the large amounts of storage that are needed for host variables to
hold LOB data.
44 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
ptr ribptr;
int retcode;
int reascode;
ptr eibptr;
• For other languages except assembler language, code zero for that parameter in the CALL DSNALI
statement. For example, suppose that you are coding a CONNECT call in a COBOL program, and you
want to specify all parameters except the return code parameter. You can write a statement similar to
the following statement:
• For assembler language, code a comma for that parameter in the CALL DSNALI statement. For example,
to specify all optional parameters except the return code parameter write a statement similar to the
following statement:
CALL DSNALI,(FUNCTN,SSID,TERMECB,STARTECB,RIBPTR,,REASCODE,SRDURA,EIBPTR,
GROUPOVERRIDE)
The following figure shows a sample parameter list structure for the CONNECT function.
12-byte area
Register 1 CONNECT that contains the
function name
Parameter
list DSN Subsystem name
Termination event
0
control block (ECB)
Effect of value in
CURRENT DEGREE
special register
CAF puts the address of
the environment information
block (EIB) here
Whether the value in the
subsystem name field
can be a group attachment
name
The preceding figure illustrates how you can omit parameters for the CALL DSNALI statement to control
the return code and reason code fields after a CONNECT call. You can terminate the parameter list at any
of the following points. These termination points apply to all CALL DSNALI statement parameter lists.
46 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 6. Effects of CAF calls, as dependent on connection history
Previous Next function
function
CONNECT OPEN SQL CLOSE DISCONNECT TRANSLATE
Empty: first call CONNECT OPEN CONNECT, Error 2031 Error 2041 Error 2051
OPEN, followed
by the SQL or
IFI call
CONNECT Error 2011 OPEN OPEN, followed Error 2031 DISCONNECT TRANSLATE
by the SQL or
IFI call
CONNECT Error 2011 Error 2021 The SQL or IFI CLOSE2 DISCONNECT TRANSLATE
followed by call
OPEN
CONNECT Error 2011 Error 2021 The SQL or IFI CLOSE2 DISCONNECT TRANSLATE
followed by SQL call
or IFI call
OPEN Error 2011 Error 2021 The SQL or IFI CLOSE2 Error 2041 TRANSLATE
call
SQL or IFI call Error 2011 Error 2021 The SQL or IFI CLOSE2 Error 2041 TRANSLATE3
call
Notes:
1. An error is shown in this table as Error nnn. The corresponding reason code is X'00C10nnn'. The
message number is DSNAnnnI or DSNAnnnE.
2. The task and address space connections remain active. If the CLOSE call fails because Db2 was down,
the CAF control blocks are reset, the function produces return code 4 and reason code X'00C10824',
and CAF is ready for more connection requests when Db2 is up.
3. A TRANSLATE request is accepted, but in this case it is redundant. CAF automatically issues a
TRANSLATE request when an SQL or IFI request fails.
Related reference
CAF return codes and reason codes
CAF provides the return codes either to the corresponding parameters that are specified in a CAF function
call or, if you choose not to use those parameters, to registers 15 and 0.
48 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
the connection to Db2 remains after the CLOSE function deallocates a plan. In this case, the connection
terminates only when you use the DISCONNECT function or when the task terminates.
The CONNECT function also enables the caller to learn the following items:
• That the operator has issued a STOP DB2 command. When this event occurs, Db2 posts the termination
ECB, termecb. Your application can either wait on or just look at the ECB.
• That Db2 is abnormally terminating. When this event occurs happens, Db2 posts the termination ECB,
termecb.
• That Db2 is available again after a connection attempt that failed because Db2 was down. Your
application can either wait or look at the startup ECB, startecb. Db2 ignores this ECB if it was active
at the time of the CONNECT request.
• The current release level of Db2. To find this information, access the RIBREL field in the release
information block (RIB). If RIBREL is '999', the actual version, release, and modification level of Db2 is
indicated in the RIBRELX field and its subfields.
Restriction: Do not issue CONNECT requests from a TCB that already has an active Db2 connection.
Recommendation: Do not mix explicit CONNECT and OPEN requests with implicitly established
connections in the same address space. Either explicitly specify which Db2 subsystem you want to use or
allow all requests to use the default subsystem.
The following diagram shows the syntax for the CONNECT function.
,retcode
,reascode
,srdura
,eibptr
,groupoverride
,decpptr
Before you check termecb in your CAF application program, first check the return code and reason
code from the CONNECT call to ensure that the call completed successfully.
startecb
A 4-byte integer representing the application's startup ECB. If Db2 has not yet started when the
application issues the call, Db2 posts the ECB when it successfully completes its startup processing.
Db2 posts at most one startup ECB per address space. The ECB is the one associated with the most
recent CONNECT call from that address space. Your application program must examine any nonzero
CAF and Db2 reason codes before issuing a WAIT on this ECB.
If ssnm is a group attachment or subgroup attachment name, the first Db2 subsystem that starts on
the local z/OS system and matches the specified group attachment name posts the ECB.
ribptr
A 4-byte area in which CAF places the address of the release information block (RIB) after the call.
You can determine what release level of Db2 you are currently running by examining the RIBREL
field. If RIBREL is '999', the actual version, release, and modification level of Db2 is indicated in the
RIBRELX field and its subfields.You can determine the modification level within the release level by
examining the RIBCNUMB and RIBCINFO fields. If the value in the RIBCNUMB field is greater than
zero, check the RIBCINFO field for modification levels.
If the RIB is not available (for example, if you name a subsystem that does not exist), Db2 sets the
4-byte area to zeros.
The area to which ribptr points is below the 16-MB line.
Your program does not have to use the release information block, but it cannot omit the ribptr
parameter.
Macro DSNDRIB maps the release information block (RIB). It can be found in
prefix.SDSNMACS(DSNDRIB).
retcode
A 4-byte area in which CAF places the return code.
This field is optional. If you do not specify retcode, CAF places the return code in register 15 and the
reason code in register 0.
reascode
A 4-byte area in which CAF places a reason code.
This field is optional. If you do not specify reascode, CAF places the reason code in register 0. If you
specify reascode, you must also specify retcode.
srdura
A 10-byte area that contains the string 'SRDURA(CD)'. This field is optional. If you specify srdura, the
value in the CURRENT DEGREE special register stays in effect from the time of the CONNECT call until
the time of the DISCONNECT call. If you do not specify srdura, the value in the CURRENT DEGREE
special register stays in effect from the time of the OPEN call until the time of the CLOSE call. If you
specify this parameter in any language except assembler, you must also specify retcode and reascode.
In assembler language, you can omit these parameters by specifying commas as placeholders.
eibptr
A 4-byte area in which CAF puts the address of the environment information block (EIB). The EIB
contains information that you can use if you are connecting to a Db2 subsystem that is part of a data
sharing group. For example, you can determine the name of the data sharing group, the member to
which you are connecting, and whether new functions are activated on the subsystem. If the Db2
subsystem that you connect to is not part of a data sharing group, the fields in the EIB that are related
50 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
to data sharing are blank. If the EIB is not available (for example, if you name a subsystem that does
not exist), Db2 sets the 4-byte area to zeros.
The area to which eibptr points is above the 16-MB line.
You can omit this parameter when you make a CONNECT call.
If you specify this parameter in any language except assembler, you must also specify retcode,
reascode, and srdura. In assembler language, you can omit retcode, reascode, and srdura by
specifying commas as placeholders.
Macro DSNDEIB maps the EIB. It can be found in prefix.SDSNMACS(DSNDEIB).
groupoverride
An 8-byte area that the application provides. This parameter is optional. If you do not want group
attach to be attempted, specify 'NOGROUP'. This string indicates that the subsystem name that is
specified by ssnm is to be used as a Db2 subsystem name, even if ssnm matches a group attachment
or subgroup attachment name. If groupoverride is not provided, ssnm is used as the group attachment
or subgroup attachment name if it matches a group attachment or subgroup attachment name.
If you specify this parameter in any language except assembler, you must also specify retcode,
reascode, srdura, and eibptr. In assembler language, you can omit retcode, reascode, srdura, and
eibptr by specifying commas as placeholders.
Recommendation: Avoid using the groupoverride parameter when possible, because it limits the
ability to do dynamic workload routing in a Parallel Sysplex®. However, you should use this parameter
in a data sharing environment when you want to connect to a specific member of a data sharing
group, and the subsystem name of that member is the same as the group attachment or subgroup
attachment name.
decpptr
A 4-byte area in which CAF is to put the address of the DSNHDECP control block or user-specified
application defaults module that was loaded by subsystem ssnm when that subsystem was started.
This 4-byte area is a 31-bit pointer. If ssnm is not found, the 4-byte area is set to 0.
The area to which decpptr points may be above the 16-MB line.
If you specify this parameter in any language except assembler, you must also specify the
retcode, reascode, srdura, eibptr, and groupoverride parameters. In assembler language, you can
omit the retcode, reascode, srdura, eibptr, and groupoverride parameters by specifying commas as
placeholders.
C1
fnret=dsnali(&functn[0],&ssid[0], &tecb, &secb,&ribptr,&retcode, &reascode,
&srdura[0],
&eibptr, &grpover[0]);
COBOL
CALL 'DSNALI' USING FUNCTN SSID TERMECB STARTECB RIBPTR RETCODE REASCODE SRDURA
EIBPTR GRPOVER.
PL/I1
CALL
DSNALI(FUNCTN,SSID,TERMECB,STARTECB,RIBPTR,RETCODE,REASCODE,SRDURA,
EIBPTR,GRPOVER)
Note:
• For C and PL/I applications, you must include the appropriate compiler directives, because DSNALI is
an assembler language program. These compiler directives are described in the instructions for invoking
CAF.
Related concepts
Examples of invoking CAF
The call attachment facility (CAF) enables programs to communicate with Db2. If you explicitly invoke
CAF in your program, you can use the CAF connection functions to control the state of the connection.
Related tasks
Invoking the call attachment facility
Invoke the call attachment facility (CAF) when you want your application program to establish and control
its own connection to Db2. Applications that use CAF can explicitly control the state of their connections
to Db2 by using connection functions that CAF supplies.
Related reference
Synchronizing Tasks (WAIT, POST, and EVENTS Macros) (MVS Programming: Assembler Services Guide)
)
, retcode
, reascode
, groupoverride
52 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
ssnm
A 4-byte Db2 subsystem name or group attachment or subgroup attachment name (if used in a data
sharing group). The OPEN function allocates the specified plan to this Db2 subsystem. Also, if the
requesting task does not already have a connection to the named Db2 subsystem, the OPEN function
establishes it.
You must specify the ssnm parameter, even if the requesting task also issues a CONNECT call. If a
task issues a CONNECT call followed by an OPEN call, the subsystem names for both calls must be the
same.
If ssnm is less than four characters long, pad it on the right with blanks to a length of four characters.
plan
An 8-byte Db2 plan name.
retcode
A 4-byte area in which CAF places the return code.
This field is optional. If you do not specify retcode,CAF places the return code in register 15 and the
reason code in register 0.
reascode
A 4-byte area in which CAF places a reason code.
This field is optional. If you do not specify reascode, CAF places the reason code in register 0. If you
specify reascode, you must also specify retcode.
groupoverride
An 8-byte area that the application provides. This field is optional. If you do not want group attach to
be attempted, specify 'NOGROUP'. This string indicates that the subsystem name that is specified by
ssnm is to be used as a Db2 subsystem name, even if ssnm matches a group attachment or subgroup
attachment name. If you do not specify groupoverride, ssnm is used as the group attachment and
subgroup attachment name if it matches a group attachment or subgroup attachment name. If you
specify this parameter in any language except assembler, you must also specify retcode and reascode.
In assembler language, you can omit these parameters by specifying commas as placeholders.
Recommendation: Avoid using the groupoverride parameter when possible, because it limits the
ability to do dynamic workload routing in a Parallel Sysplex. However, you should use this parameter
in a data sharing environment when you want to connect to a specific member of a data sharing
group, and the subsystem name of that member is the same as the group attachment or subgroup
attachment name.
C1
fnret=dsnali(&functn[0],&ssid[0], &planname[0],&retcode, &reascode,&grpover[0]);
COBOL
CALL 'DSNALI' USING FUNCTN SSID PLANNAME RETCODE REASCODE GRPOVER.
Fortran
CALL DSNALI(FUNCTN,SSID,PLANNAME, RETCODE,REASCODE,GRPOVER)
PL/I1
CALL DSNALI(FUNCTN,SSID,PLANNAME, RETCODE,REASCODE,GRPOVER);
54 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
function
A 12-byte area that contains the word CLOSE followed by seven blanks.
termop
A 4-byte terminate option, with one of the following values:
SYNC
Specifies that Db2 is to commit any modified data.
ABRT
Specifies that Db2 is to roll back data to the previous commit point.
retcode
A 4-byte area in which CAF is to place the return code.
This field is optional. If you do not specify retcode, CAF places the return code in register 15 and the
reason code in register 0.
reascode
A 4-byte area in which CAF places a reason code.
This field is optional. If you do not specify reascode, CAF places the reason code in register 0. If you
specify reascode, you must also specify retcode.
C1
fnret=dsnali(&functn[0], &termop[0], &retcode,&reascode);
COBOL
CALL 'DSNALI' USING FUNCTN TERMOP RETCODE REASCODE.
Fortran
CALL DSNALI(FUNCTN,TERMOP, RETCODE,REASCODE)
PL/I1
CALL DSNALI(FUNCTN,TERMOP, RETCODE,REASCODE);
Note:
• For C and PL/I applications, you must include the appropriate compiler directives, because DSNALI is
an assembler language program. These compiler directives are described in the instructions for invoking
CAF.
Related tasks
Invoking the call attachment facility
Invoke the call attachment facility (CAF) when you want your application program to establish and control
its own connection to Db2. Applications that use CAF can explicitly control the state of their connections
to Db2 by using connection functions that CAF supplies.
C1
fnret=dsnali(&functn[0], &retcode, &reascode);
COBOL
CALL 'DSNALI' USING FUNCTN RETCODE REASCODE.
56 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 11. Examples of CAF DISCONNECT calls (continued)
Language Call example
Fortran
CALL DSNALI(FUNCTN,RETCODE,REASCODE)
PL/I1
CALL DSNALI(FUNCTN,RETCODE,REASCODE);
Note:
• For C and PL/I applications, you must include the appropriate compiler directives, because DSNALI is
an assembler language program. These compiler directives are described in the instructions for invoking
CAF.
Related tasks
Invoking the call attachment facility
Invoke the call attachment facility (CAF) when you want your application program to establish and control
its own connection to Db2. Applications that use CAF can explicitly control the state of their connections
to Db2 by using connection functions that CAF supplies.
C1
fnret=dsnali(&functn[0], &sqlca, &retcode, &reascode);
COBOL
CALL 'DSNALI' USING FUNCTN SQLCA RETCODE REASCODE.
PL/I1
CALL DSNALI(FUNCTN,SQLCA,RETCODE, REASCODE);
Note:
• For C and PL/I applications, you must include the appropriate compiler directives, because DSNALI is
an assembler language program. These compiler directives are described in the instructions for invoking
CAF.
Related tasks
Invoking the call attachment facility
Invoke the call attachment facility (CAF) when you want your application program to establish and control
its own connection to Db2. Applications that use CAF can explicitly control the state of their connections
to Db2 by using connection functions that CAF supplies.
Procedure
Allocate a DSNTRACE data set either dynamically or by including a DSNTRACE DD statement in your JCL.
CAF writes diagnostic trace messages to that data set. The trace message numbers contain the last three
digits of the reason codes.
Related concepts
Examples of invoking CAF
58 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
The call attachment facility (CAF) enables programs to communicate with Db2. If you explicitly invoke
CAF in your program, you can use the CAF connection functions to control the state of the connection.
Notes:
1. A CAF error probably caused by errors in the parameter lists from the application programs. CAF errors
do not change the current state of your connection to Db2; you can continue processing with a corrected
request.
2. System errors cause abends. If tracing is on, a descriptive message is written to the DSNTRACE data set just
before the abend.
CONNECT
OPEN allocate a plan
SQL or IFI call
···
CLOSE deallocate the current plan
OPEN allocate a new plan
SQL or IFI call
···
CLOSE
DISCONNECT
A task can have a connection to only one Db2 subsystem at any point in time. A CAF error occurs if the
subsystem name in the OPEN call does not match the subsystem name in the CONNECT call. To switch to
a different subsystem, the application must first disconnect from the current subsystem and then issue a
connect request with a new subsystem name.
Multiple tasks
In the following scenario, multiple tasks within the address space use Db2 services. Each task must
explicitly specify the same subsystem name on either the CONNECT function request or the OPEN
function request. Task 1 makes no SQL or IFI calls. Its purpose is to monitor the Db2 termination and
startup ECBs and to check the Db2 release level.
CONNECT
OPEN OPEN OPEN
SQL SQL SQL
... ... ...
CLOSE CLOSE CLOSE
OPEN OPEN OPEN
SQL SQL SQL
... ... ...
CLOSE CLOSE CLOSE
DISCONNECT
60 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Examples of invoking CAF
The call attachment facility (CAF) enables programs to communicate with Db2. If you explicitly invoke
CAF in your program, you can use the CAF connection functions to control the state of the connection.
//SYSPRINT DD SYSOUT=*
//DSNTRACE DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
This example code does not show a task that waits on the Db2 termination ECB. If you want such a task,
you can code it by using the z/OS WAIT macro to monitor the ECB. You probably want this task to detach
the sample code if the termination ECB is posted. That task can also wait on the Db2 startup ECB. This
sample waits on the startup ECB at its own task level.
This example code assumes that the variables in the following table are already set:
Table 14. Variables that preceding example assembler code assumes are set
Variable Usage
LIALI The entry point that handles Db2 connection
service requests.
LISQL The entry point that handles SQL calls.
SSID The Db2 subsystem identifier.
TECB The address of the Db2 termination ECB.
SECB The address of the Db2 startup ECB.
RIBPTR A fullword that CAF sets to contain the RIB
address.
PLAN The plan name to use in the OPEN call.
CONTROL This variable is used to shut down processing
because of unsatisfactory return or reason codes.
The CHECKCODE subroutine sets this value.
CAFCALL List-form parameter area for the CALL macro.
62 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Example of checking return codes and reason codes when using CAF
The following example code illustrates a way to check the return codes and the Db2 termination ECB after
each connection service request and SQL call. The routine sets the variable CONTROL to control further
processing within the module.
***********************************************************************
* CHEKCODE PSEUDOCODE *
***********************************************************************
*IF TECB is POSTed with the ABTERM or FORCE codes
* THEN
* CONTROL = 'SHUTDOWN'
* WRITE 'DB2 found FORCE or ABTERM, shutting down'
* ELSE /* Termination ECB was not POSTed */
* SELECT (RETCODE) /* Look at the return code */
* WHEN (0) ; /* Do nothing; everything is OK */
* WHEN (4) ; /* Warning */
* SELECT (REASCODE) /* Look at the reason code */
* WHEN ('00C10824'X) /* Ready for another CAF call */
* CONTROL = 'RESTART' /* Start over, from the top */
* OTHERWISE
* WRITE 'Found unexpected R0 when R15 was 4'
* CONTROL = 'SHUTDOWN'
* END INNER-SELECT
* WHEN (8,12) /* Connection failure */
* SELECT (REASCODE) /* Look at the reason code */
* WHEN ('00C10831'X) /* DB2 / CAF release level mismatch*/
* WRITE 'Found a mismatch between DB2 and CAF release levels'
* WHEN ('00F30002'X, /* These mean that DB2 is down but */
* '00F30012'X) /* will POST SECB when up again */
* DO
* WRITE 'DB2 is unavailable. I'll tell you when it is up.'
* WAIT SECB /* Wait for DB2 to come up */
* WRITE 'DB2 is now available.'
* END
* /**********************************************************/
* /* Insert tests for other DB2 connection failures here. */
* /* CAF Externals Specification lists other codes you can */
* /* receive. Handle them in whatever way is appropriate */
* /* for your application. */
* /**********************************************************/
* OTHERWISE /* Found a code we're not ready for*/
* WRITE 'Warning: DB2 connection failure. Cause unknown'
* CALL DSNALI ('TRANSLATE',SQLCA) /* Fill in SQLCA */
* WRITE SQLCODE and SQLERRM
* END INNER-SELECT
* WHEN (200)
* WRITE 'CAF found user error. See DSNTRACE data set'
* WHEN (204)
* WRITE 'CAF system error. See DSNTRACE data set'
* OTHERWISE
* CONTROL = 'SHUTDOWN'
* WRITE 'Got an unrecognized return code'
* END MAIN SELECT
* IF (RETCODE > 4) THEN /* Was there a connection problem?*/
* CONTROL = 'SHUTDOWN'
* END CHEKCODE
***********************************************************************
* Subroutine CHEKCODE checks return codes from DB2 and Call Attach.
* When CHEKCODE receives control, R13 should point to the caller's
* save area.
***********************************************************************
CHEKCODE DS 0H
STM R14,R12,12(R13) Prolog
ST R15,RETCODE Save the return code
ST R0,REASCODE Save the reason code
LA R15,SAVEAREA Get save area address
ST R13,4(,R15) Chain the save areas
ST R15,8(,R13) Chain the save areas
LR R13,R15 Put save area address in R13
* ********************* HUNT FOR FORCE OR ABTERM ***************
TM TECB,POSTBIT See if TECB was POSTed
BZ DOCHECKS Branch if TECB was not POSTed
CLC TECBCODE(3),QUIESCE Is this "STOP DB2 MODE=FORCE"
BE DOCHECKS If not QUIESCE, was FORCE or ABTERM
MVC CONTROL,SHUTDOWN Shutdown
WRITE 'Found found FORCE or ABTERM, shutting down'
B ENDCCODE Go to the end of CHEKCODE
64 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
L R13,4(,R13) Point to caller's save area
RETURN (14,12) Return to the caller
Example of invoking CAF when you do not specify the precompiler option ATTACH(CAF)
Each of the four Db2 attachment facilities contains an entry point named DSNHLI. When you use CAF
but do not specify the precompiler option ATTACH(CAF), SQL statements result in BALR instructions to
DSNHLI in your program. To find the correct DSNHLI entry point without including DSNALI in your load
module, code a subroutine with entry point DSNHLI that passes control to entry point DSNHLI2 in the
DSNALI module. DSNHLI2 is unique to DSNALI and is at the same location in DSNALI as DSNHLI. DSNALI
uses 31-bit addressing. If the application that calls this intermediate subroutine uses 24-bit addressing,
this subroutine should account for the difference.
In the following example, LISQL is addressable because the calling CSECT used the same register 12 as
CSECT DSNHLI. Your application must also establish addressability to LISQL.
***********************************************************************
* Subroutine DSNHLI intercepts calls to LI EP=DSNHLI
***********************************************************************
DS 0D
DSNHLI CSECT Begin CSECT
STM R14,R12,12(R13) Prologue
LA R15,SAVEHLI Get save area address
ST R13,4(,R15) Chain the save areas
ST R15,8(,R13) Chain the save areas
LR R13,R15 Put save area address in R13
L R15,LISQL Get the address of real DSNHLI
BASSM R14,R15 Branch to DSNALI to do an SQL call
* DSNALI is in 31-bit mode, so use
* BASSM to assure that the addressing
* mode is preserved.
L R13,4(,R13) Restore R13 (caller's save area addr)
L R14,12(,R13) Restore R14 (return address)
RETURN (1,12) Restore R1-12, NOT R0 and R15 (codes)
Procedure
To invoke RRSAF:
1. Perform one of the following actions:
• Explicitly invoke RRSAF by including in your program CALL DSNRLI statements with the appropriate
options.
The first option is an RRSAF connection function, which describes the action that you want RRSAF
to take. The effect of any function depends in part on what functions the program has already
performed.
66 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
To code RRSAF functions in C, COBOL, Fortran, or PL/I, follow the individual language's rules for
making calls to assembler language routines. Specify the return code and reason code parameters in
the parameter list for each RRSAF call.
Requirement: For C, C++, and PL/I applications, you must also include in your program the compiler
directives that are listed in the following table, because DSNRLI is an assembler language program.
Table 15. Compiler directives to include in C, C++, and PL/I applications that contain CALL DSNRLI
statements
Language Compiler directive to include
• Implicitly invoke RRSAF by including SQL statements or IFI calls in your program just as you would
in any program. The RRSAF facility establishes the connection to Db2 with the default values for the
subsystem name, plan name and authorization ID.
Restriction: If your program can make its first SQL call from different modules with different DBRMs,
you cannot use a default plan name and thus, you cannot implicitly invoke RRSAF. Instead, you must
explicitly invoke RRSAF by calling the CREATE THREAD function.
Requirement: If your application includes both SQL and IFI calls, you must issue at least one SQL
call before you issue any IFI calls. This action ensures that your application uses the correct plan.
2. If you implicitly invoked RRSAF, determine if the implicit connection was successful by examining
the return code and reason code immediately after the first executable SQL statement within the
application program. Your program can check these codes by performing one of the following actions:
• Examine registers 0 and 15 directly.
• Examine the SQLCA, and if the SQLCODE is -981, obtain the return and reason code from the
message text. The return code is the first token, and the reason code is the second token.
If the implicit connection is successful, the application can examine the SQLCODE for the first, and
subsequent, SQL statements.
68 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
• Supply event control blocks (ECBs), for Db2 to post, that signal start-up or termination.
• Intercept return codes, reason codes, and abend codes from Db2 and translate them into messages as
required.
RRSAF uses z/OS Transaction Management and Recoverable Resource Manager Services (z/OS RRS).
Any task in an address space can establish a connection to Db2 through RRSAF. Each task control block
(TCB) can have only one connection to Db2. A Db2 service request that is issued by a program that
runs under a given task is associated with that task's connection to Db2. The service request operates
independently of any Db2 activity under any other task.
Each connected task can run a plan. Tasks within a single address space can specify the same plan,
but each instance of a plan runs independently from the others. A task can terminate its plan and run a
different plan without completely breaking its connection to Db2.
RRSAF does not generate task structures.
When you design your application, consider that using multiple simultaneous connections can increase
the possibility of deadlocks and Db2 resource contention.
Restriction: RRSAF does not provide attention processing exits or functional recovery routines. You can
provide whatever attention handling and functional recovery your application needs, but you must use
ESTAE/ESTAI type recovery routines only.
A tracing facility provides diagnostic messages that help you debug programs and diagnose errors in the
RRSAF code. The trace information is available only in a SYSABEND or SYSUDUMP dump.
To commit work in RRSAF applications, use the CPIC SRRCMIT function or the Db2 COMMIT statement.
To roll back work, use the CPIC SRRBACK function or the Db2 ROLLBACK statement.
Use the following guidelines to decide whether to use the Db2 statements or the CPIC functions for
commit and rollback operations:
• Use Db2 COMMIT and ROLLBACK statements when all of the following conditions are true:
– The only recoverable resource that is accessed by your application is Db2 data that is managed by a
single Db2 instance.
Db2 COMMIT and ROLLBACK statements fail if your RRSAF application accesses recoverable
resources other than Db2 data that is managed by a single Db2 instance.
– The address space from which syncpoint processing is initiated is the same as the address space that
is connected to Db2.
• If your application accesses other recoverable resources, or syncpoint processing and Db2 access are
initiated from different address spaces, use SRRCMIT and SRRBACK.
Related reference
COMMIT (Db2 SQL)
ROLLBACK (Db2 SQL)
Related information
Using Protected Resources (MVS Programming: Callable Services for High-Level Languages)
70 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 16. Properties of RRSAF connections (continued)
Property Value Comments
Scope RRSAF processes connections as None.
if each task is entirely isolated.
When a task requests a function,
RRSAF passes the function to
Db2, regardless of the connection
status of other tasks in the
address space. However, the
application program and the Db2
subsystem have access to the
connection status of multiple
tasks in an address space.
If an application that is connected to Db2 through RRSAF terminates normally before the TERMINATE
THREAD or TERMINATE IDENTIFY functions deallocate the plan, RRS commits any changes made after
the last commit point. If the application terminates abnormally before the TERMINATE THREAD or
TERMINATE IDENTIFY functions deallocate the plan, z/OS RRS rolls back any changes made after the
last commit point. In either case, Db2 deallocates the plan, if necessary, and terminates the application's
connection.
If Db2 abends while an application is running, Db2 rolls back changes to the last commit point. If Db2
terminates while processing a commit request, Db2 either commits or rolls back any changes at the next
restart. The action taken depends on the state of the commit request when Db2 terminates.
Procedure
To make DSNRLI available:
1. Decide which of the following methods you want to use to make DSNRLI available:
• Explicitly issuing LOAD requests when your program runs.
By explicitly loading the DSNRLI module, you can isolate the maintenance of your application from
future IBM maintenance to the language interface. If the language interface changes, the change will
probably not affect your load module.
• Including the DSNRLI module in your load module when you link-edit your program.
A disadvantage of link-editing DSNRLI into your load module is that if IBM makes a change to
DSNRLI, you must link-edit your program again.
INCLUDE DB2LIB(DSNRLI).
By coding this statement, you avoid inadvertently picking up the wrong language interface module.
When you include the DSNRLI module during the link-edit, do not include a dummy DSNHLI entry
point in your program or specify the precompiler option ATTACH. Module DSNRLI contains an entry
point for DSNHLI, which is identical to DSNHLIR, and an entry point for DSNWLI, which is identical to
DSNWLIR.
Related concepts
Program examples for RRSAF
The Resource Recovery Services attachment facility (RRSAF) enables programs to communicate with
Db2. You can use RRSAF as an alternative to CAF.
“Universal language interface (DSNULI)” on page 113
The universal language interface (DSNULI) subcomponent determines the runtime environment and
dynamically loads and branches to the appropriate language interface module.
Related tasks
Making the CAF language interface (DSNALI) available
Before you can invoke the call attachment facility (CAF), you must first make DSNALI available.
Link-editing an application with DSNULI
To create a single load module that can be used in more than one attachment environment, you can
link-edit your program or stored procedure with the Universal Language Interface module (DSNULI)
instead of with one of the environment-specific language interface modules (DSNELI, DSNALI, DSNRLI,
DSNCLI, or DFSLI000).
72 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
• The program accounts for the size of the RRSAF code. The RRSAF code requires about 10 KB of virtual
storage per address space and an additional 10 KB for each TCB that uses RRSAF.
• If your local environment intercepts and replaces the z/OS LOAD SVC that RRSAF uses, you must ensure
that your version of LOAD manages the load list element (LLE) and contents directory entry (CDE)
chains like the standard z/OS LOAD macro. RRSAF uses z/OS SVC LOAD to load a module as part of the
initialization after your first service request. The module is loaded into fetch-protected storage that has
the job-step protection key.
You can prepare application programs to run in RRSAF similar to how you prepare applications to run
in other environments, such as CICS, IMS, and TSO. You can prepare an RRSAF application either in
the batch environment or by using the Db2 program preparation process. You can use the program
preparation system either through DB2I or through the DSNH CLIST.
Related tasks
Preparing an application to run on Db2 for z/OS
To prepare and run applications that contain embedded static SQL statements or dynamic SQL
statements, you must process, compile, link-edit, and bind the SQL statements.
• For all languages except assembler language, code zero for that parameter in the CALL DSNRLI
statement. For example, suppose that you are coding an IDENTIFY call in a COBOL program, and you
want to specify all parameters except the return code parameter. You can write a statement similar to
the following statement:
• For assembler language, code a comma for that parameter in the CALL DSNRLI statement. For example,
suppose that you are coding an IDENTIFY call, and you want to specify all parameters except the return
code parameter. You can write a statement similar to the following statement:
CALL DSNRLI,(IDFYFN,SSNM,RIBPTR,EIBPTR,TERMECB,STARTECB,,REASCODE)
For assembler programs that invoke RRSAF, use a standard parameter list for an z/OS CALL. Register 1
must contain the address of a list of pointers to the parameters. Each pointer is a 4-byte address. The last
address must contain the value 1 in the high-order bit.
74 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Summary of RRSAF behavior
The effect of any Resource Recovery Services attachment facility (RRSAF) function depends in part on
what functions the program has already run. You should plan the RRSAF function calls that your program
makes to avoid any errors and major structural problems in your application.
The following tables summarize RRSAF behavior after various inputs from application programs. The
contents of each table cell indicate the result of calling the function in the first column for that row
followed by the function in the current column heading. For example, if you issue TERMINATE THREAD
and then IDENTIFY, RRSAF returns reason code X'00C12201'. Use these tables to understand the order
in which your application must issue RRSAF calls, SQL statements, and IFI requests.
The RRSAF FIND_DB2_SYSTEMS function is omitted from these tables, because it does not affect the
operation of any of the other functions
The following table summarizes RRSAF behavior when the next call is to the IDENTIFY function, the
SWITCH TO function, the SIGNON function, or the CREATE THREAD function.
Table 18. Effect of call order when next call is IDENTIFY, SWITCH TO, SIGNON, or CREATE THREAD
Next function
IDENTIFY SWITCH TO SIGNON, AUTH SIGNON, CREATE THREAD
Previous function or CONTEXT SIGNON
Empty: first call IDENTIFY X'00C12205'1 X'00C12204'1 X'00C12204'1
IDENTIFY X'00F30049'1 Switch to ssnm Signon 2 X'00C12217'1
SWITCH TO IDENTIFY Switch to ssnm Signon 2 CREATE THREAD
SIGNON, AUTH SIGNON, X'00F30049'1 Switch to ssnm Signon 2 CREATE THREAD
or CONTEXT SIGNON
CREATE THREAD X'00F30049'1 Switch to ssnm Signon 2 X'00C12202'1
TERMINATE THREAD X'00C12201'1 Switch to ssnm Signon 2 CREATE THREAD
IFI X'00F30049'1 Switch to ssnm Signon 2 X'00C12202'1
SQL X'00F30049'1 Switch to ssnm X'00F30092'13 X'00C12202'1
SRRCMIT or SRRBACK X'00F30049'1 Switch to ssnm Signon 2 X'00C12202'1
Notes:
1. Errors are identified by the Db2 reason code that RRSAF returns.
2. Signon means either the SIGNON function, the AUTH SIGNON function, or the CONTEXT SIGNON function.
3. The SIGNON, AUTH SIGNON, or CONTEXT SIGNON functions are not allowed if any SQL operations are
requested after the CREATE THREAD function or after the last SRRCMIT or SRRBACK request.
The following table summarizes RRSAF behavior when the next call is an SQL statement or an IFI call or
to the TERMINATE THREAD function, the TERMINATE IDENTIFY function, or the TRANSLATE function.
Table 19. Effect of call order when next call is SQL or IFI, TERMINATE THREAD, TERMINATE IDENTIFY, or
TRANSLATE
Next function
Previous function SQL or IFI TERMINATE THREAD TERMINATE IDENTIFY TRANSLATE
Empty: first call SQL or IFI call4 X'00C12204'1 X'00C12204'1 X'00C12204'1
IDENTIFY SQL or IFI call4 X'00C12203'1 TERMINATE IDENTIFY TRANSLATE
SWITCH TO SQL or IFI call4 TERMINATE THREAD TERMINATE IDENTIFY TRANSLATE
Notes:
1. Errors are identified by the Db2 reason code that RRSAF returns.
2. TERMINATE THREAD is not allowed if any SQL operations are requested after the CREATE THREAD function
or after the last SRRCMIT or SRRBACK request.
3. TERMINATE IDENTIFY is not allowed if any SQL operations are requested after the CREATE THREAD
function or after the last SRRCMIT or SRRBACK request.
4. If you are using an implicit connection to RRSAF and issue SQL or IFI calls, RRSAF issues implicit IDENTIFY
and CREATE THREAD requests. If you continue with explicit RRSAF statements, you must follow the
standard order of explicit RRSAF calls. Implicitly connecting to RRSAF does not cause an implicit SIGNON
request. Therefore, you might need to issue an explicit SIGNON request to satisfy the standard order
requirement. For example, an SQL statement followed by an explicit TERMINATE THREAD request results in
an error. You must issue an explicit SIGNON request before issuing the TERMINATE THREAD request.
Related concepts
X'C1......' codes (Db2 Codes)
X'F3......' codes (Db2 Codes)
76 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
The following diagram shows the syntax for the IDENTIFY function.
startecb
, retcode
, reascode
, groupoverride
, decpptr
startecb
The address of the application's startup ECB. If Db2 has not started when the application issues the
IDENTIFY call, Db2 posts the ECB when Db2 has started. If Db2 is already started, the startup ECB
is ignored. and is not applied to the next Db2 startup. If Db2 is not started, and the startup ECB is
queued, the termination ECB is ignored.
Enter a value of zero if you do not want to use a startup ECB. Db2 posts no more than one startup
ECB per address space. The ECB that is posted is associated with the most recent IDENTIFY call from
that address space. The application program must examine any nonzero RRSAF or Db2 reason codes
before issuing a WAIT request on this ECB.
retcode
A 4-byte area in which RRSAF places the return code.
This parameter is optional. If you do not specify retcode, RRSAF places the return code in register 15
and the reason code in register 0.
reascode
A 4-byte area in which RRSAF places a reason code.
This parameter is optional. If you do not specify reascode, RRSAF places the reason code in register 0.
If you specify reascode, you must also specify retcode or its default. You can specify a default for
retcode by specifying a comma or zero, depending on the language.
groupoverride
An 8-byte area that the application provides. This parameter is optional. If you do not want group
attach to be attempted, specify 'NOGROUP'. This string indicates that the subsystem name that is
specified by ssnm is to be used as a Db2 subsystem name, even if ssnm matches a group attachment
or subgroup attachment name. If groupoverride is not provided, ssnm is used as the group attachment
or subgroup attachment name if it matches a group attachment or subgroup attachment name.
If you specify this parameter in any language except assembler, you must also specify the retcode and
reascode parameters. In assembler language, you can omit the retcode and reascode parameters by
specifying commas as place-holders.
Recommendation: Avoid using the groupoverride parameter when possible, because it limits the
ability to do dynamic workload routing in a Parallel Sysplex. However, you should use this parameter
in a data sharing environment when you want to connect to a specific member of a data sharing
group, and the subsystem name of that member is the same as the group attachment or subgroup
attachment name.
decpptr
A 4-byte area in which RRSAF is to put the address of the DSNHDECP or a user-specified application
defaults module that was loaded by subsystem ssnm when that subsystem was started. This 4-byte
area is a 31-bit pointer. If ssnm is not found, the 4-byte area is set to 0.
The area to which decpptr points is above the 16-MB line.
If you specify this parameter in any language except assembler, you must also specify the retcode,
reascode, and groupoverride parameters. In assembler language, you can omit the retcode, reascode,
and groupoverride parameters by specifying commas as placeholders.
78 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Example of RRSAF IDENTIFY function calls
The following table shows an IDENTIFY call in each language.
C1
fnret=dsnrli(&idfyfn[0],&ssnm[0], &ribptr, &eibptr, &termecb, &startecb, &retcode,
&reascode,&grpover[0],&decpptr);
COBOL
CALL 'DSNRLI' USING IDFYFN SSNM RIBTPR EIBPTR TERMECB STARTECB RETCODE REASCODE
GRPOVER
DECPPTR.
Fortran
CALL DSNRLI(IDFYFN,SSNM,RIBPTR,EIBPTR,TERMECB,STARTECB,
RETCODE,REASCODE,GRPOVER,DECPPTR)
PL/I1
CALL DSNRLI(IDFYFN,SSNM,RIBPTR,EIBPTR,TERMECB,STARTECB,
RETCODE,REASCODE,GRPOVER,DECPPTR);
Note:
1. For C, C++, and PL/I applications, you must include the appropriate compiler directives, because
DSNRLI is an assembler language program. These compiler directives are described in the instructions
for invoking RRSAF.
)
, retcode
, reascode
, groupoverride
80 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
If you specify this parameter in any language except assembler, you must also specify the retcode and
reascode parameters. In assembler language, you can omit the retcode and reascode parameters by
specifying commas as place-holders.
Recommendation: Avoid using the groupoverride parameter when possible, because it limits the
ability to do dynamic workload routing in a Parallel Sysplex. However, you should use this parameter
in a data sharing environment when you want to connect to a specific member of a data sharing
group, and the subsystem name of that member is the same as the group attachment or subgroup
attachment name.
C1
fnret=dsnrli(&switchfn[0], &ssnm[0], &retcode,
&reascode,&grpover[0]);
COBOL
CALL 'DSNRLI' USING SWITCHFN RETCODE REASCODE GRPOVER.
Fortran
CALL DSNRLI(SWITCHFN,RETCODE,REASCODE,GRPOVER)
PL/I1
CALL DSNRLI(SWITCHFN,RETCODE,REASCODE,GRPOVER);
1. For C, C++, and PL/I applications, you must include the appropriate compiler directives, because
DSNRLI is an assembler language program. These compiler directives are described in the instructions
for invoking RRSAF.
Example of using the SWITCH TO function to interact with multiple Db2 subsystems
The following example shows how you can use the SWITCH TO function to interact with three Db2
subsystems.
Related tasks
Invoking the Resource Recovery Services attachment facility
The Resource Recovery Services attachment facility (RRSAF) enables your program to communicate with
Db2. Invoke RRSAF as an alternative to invoking CAF or when using stored procedures that run in a
WLM-established address space. RRSAF has more capabilities than CAF.
82 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
DSNRLI SIGNON function
CALL DSNRLI ( function, correlation-id, accounting-token, accounting-interval
,retcode
,reascode
,user
,appl
,ws
,xid
,accounting-string
0,0 0,0
0,0 0,0
84 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
('FFFFFFF'X). Db2 then replaces the contents of the area with the generated transaction ID. The
area at the specified address must be in writable storage and have a length of at least 140 bytes to
accommodate the largest possible transaction ID value.
The following table shows the format of a global transaction ID.
accounting-string
A one-byte length field and a 255-byte area in which you can put a value for a Db2 accounting string.
This value is placed in the DDF accounting trace records in the QMDASQLI field, which is mapped by
DSNDQMDA DSECT. If accounting-string is less than 255 characters, you must pad it on the right with
zeros to a length of 255 bytes. The entire 256 bytes is mapped by DSNDQMDA DSECT.
This parameter is optional. If you specify accounting-string, you must also specify retcode, reascode,
user, appl and xid. If you do not specify accounting-string, no accounting string is associated with the
connection.
You can also change the value of the accounting string with RRSAF functions AUTH SIGNON,
CONTEXT SIGNON, or SET_CLIENT_ID.
You can retrieve the DDF suffix portion of the accounting string with the CURRENT CLIENT_ACCTNG
special register. The suffix portion of accounting-string can contain a maximum of 200 characters.
The QMDASFLN field contains the accounting suffix length, and the QMDASUFX field contains the
accounting suffix value. If the DDF accounting string is set, you cannot query the accounting token
with the CURRENT CLIENT_ACCTNG special register.
The following parameters are optional and positional. These parameters override values specified earlier
in the parameter list. To provide a value for a length, value pair, you must provide a value or specify a 0
length for previous parameters in the parameter list.
user-length, user-longname
A pair of parameters that consist of a 2-byte integer length and 128-byte string area. A comma
separates the parameters. You can provide the user ID of the client user for accounting and
monitoring purposes in user-longname. Db2 displays this user ID in the output from the DISPLAY
THREAD command and in Db2 accounting and statistics trace records. Setting the user ID sets
the value of the CURRENT CLIENT_USERID special register. Trailing blanks in user-longname are
truncated and the length in user-length is updated.
These parameters are optional, to specify them you must also specify a value for accounting-string. A
value of 0 in user-length skips processing of user-longname.
Important: These parameters override any value that is provided in user.
appl-length, appl-longname
A pair of parameters that consist of a 2-byte integer length and 255-byte string area. A comma
separates the parameters.You can provide the application or transaction name of the client user for
accounting and monitoring purposes in appl-longname. Db2 displays this application name in the
output from the DISPLAY THREAD command and in Db2 accounting and statistics trace records.
Setting the application name sets the value of the CURRENT CLIENT_APPLNAME special register.
Trailing blanks in appl-longname are truncated and the length in appl-length is updated.
C1
fnret=dsnrli(&sgnonfn[0], &corrid[0], &accttkn[0], &acctint[0], &retcode, &reascode,
&userid[0], &applname[0], &wsname[0], &xidptr);
COBOL
CALL 'DSNRLI' USING SGNONFN CORRID ACCTTKN ACCTINT RETCODE REASCODE USERID APPLNAME
WSNAME
XIDPTR.
Fortran
CALL DSNRLI(SGNONFN,CORRID,ACCTTKN,ACCTINT,
RETCODE,REASCODE,USERID,APPLNAME,WSNAME,XIDPTR)
PL/I1
CALL DSNRLI(SGNONFN,CORRID,ACCTTKN,ACCTINT,
RETCODE,REASCODE,USERID,APPLNAME,WSNAME,XIDPTR);
Note:
1. For C, C++, and PL/I applications, you must include the appropriate compiler directives, because
DSNRLI is an assembler language program. These compiler directives are described in the instructions
for invoking RRSAF.
86 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
The following example shows a SIGNON call in C 1 with all parameters passed in. Parameters that are
numbers are passed in as integers and strings as character arrays. In this example, if &useridlen is
larger than 0, then the value of CURRENT CLIENT_USERID special register is the value that is stored in
&luserid[0].
fnret=dsnrli(&sgnonfn[0],&corrid[0],&accttkn[0],&acctint[0],&retcode,&reascode,
&userid[0],&applname[0],&wsname[0],&xidptr,&lacctngid[0],
&useridlen,&luserid[0],&applidlen,&lapplid[0],&wsidlen,&lwsid[0],
&corrtkidlen,&lcorrtkid[0]);
Note:
1. For C applications, you must include the appropriate compiler directives, because DSNRLI is an
assembler language program. These compiler directives are described in the instructions for invoking
RRSAF.
Related tasks
Invoking the Resource Recovery Services attachment facility
The Resource Recovery Services attachment facility (RRSAF) enables your program to communicate with
Db2. Invoke RRSAF as an alternative to invoking CAF or when using stored procedures that run in a
WLM-established address space. RRSAF has more capabilities than CAF.
Related reference
RACROUTE REQUEST=VERIFY (standard form) (Security Server RACROUTE Macro Reference)
,retcode
,reascode
,user
,appl
,ws
,xid
,accounting-string
0,0 0,0
0,0 0,0
88 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
user
A 16-byte area that contains the user ID of the client user. You can use this parameter to provide
the identity of the client user for accounting and monitoring purposes. Db2 displays this user ID in
the output from the DISPLAY THREAD command and in Db2 accounting and statistics trace records.
Setting the user ID sets the value of the CURRENT CLIENT_USERID special register. If user is less than
16 characters long, you must pad it on the right with blanks to a length of 16 characters.
This parameter is optional. If you specify user, you must also specify retcode and reascode. If you do
not specify this parameter, no user ID is associated with the connection.
appl
A 32-byte area that contains the application or transaction name of the user's application. You can
use this parameter to provide the identity of the client user for accounting and monitoring purposes.
Db2 displays the application name in the output from the DISPLAY THREAD command and in Db2
accounting and statistics trace records. Setting the application name sets the value of the CURRENT
CLIENT_APPLNAME special register. If appl is less than 32 characters long, you must pad it on the
right with blanks to a length of 32 characters.
This parameter is optional. If you specify appl, you must also specify retcode, reascode, and user. If
you do not specify this parameter, no application or transaction is associated with the connection.
ws
An 18-byte area that contains the workstation name of the client user. You can use this parameter
to provide the identity of the client user for accounting and monitoring purposes. Db2 displays
the workstation name in the output from the DISPLAY THREAD command and in Db2 accounting
and statistics trace records. Setting the workstation name sets the value of the CURRENT
CLIENT_WRKSTNNAME special register. If ws is less than 18 characters long, you must pad it on
the right with blanks to a length of 18 characters.
This parameter is optional. If you specify ws, you must also specify retcode, reascode, user, and appl.
If you do not specify this parameter, no workstation name is associated with the connection.
You can also change the value of the workstation name with RRSAF functions SIGNON,
CONTEXT SIGNON, or SET_CLIENT_ID. You can retrieve the workstation name with the CURRENT
CLIENT_WRKSTNNAME special register.
xid
A 4-byte area that indicates whether the thread is part of a global transaction. A Db2 thread that is
part of a global transaction can share locks with other Db2 threads that are part of the same global
transaction and can access and modify the same data. A global transaction exists until one of the
threads that is part of the global transaction is committed or rolled back.
You can specify one of the following values for xid:
0
Indicates that the thread is not part of a global transaction. The value 0 must be specified as a
binary integer.
1
Indicates that the thread is part of a global transaction and that Db2 should retrieve the global
transaction ID from RRS. If a global transaction ID already exists for the task, the thread becomes
part of the associated global transaction. Otherwise, RRS generates a new global transaction ID.
The value 1 must be specified as a binary integer. Alternatively, if you want Db2 to return the
generated global transaction ID to the caller, specify an address instead of 1.
address
The 4-byte address of an area into which you enter a global transaction ID for the thread. If the
global transaction ID already exists, the thread becomes part of the associated global transaction.
Otherwise, RRS creates a new global transaction with the ID that you specify.
Alternatively, if you want Db2 to generate and return a global transaction ID, pass the address of
a null global transaction ID by setting the format ID field of the global transaction ID to binary -1
('FFFFFFF'X). Db2 then replaces the contents of the area with the generated transaction ID. The
90 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Important: These parameters override any value that is provided in ws.
correlation-length, correlation-longname
A pair of parameters that consist of a 2-byte integer length and 255-byte string area. A comma
separates the parameters. You can provide a unique value to correlate your business process names
with Db2 threads in correlation-longname. Db2 displays this correlation token in the output from the
DISPLAY THREAD DETAIL command. The CURRENT CLIENT_CORR_TOKEN special register contains
the client correlation token. Trailing blanks in correlation-longname are truncated and the length in
correlation-length is updated.
These parameters are optional, to specify them you must also specify a value for ws-length, ws-
longname. A value of 0 in correlation-length skips processing of correlation-longname.
You can also change the value of the client correlation token with the RRSAF AUTH SIGNON function
and the SET_CLIENT_ID function.
C1
fnret=dsnrli(&asgnonfn[0], &corrid[0], &accttkn[0], &acctint[0], &pauthid[0], &aceeptr,
&sauthid[0], &retcode, &reascode, &userid[0], &applname[0], &wsname[0], &xidptr);
COBOL
CALL 'DSNRLI' USING ASGNONFN CORRID ACCTTKN ACCTINT PAUTHID ACEEPTR SAUTHID RETCODE
REASCODE
USERID APPLNAME WSNAME XIDPTR.
Fortran
CALL DSNRLI(ASGNONFN,CORRID,ACCTTKN,ACCTINT,PAUTHID,ACEEPTR,
SAUTHID,RETCODE,REASCODE,USERID,
APPLNAME,WSNAME,XIDPTR)
PL/I1
CALL DSNRLI(ASGNONFN,CORRID,ACCTTKN,ACCTINT,PAUTHID,ACEEPTR,
SAUTHID,RETCODE,REASCODE,USERID,
APPLNAME,WSNAME,XIDPTR);
Note:
1. For C, C++, and PL/I applications, you must include the appropriate compiler directives, because
DSNRLI is an assembler language program. These compiler directives are described in the instructions
for invoking RRSAF.
The following example shows an AUTH SIGNON call in C 1 with all parameters passed in. Parameters that
are numbers are passed in as integers and strings as character arrays. In this example, if &useridlen is
larger than 0, then the value of CURRENT CLIENT_USERID special register is the value that is stored in
&luserid[0].
fnret = dsnrli(&authsgnfn[0],&corrid[0],&acctkn[0],&accint[0],&pauthid[0],
&aceeptr,&sauthid[0],&retcode,&reascode,&userid[0],&applname[0],
&wsname[0],&xidptr,&lacctngid[0],&useridlen,&luserid[0],&applidlen,
&lapplid[0],&wsidlen,&lwsid[0],&corrtkidlen,&lcorrtkid[0]);
Note:
92 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
DSNRLI CONTEXT SIGNON function
CALL DSNRLI ( function, correlation-id, accounting-token, accounting-interval,
context-key
,retcode
,reascode
,user
,appl
,ws
,xid
,accounting-string
94 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
address
The 4-byte address of an area into which you enter a global transaction ID for the thread. If the
global transaction ID already exists, the thread becomes part of the associated global transaction.
Otherwise, RRS creates a new global transaction with the ID that you specify.
Alternatively, if you want Db2 to generate and return a global transaction ID, pass the address of
a null global transaction ID by setting the format ID field of the global transaction ID to binary -1
('FFFFFFF'X). Db2 then replaces the contents of the area with the generated transaction ID. The
area at the specified address must be in writable storage and have a length of at least 140 bytes to
accommodate the largest possible transaction ID value.
The format of a global transaction ID is shown in the description of the RRSAF SIGNON function.
accounting-string
A one-byte length field and a 255-byte area in which you can put a value for a Db2 accounting string.
This value is placed in the DDF accounting trace records in the QMDASQLI field, which is mapped by
DSNDQMDA DSECT. If accounting-string is less than 255 characters, you must pad it on the right with
zeros to a length of 255 bytes. The entire 256 bytes is mapped by DSNDQMDA DSECT.
This parameter is optional. If you specify this accounting-string, you must also specify retcode,
reascode, user, appl and xid. If you do not specify this parameter, no accounting string is associated
with the connection.
You can also change the value of the accounting string with RRSAF functions AUTH SIGNON,
CONTEXT SIGNON, or SET_CLIENT_ID.
You can retrieve the DDF suffix portion of the accounting string with the CURRENT CLIENT_ACCTNG
special register. The suffix portion of accounting-string can contain a maximum of 200 characters.
The QMDASFLN field contains the accounting suffix length, and the QMDASUFX field contains the
accounting suffix value. If the DDF accounting string is set, you cannot query the accounting token
with the CURRENT CLIENT_ACCTNG special register.
C1
fnret=dsnrli(&csgnonfn[0], &corrid[0], &accttkn[0], &acctint[0], &ctxtkey[0], &retcode,
&reascode, &userid[0], &applname[0], &wsname[0], &xidptr);
COBOL
CALL 'DSNRLI' USING CSGNONFN CORRID ACCTTKN ACCTINT CTXTKEY RETCODE REASCODE USERID
APPLNAME
WSNAME XIDPTR.
Fortran
CALL DSNRLI(CSGNONFN,CORRID,ACCTTKN,ACCTINT,CTXTKEY, RETCODE,REASCODE, USERID,APPLNAME,
WSNAME,XIDPTR)
PL/I1
CALL DSNRLI(CSGNONFN,CORRID,ACCTTKN,ACCTINT,CTXTKEY, RETCODE,REASCODE,USERID,APPLNAME,
WSNAME,XIDPTR);
Note:
1. For C, C++, and PL/I applications, you must include the appropriate compiler directives, because
DSNRLI is an assembler language program. These compiler directives are described in the instructions
for invoking RRSAF.
C1
fnret=dsnrli(&setidfn[0], &progid[0], &retcode, &reascode);
96 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 27. Examples of RRSAF SET_ID calls (continued)
Language Call example
COBOL
CALL 'DSNRLI' USING SETIDFN PROGID RETCODE REASCODE.
Fortran
CALL DSNRLI(SETIDFN,PROGID,RETCODE,REASCODE)
PL/I1
CALL DSNRLI(SETIDFN,PROGID,RETCODE,REASCODE);
Note:
1. For C, C++, and PL/I applications, you must include the appropriate compiler directives, because
DSNRLI is an assembler language program. These compiler directives are described in the instructions
for invoking RRSAF.
Related tasks
Invoking the Resource Recovery Services attachment facility
The Resource Recovery Services attachment facility (RRSAF) enables your program to communicate with
Db2. Invoke RRSAF as an alternative to invoking CAF or when using stored procedures that run in a
WLM-established address space. RRSAF has more capabilities than CAF.
0 0
appl , ws ,
0 0
0 0 0 0 long-name
98 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
You can omit this parameter by specifying a value of 0 in the parameter list.
This parameter is optional. If you do not specify reascode, RRSAF places the reason code in register 0.
If you specify reascode, you must also specify retcode.
accounting-string
A one-byte length field and a 255-byte area in which you can put a value for a Db2 accounting string.
This value is placed in the DDF accounting trace records in the QMDASUFX field, which is mapped by
DSNDQMDA DSECT. If accounting-string is less than 255 characters, you must pad it on the right with
zeros to a length of 255 bytes. The entire 256 bytes is mapped by DSNDQMDA DSECT.
You can omit this parameter by specifying a value of 0 in the parameter list.
This parameter is optional. If you specify this accounting-string, you must also specify retcode,
reascode, user, and appl. If you do not specify this parameter, no accounting string is associated
with the connection.
You can also change the value of the accounting string with RRSAF functions AUTH SIGNON,
CONTEXT SIGNON, or SET_CLIENT_ID.
You can retrieve the DDF suffix portion of the accounting string with the CURRENT CLIENT_ACCTNG
special register. The suffix portion of accounting-string can contain a maximum of 200 characters.
The QMDASFLN field contains the accounting suffix length, and the QMDASUFX field contains the
accounting suffix value. If the DDF accounting string is set, you cannot query the accounting token
with the CURRENT CLIENT_ACCTNG special register.
corr-token
An 255-byte area where you specify a client correlation token. You can specify a unique value to
correlate your business process within Db2 and your entire business enterprise. The value of corr-
token is displayed by the DISPLAY THREAD DETAIL command. The CURRENT CLIENT_CORR_TOKEN
special register contains the client correlation token. If corr-token is less than 255 characters, you
must pad it on the right with blanks to a length of 255 bytes.
You can omit this parameter by specifying a value of 0 in the parameter list. If you specify corr-token
you must also specify long-name.
You can also change the value of the client correlation token with the RRSAF SIGNON function.
long-name
An 8-byte area that contains the value LONGNAME.
This optional parameter is used to indicate to the RRSAF function that the input parameters user,
appl, ws, accounting-string, and corr-token can accept longer lengths. You cannot selectively associate
the long-name parameter with any individual parameter.
C1
fnret=dsnrli(&seclidfn[0], &acct[0], &user[0], &appl[0], &ws[0], &retcode,
&reascode, &accountingstring[0], &corrtoken[0], &longname[0]);
COBOL
CALL 'DSNRLI' USING SECLIDFN ACCT USER APPL WS RETCODE REASCODE
ACCOUNTING-STRING CORR-TOKEN LONG-NAME.
PL/I1
CALL DSNRLI(SECLIDFN,ACCT,USER,APPL,WS,RETCODE,REASCODE,
ACCOUNTINGSTRING,CORRTOKEN,LONGNAME);
Note:
1. For C, C++, and PL/I applications, you must include the appropriate compiler directives, because
DSNRLI is an assembler language program. These compiler directives are described in the instructions
for invoking RRSAF.
Related tasks
Invoking the Resource Recovery Services attachment facility
The Resource Recovery Services attachment facility (RRSAF) enables your program to communicate with
Db2. Invoke RRSAF as an alternative to invoking CAF or when using stored procedures that run in a
WLM-established address space. RRSAF has more capabilities than CAF.
100 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
The Resource Recovery Services attachment facility (RRSAF) enables your program to communicate with
Db2. Invoke RRSAF as an alternative to invoking CAF or when using stored procedures that run in a
WLM-established address space. RRSAF has more capabilities than CAF.
)
, retcode
, reascode
, pklistptr
102 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 29. Examples of RRSAF CREATE THREAD calls (continued)
Languag
e Call example
COBOL
CALL 'DSNRLI' USING CRTHRDFN PLAN COLLID REUSE RETCODE REASCODE PKLSTPTR.
Fortran
CALL DSNRLI(CRTHRDFN,PLAN,COLLID,REUSE,RETCODE,REASCODE,PKLSTPTR)
PL/I1
CALL DSNRLI(CRTHRDFN,PLAN,COLLID,REUSE,RETCODE,REASCODE,PKLSTPTR);
Note:
1. For C, C++, and PL/I applications, you must include the appropriate compiler directives, because
DSNRLI is an assembler language program. These compiler directives are described in the instructions
for invoking RRSAF.
Related tasks
Invoking the Resource Recovery Services attachment facility
The Resource Recovery Services attachment facility (RRSAF) enables your program to communicate with
Db2. Invoke RRSAF as an alternative to invoking CAF or when using stored procedures that run in a
WLM-established address space. RRSAF has more capabilities than CAF.
Authorizing plan or package access through applications (Managing Security)
Related reference
BIND and REBIND options for packages, plans, and services (Db2 Commands)
C1
fnret=dsnrli(&trmthdfn[0], &retcode, &reascode);
COBOL
CALL 'DSNRLI' USING TRMTHDFN RETCODE REASCODE.
Fortran
CALL DSNRLI(TRMTHDFN,RETCODE,REASCODE)
PL/I1
CALL DSNRLI(TRMTHDFN,RETCODE,REASCODE);
Note:
1. For C, C++, and PL/I applications, you must include the appropriate compiler directives, because
DSNRLI is an assembler language program. These compiler directives are described in the instructions
for invoking RRSAF.
Related tasks
Invoking the Resource Recovery Services attachment facility
The Resource Recovery Services attachment facility (RRSAF) enables your program to communicate with
Db2. Invoke RRSAF as an alternative to invoking CAF or when using stored procedures that run in a
WLM-established address space. RRSAF has more capabilities than CAF.
104 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
DSNRLI TERMINATE IDENTIFY function
CALL DSNRLI ( function )
, retcode
, reascode
C1
fnret=dsnrli(&tmidfyfn[0], &retcode, &reascode);
COBOL
CALL 'DSNRLI' USING TMIDFYFN RETCODE REASCODE.
Fortran
CALL DSNRLI(TMIDFYFN,RETCODE,REASCODE)
PL/I1
CALL DSNRLI(TMIDFYFN,RETCODE,REASCODE);
Note:
1. For C, C++, and PL/I applications, you must include the appropriate compiler directives, because
DSNRLI is an assembler language program. These compiler directives are described in the instructions
for invoking RRSAF.
Related tasks
Invoking the Resource Recovery Services attachment facility
106 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 32. Examples of RRSAF TRANSLATE calls
Language Call example
Assembler
CALL DSNRLI,(XLATFN,SQLCA,RETCODE,REASCODE)
C1
fnret=dsnrli(&connfn[0], &sqlca, &retcode, &reascode);
COBOL
CALL 'DSNRLI' USING XLATFN SQLCA RETCODE REASCODE.
PL/I1
CALL DSNRLI(XLATFN,SQLCA,RETCODE,REASCODE);
Note:
1. For C, C++, and PL/I applications, you must include the appropriate compiler directives, because
DSNRLI is an assembler language program. These compiler directives are described in the instructions
for invoking RRSAF.
Related tasks
Invoking the Resource Recovery Services attachment facility
The Resource Recovery Services attachment facility (RRSAF) enables your program to communicate with
Db2. Invoke RRSAF as an alternative to invoking CAF or when using stored procedures that run in a
WLM-established address space. RRSAF has more capabilities than CAF.
)
, retcode
, reascode
Related tasks
Invoking the Resource Recovery Services attachment facility
The Resource Recovery Services attachment facility (RRSAF) enables your program to communicate with
Db2. Invoke RRSAF as an alternative to invoking CAF or when using stored procedures that run in a
WLM-established address space. RRSAF has more capabilities than CAF.
108 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Related reference
TRANSLATE function for RRSAF
The RRSAF TRANSLATE function converts a hexadecimal reason code for a Db2 error into a signed integer
SQL code and a printable error message. The SQL code and message text are placed in the SQLCODE and
SQLSTATE host variables or related fields of the SQLCA.
A single task
The following example pseudocode illustrates a single task running in an address space that explicitly
connects to Db2 through RRSAF. z/OS RRS controls commit processing when the task terminates
normally.
IDENTIFY
SIGNON
CREATE THREAD
SQL or IFI
⋮
TERMINATE IDENTIFY
Multiple tasks
In the following scenario, multiple tasks in an address space explicitly connect to Db2 through RRSAF.
Task 1 executes no SQL statements and makes no IFI calls. Its purpose is to monitor Db2 termination and
startup ECBs and to check the Db2 release level.
IDENTIFY
SIGNON user A
CREATE THREAD
SQL
...
SRRCMIT
SIGNON user B
SQL
...
SRRCMIT
Task 1 Task 2
110 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Program examples for RRSAF
The Resource Recovery Services attachment facility (RRSAF) enables programs to communicate with
Db2. You can use RRSAF as an alternative to CAF.
//SYSPRINT DD SYSOUT=*
//DSNRRSAF DD DUMMY
//SYSUDUMP DD SYSOUT=*
***********************************************************************
* Subroutine DSNHLI intercepts calls to LI EP=DSNHLI
***********************************************************************
DS 0D
DSNHLI CSECT Begin CSECT
STM R14,R12,12(R13) Prologue
LA R15,SAVEHLI Get save area address
ST R13,4(,R15) Chain the save areas
ST R15,8(,R13) Chain the save areas
LR R13,R15 Put save area address in R13
L R15,LISQL Get the address of real DSNHLI
BASSM R14,R15 Branch to DSNRLI to do an SQL call
* DSNRLI is in 31-bit mode, so use
* BASSM to assure that the addressing
* mode is preserved.
L R13,4(,R13) Restore R13 (caller's save area addr)
The following example code shows how to issue requests for the RRSAF functions IDENTIFY, SIGNON,
CREATE THREAD, TERMINATE THREAD, and TERMINATE IDENTIFY. This example does not show a task
that waits on the Db2 termination ECB. You can code such a task and use the z/OS WAIT macro to monitor
the ECB. The task that waits on the termination ECB should detach the sample code if the termination
ECB is posted. That task can also wait on the Db2 startup ECB. This example waits on the startup ECB at
its own task level.
112 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
BNE EXIT If CONTROL not 'CONTINUE', shut down
L R15,LIRLI Get the Language Interface address
CALL (15),(TRMTHDFN),VL,MF=(E,RRSAFCLL)
BAL R14,CHEKCODE Check the return and reason codes
************************ TERMINATE IDENTIFY ***************************
CLC CONTROL,CONTINUE Is everything still OK
BNE EXIT If CONTROL not 'CONTINUE', stop loop
L R15,LIRLI Get the Language Interface address
CALL (15),(TMIDFYFN),VL,MF=(E,RRSAFCLL)
BAL R14,CHEKCODE Check the return and reason codes
CAF
DSNALI
DSNHLI2
DSNWLI2
Application program
or stored procedure DSNRLI
RRSAF
DSNULI DSNRLI
DSNHLIR
DSNALI DSNWLIR
DSNELI
DSNRLI
TSO
DSNHLI
DSNHLI2
DSNHLIR DSNWLI
DSNHLI
DSNCLI
CICS
DSNWLI2
DSNWLIR DSNHLI
DSNWLI
DSNWLI
DFSLI000
PLITDLI
DFSPLI IMS
CBLTDLI
DFSCOBOL PLITDLI
ASMTDLI
DFSASM DFSPLI
CBLTDLI
DFSCOBOL
ASMTDLI
DFSASM
The Db2 load module, DSNULI, is the Universal Language Interface module. DSNULI has no aliases.
114 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
instead of with one of the environment-specific language interface modules (DSNELI, DSNALI, DSNRLI,
DSNCLI, or DFSLI000).
Procedure
You can include DSNULI when you link-edit your load module. For example, you can use a linkage editor
control statement like this in your JCL:
INCLUDE SYSLIB(DSNULI)
Results
By coding this statement, you avoid linking to one of the environment-specific language interface
modules.
Procedure
To control the CICS attachment facility:
1. To start the CICS attachment facility, perform one of the following actions:
• Include the following statement in your application:
• Use the system programming interface SET DB2CONN for the CICS Transaction Server.
2. To stop the CICS attachment facility, perform one of the following actions:
• Include the following statement in your application:
• Use the system programming interface SET DB2CONN for the CICS Transaction Server.
Related information
SET DB2CONN (CICS Transaction Server for z/OS)
Procedure
Use the INQUIRE EXITPROGRAM command for the CICS Transaction Server in your application.
The following example shows how to use this command. In this example, the INQUIRE EXITPROGRAM
command tests whether the resource manager for SQL, DSNCSQL, is up and running. CICS returns the
results in the EIBRESP field of the EXEC interface block (EIB) and in the field whose name is the argument
of the CONNECTST parameter (in this case, STST). If the EIBRESP value indicates that the command
completed normally and the STST value indicates that the resource manager is available, you can then
execute SQL statements.
STST DS F
ENTNAME DS CL8
EXITPROG DS CL8
⋮
MVC ENTNAME,=CL8'DSNCSQL'
MVC EXITPROG,=CL8'DSN2EXT1'
EXEC CICS INQUIRE EXITPROGRAM(EXITPROG) X
ENTRYNAME(ENTNAME) CONNECTST(STST) NOHANDLE
CLC EIBRESP,DFHRESP(NORMAL)
BNE NOTREADY
CLC STST,DFHVALUE(CONNECTED)
BNE NOTREADY
UPNREADY DS 0H
attach is up
NOTREADY DS 0H
attach is not up yet
If you use the INQUIRE EXITPROGRAM command to avoid AEY9 abends and the CICS attachment facility
is down, the storm drain effect can occur. The storm drain effect is a condition that occurs when a system
continues to receive work, even though that system is down.
Related concepts
Storm-drain effect (Db2 Installation and Migration)
Related information
INQUIRE EXITPROGRAM (CICS Transaction Server for z/OS)
-923 (Db2 Codes)
116 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Improving thread reuse in CICS applications
Having transactions reuse threads is generally recommended because each thread creation is associated
with a high processor cost.
Procedure
Close all cursors that are declared with the WITH HOLD option before each sync point.
Db2 does not automatically close them. A thread for an application that contains an open cursor cannot
be reused. You should close all cursors immediately after you finish using them.
Related concepts
Held and non-held cursors
A held cursor does not close after a commit operation. A cursor that is not held closes after a commit
operation. You specify whether you want a cursor to be held or not held by including or omitting the WITH
HOLD clause when you declare the cursor.
Procedure
Use a CREATE TABLE statement that includes the following elements:
• The name of the table. See Guidelines for table names (Db2 Administration Guide).
• A list of the columns that make up the table. Separate each column description from the next with a
comma, and enclose the entire list of column descriptions in parentheses.
For each column, specify the following information:
– The name of the column (for example, SERIAL). See Column names (Db2 SQL).
– The data type and length attribute (for example, CHAR(8)). See Data types of columns (Introduction
to Db2 for z/OS).
– Optionally, specify a default value, or a constraint on the value. You can use the following values:
Keyword Result
NOT NULL Specifies the column cannot contain null values
UNIQUE The value for each row must be unique, and the
column cannot contain null values.
DEFAULT The column has one of the following Db2-
assigned default values:
- For numeric columns, 0 (zero) is the default
value.
- For character or graphic fixed-length strings,
blank is the default value.
- For binary fixed-length strings, a set of
hexadecimal zeros is the default value.
- For variable-length strings, including LOB
strings, the empty string (a string of zero-
length) is the default value.
– Optionally, specify the partitioning method for the data in the table. Db2 uses size-based partitions
by default if you do not specify how to partition the data when you create the table. For more
information, see Partitioning data in Db2 tables (Db2 Administration Guide).
– Optionally, a referential constraint or check constraint. For more information, see “Check constraints”
on page 127 and “Referential constraints” on page 128.
Example
For example, the following SQL statement creates a table named PRODUCT:
Related concepts
Db2 tables (Introduction to Db2 for z/OS)
Related tasks
Creating base tables (Db2 Administration Guide)
Related reference
CREATE TABLE (Db2 SQL)
Related information
Lesson 1.2: Creating a table (Introduction to Db2 for z/OS)
120 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
The data type for a column can be a distinct type, which is a user-defined data type, or a Db2 built-in
data type. As shown in the following figure, Db2 built-in data types have four general categories: datetime,
string, numeric, and row identifier (ROWID).
Built-indata types
Related concepts
Assignment and comparison (Db2 SQL)
Casting between data types (Db2 SQL)
Rules for result data types (Db2 SQL)
Distinct types
A distinct type is a user-defined data type that shares its internal representation with a built-in data type
(its source type), but is considered to be a separate and incompatible data type for most operations.
Data types (Db2 SQL)
Procedure
To store LOB data in Db2:
1. Define one or more columns of the appropriate LOB type and optionally a row identifier (ROWID)
column by executing a CREATE TABLE statement or one or more ALTER TABLE statements.
Define only one ROWID column, even if the table is to have multiple LOB columns. If you do not create
a ROWID column before you define a LOB column, Db2 implicitly creates a ROWID column with the
IMPLICITLY HIDDEN attribute and appends it as the last column of the table.
If you add a ROWID column after you add a LOB column, the table has two ROWID columns: the
implicitly-created column and the explicitly-created column. In this case, Db2 ensures that the values
of the two ROWID columns are always identical.
If Db2 implicitly creates the table space for this table or CURRENT RULES is set to STD, Db2 creates
the necessary auxiliary objects for you and you can skip steps 2 and 3.
2. If you explicitly created the table space for this table and the CURRENT RULES special register is not
set to STD, create a LOB table space and auxiliary table by using the CREATE LOB TABLESPACE and
CREATE AUXILIARY TABLE statements.
• If your base table is nonpartitioned, create one LOB table space and for each column create one
auxiliary table.
• If your base table is partitioned, create one LOB table space for each partition and one auxiliary table
for each column. For example, if your base table has three partitions, you must create three LOB
table spaces and three auxiliary tables for each LOB column.
3. If you explicitly created the table space for this table and the CURRENT RULES special register is not
set to STD, create one index for each auxiliary table by using the CREATE INDEX statement.
4. Insert the LOB data into Db2 by using one of the following techniques:
• If the total length of a LOB column and the base table row is less than 32 KB, use the LOAD utility
and specify the base table.
• Otherwise, use INSERT, UPDATE, or MERGE statements and specify the base table. If you use the
INSERT statement, ensure that you application has enough storage available to hold the entire value
that is to be put into the LOB column.
Example
Suppose that you want to add a resume for each employee to the employee table. The employee resumes
are no more than 5 MB in size. Because the employee resumes contain single-byte characters, you can
define the resumes to Db2 as CLOBs. You therefore need to add a column of data type CLOB with a length
of 5 MB to the employee table. If you want to define a ROWID column explicitly, you must define it before
you define the CLOB column.
First, execute an ALTER TABLE statement to add the ROWID column, and then execute another ALTER
TABLE statement to add the CLOB column. The following statements create these columns:
If you explicitly created the table space for this table and the CURRENT RULES special register is not set
to STD, you then need to define a LOB table space and an auxiliary table to hold the employee resumes.
You also need to define an index on the auxiliary table. You must define the LOB table space in the same
database as the associated base table. The following statements create these objects:
122 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
CREATE LOB TABLESPACE RESUMETS
IN DSN8D12A
LOG NO
COMMIT;
CREATE AUXILIARY TABLE EMP_RESUME_TAB
IN DSN8D12A.RESUMETS
STORES DSN8C10.EMP
COLUMN EMP_RESUME;
CREATE UNIQUE INDEX XEMP_RESUME
ON EMP_RESUME_TAB;
COMMIT;
You can then load your employee resumes into Db2. In your application, you can define a host variable
to hold the resume, copy the resume data from a file into the host variable, and then execute an UPDATE
statement to copy the data into Db2. Although the LOB data is stored in the auxiliary table, your UPDATE
statement specifies the name of the base table. The following code declares a host variable to store the
resume in the C language:
In this statement, employeenum is a host variable that identifies the employee who is associated with a
resume.
Related concepts
Large objects (LOBs) (Db2 SQL)
Creation of large objects (Introduction to Db2 for z/OS)
Related reference
CREATE TABLE (Db2 SQL)
CREATE AUXILIARY TABLE (Db2 SQL)
CREATE LOB TABLESPACE (Db2 SQL)
CREATE INDEX (Db2 SQL)
Identity columns
An identity column contains a unique numeric value for each row in the table. Db2 can automatically
generate sequential numeric values for this column as rows are inserted into the table. Thus, identity
columns are ideal for primary key values, such as employee numbers or product numbers.
CREATE TABLE T1
(CHARCOL1 CHAR(1),
IDENTCOL1 SMALLINT GENERATED ALWAYS AS IDENTITY
(START WITH -1,
INCREMENT BY 1,
CYCLE,
MINVALUE -3,
MAXVALUE 3));
Now suppose that you execute the following INSERT statement eight times:
When Db2 generates values for IDENTCOL1, it starts with -1 and increments by 1 until it reaches the
MAXVALUE of 3 on the fifth INSERT. To generate the value for the sixth INSERT, Db2 cycles back to
MINVALUE, which is -3. T1 looks like this after the eight INSERT statements are executed:
CHARCOL1 IDENTCOL1
======== =========
A -1
A 0
A 1
A 2
A 3
A -3
A -2
A -1
The value of IDENTCOL1 for the eighth INSERT repeats the value of IDENTCOL1 for the first INSERT.
Example: START WITH or RESTART WITH values outside the range for cycling
The MINVALUE and MAXVALUE options do not constrain the START WITH value. That is, the START WITH
clause can be used to start the generation of values outside the range that is used for cycles. However, the
next generated value after the specified START WITH value is MNVALUE for an ascending identity column
or MAXVALUE for a descending identity column. The same is true if you alter the identity column and
specify a RESTART WITH value.
124 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Consider T1 from the previous example, and suppose that you alter the table with a statement that
specifies the following keywords.
ALTER TABLE T1
ALTER COLUMN IDENTCOL1 SET GENERATED ALWAYS RESTART WITH 99;
Now suppose that you execute the following INSERT statement three times:
When Db2 generates the IDENTCOL1 value, it starts with 99. However, for the next generated value, Db2
again cycles back to MINVALUE, which is -3. T1 looks like this after the three INSERT statements are
executed:
CHARCOL1 IDENTCOL1
======== =========
A -1
A 0
A 1
A 2
A 3
A -3
A -2
A -1
B 99
B -3
B -2
When you insert a new employee into the EMPLOYEE table, to retrieve the value for the EMPNO column,
you can use the following SELECT from INSERT statement:
EXEC SQL
SELECT EMPNO INTO :hv_empno
FROM FINAL TABLE (INSERT INTO EMPLOYEE (NAME, SALARY, WORKDEPT)
VALUES ('New Employee', 75000.00, 11));
The SELECT statement returns the Db2-generated identity value for the EMPNO column in the host
variable :hv_empno.
EXEC SQL
UPDATE DEPARTMENT
SET MGRNO = :hv_empno
WHERE DEPTNO = 11;
Related concepts
Rules for inserting data into an identity column
An identity column contains a unique numeric value for each row in the table. Whether you can insert data
into an identity column and how that data gets inserted depends on how the column is defined.
Related tasks
Selecting values while inserting data
When you insert rows into a table, you can also select values from the inserted rows at the same time.
Related reference
IDENTITY_VAL_LOCAL (Db2 SQL)
126 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Triggers are a series of actions that are invoked when a table is updated. Triggers are discussed in
“Creating a trigger” on page 149.
Related reference
CHECK-pending status (Db2 Utilities)
Check constraints
A check constraint is a rule that specifies the values that are allowed in one or more columns of every row
of a base table. For example, you can define a check constraint to ensure that all values in a column that
contains ages are positive numbers.
Check constraints designate the values that specific columns of a base table can contain, providing
you a method of controlling the integrity of data entered into tables. You can create tables with check
constraints using the CREATE TABLE statement, or you can add the constraints with the ALTER TABLE
statement. However, if the check integrity is compromised or cannot be guaranteed for a table, the
table space or partition that contains the table is placed in a check pending state. Check integrity is the
condition that exists when each row of a table conforms to the check constraints defined on that table.
For example, you might want to make sure that no salary can be below 15000 dollars. To do this, you can
create the following check constraint:
Using check constraints makes your programming task easier, because you do not need to enforce those
constraints within application programs or with a validation routine. Define check constraints on one or
more columns in a table when that table is created or altered.
The syntax of a check constraint is checked when the constraint is defined, but the meaning of the
constraint is not checked. The following examples show mistakes that are not caught. Column C1 is
defined as INTEGER NOT NULL.
Allowable but mistaken check constraints:
• A self-contradictory check constraint:
A check constraint is not checked for consistency with other types of constraints. For example, a column
in a dependent table can have a referential constraint with a delete rule of SET NULL. You can also define
a check constraint that prohibits nulls in the column. As a result, an attempt to delete a parent row fails,
because setting the dependent row to null violates the check constraint.
Referential constraints
A referential constraint is a rule that specifies that the only valid values for a particular column are those
values that exist in another specified table column. For example, a referential constraint can ensure that
all customer IDs in a transaction table exist in the ID column of a customer table.
A table can serve as the "master list" of all occurrences of an entity. In the sample application, the
employee table serves that purpose for employees; the numbers that appear in that table are the only
valid employee numbers. Likewise, the department table provides a master list of all valid department
numbers; the project activity table provides a master list of activities performed for projects; and so on.
The following figure shows the relationships that exist among the tables in the sample application. Arrows
point from parent tables to dependent tables.
128 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
CASCADE
DEPT
SET SET
NULL NULL
RETRICT EMP
RETRICT
CASCADE ACT
PROJ
RETRICT RETRICT
PROJACT
RETRICT
RETRICT
EMPPROJACT
When a table refers to an entity for which there is a master list, it should identify an occurrence of the
entity that actually appears in the master list; otherwise, either the reference is invalid or the master list is
incomplete. Referential constraints enforce the relationship between a table and a master list.
Alternatively, a delete operation on a self-referencing table must involve the same table, and the delete
rule there must be CASCADE or NO ACTION.
130 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Defining a parent key and unique index
A parent key is either a primary key or a unique key in the parent table of a referential constraint. The
values of a parent key determine the valid values of the foreign key in the constraint. You must create a
unique index on a parent key.
Procedure
Use the PRIMARY KEY clause in an ALTER TABLE statement. In this case, a unique index must already
exist.
Consider the following items when you plan for primary keys:
• The theoretical model of a relational database suggests that every table should have a primary key to
uniquely identify the entities it describes. However, you must weigh that model against the potential
cost of index maintenance overhead. Db2 does not require you to define a primary key for tables with no
dependents.
• Choose a primary key whose values will not change over time. Choosing a primary key with persistent
values enforces the good practice of having unique identifiers that remain the same for the lifetime of
the entity occurrence.
• A primary key column should not have default values unless the primary key is a single TIMESTAMP
column.
• Choose the minimum number of columns to ensure uniqueness of the primary key.
• A view that can be updated that is defined on a table with a primary key should include all columns of
the key. Although this is necessary only if the view is used for inserts, the unique identification of rows
can be useful if the view is used for updates, deletes, or selects.
• Drop a primary key later if you change your database or application using SQL.
Related concepts
Ways to maintain data integrity
When you add or modify data in a Db2 table, you need to ensure that the data is valid. Two techniques
that you can use to ensure valid data are constraints and triggers.
Related reference
ALTER TABLE (Db2 SQL)
Table 35. Part of the project table with the primary key column, PROJNO
PROJNO PROJNAME DEPTNO
MA2100 WELD LINE AUTOMATION D01
MA2110 W L PROGRAMMING D11
Table 36 on page 132 shows part of the project activity table, which has a primary key that contains
more than one column. The primary key is a composite key, which consists of the PRONNO, ACTNO, and
ACSTDATE columns.
Table 36. Part of the Project activities table with a composite primary key
PROJNO ACTNO ACSTAFF ACSTDATE ACENDATE
AD3100 10 .50 1982-01-01 1982-07-01
AD3110 10 1.00 1982-01-01 1983-01-01
AD3111 60 .50 1982-03-15 1982-04-15
132 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Procedure
To define a foreign key, use one of the following approaches:
• Issue a CREATE TABLE statement and specify a FOREIGN KEY clause.
a) Choose a constraint name for the relationship that is defined by a foreign key.
If you do not choose a name, Db2 generates one from the name of the first column of the foreign
key, in the same way that it generates the name of an implicitly created table space.
For example, the names of the relationships in which the employee-to-project activity table is a
dependent would, by default, be recorded (in column RELNAME of SYSIBM.SYSFOREIGNKEYS) as
EMPNO and PROJNO.
The name is used in error messages, queries to the catalog, and DROP FOREIGN KEY statements.
Hence, you might want to choose one if you are experimenting with your database design and have
more than one foreign key that begins with the same column (otherwise Db2 generates the name).
b) Specify column names that identify the columns of the parent key.
A foreign key can refer to either a unique or a primary key of the parent table. If the foreign key
refers to a non-primary unique key, you must specify the column names of the key explicitly. If the
column names of the key are not specified explicitly, the default is to refer to the column names of
the primary key of the parent table.
• Issue an ALTER TABLE statement and specify the FOREIGN KEY clause.
You can add a foreign key to an existing table; in fact, that is sometimes the only way to proceed. To
make a table self-referencing, you must add a foreign key after creating it. When a foreign key is added
to a populated table, the table space is put into CHECK-pending status.
Example
The following example shows a CREATE TABLE statement that specifies constraint names REPAPA and
REPAE for the foreign keys in the employee-to-project activity table.
What to do next
If rows of the parent table are often deleted, it is best to create an index on the foreign key.
Related tasks
Adding parent keys and foreign keys (Db2 Administration Guide)
Related reference
CREATE TABLE (Db2 SQL)
ALTER TABLE (Db2 SQL)
SYSFOREIGNKEYS catalog table (Db2 SQL)
Creating work tables for the EMP and DEPT sample tables
Before testing SQL statements that insert, update, and delete rows in the DSN8C10.EMP and
DSN8C10.DEPT sample tables, you should create duplicates of these tables. Create duplicates so that
the original sample tables remain intact. These duplicate tables are called work tables.
If you want DEPTNO to be a primary key, as in the sample table, explicitly define the key. Use an ALTER
TABLE statement, as in the following example:
You can use an INSERT statement to copy the rows of the result table of a fullselect from one table to
another. The following statement copies all of the rows from DSN8C10.DEPT to your own YDEPT work
table:
For information about using the INSERT statement, see “Inserting rows by using the INSERT statement”
on page 331.
You can use the following statements to create a new employee table called YEMP:
134 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
HIREDATE DATE ,
JOB CHAR(8) ,
EDLEVEL SMALLINT ,
SEX CHAR(1) ,
BIRTHDATE DATE ,
SALARY DECIMAL(9, 2) ,
BONUS DECIMAL(9, 2) ,
COMM DECIMAL(9, 2) );
This statement also creates a referential constraint between the foreign key in YEMP (WORKDEPT) and
the primary key in YDEPT (DEPTNO). It also restricts all phone numbers to unique numbers.
If you want to change a table definition after you create it, use the ALTER TABLE statement with a
RENAME clause. If you want to change a table name after you create it, use the RENAME statement.
You can change a table definition by using the ALTER TABLE statement only in certain ways. For example,
you can add and drop constraints on columns in a table. You can also change the data type of a column
within character data types, within numeric data types, and within graphic data types. You can add a
column to a table. However, you cannot use the ALTER TABLE statement to drop a column from a table.
Related tasks
Altering Db2 tables (Db2 Administration Guide)
Related reference
ALTER TABLE (Db2 SQL)
RENAME (Db2 SQL)
Procedure
To create a created temporary table:
1. Define the table by issuing CREATE GLOBAL TEMPORARY TABLE statement.
For example, the following statement creates the definition of a table called TEMPPROD:
You can also create this same definition by copying the definition of a base table (named PROD) by
using the LIKE clause:
Restriction: You cannot use the MERGE statement with created temporary tables.
The SQL statements in the examples create identical definitions for the TEMPPROD table, but these
tables differ slightly from the PROD sample table PROD. The PROD sample table contains two
columns, DESCRIPTION and CURDATE, that are defined as NOT NULL WITH DEFAULT. Because
created temporary tables do not support non-null default values, the DESCRIPTION and CURDATE
columns in the TEMPPROD table are defined as NOT NULL and do not have defaults.
After you run one of the two CREATE statements, the definition of TEMPPROD exists, but no instances
of the table exist.
2. Create an instance of the created temporary table by using it in an application.
Db2 creates an instance of the table when it is specified in one of the following SQL statements:
• OPEN
• SELECT
• INSERT
• DELETE
For example, suppose that you defined TEMPROD as described the previous step and then run an
application that contains the following statements:
When you run the INSERT statement, Db2 creates an instance of TEMPPROD and populates that
instance with rows from table PROD. When the COMMIT statement runs, Db2 deletes all rows
from TEMPPROD. However, assume that you change the declaration of cursor C1 to the following
declaration:
In this case, Db2 does not delete the contents of TEMPPROD until the application ends because C1, a
cursor that is defined with the WITH HOLD clause, is open when the COMMIT statement runs. In either
case, Db2 drops the instance of TEMPPROD when the application ends.
3. When the table is no longer needed, issue a DROP statement .
For example, to drop the definition of TEMPPROD, you must run the following statement:
Related reference
CREATE GLOBAL TEMPORARY TABLE (Db2 SQL)
DROP (Db2 SQL)
136 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Temporary tables
Use temporary tables when you need to store data for only the duration of an application process.
Depending on whether you want to share the table definition, you can create a created temporary table or
a declared temporary table.
The two kinds of temporary tables are:
• Created temporary tables, which you define using a CREATE GLOBAL TEMPORARY TABLE statement
• Declared temporary tables, which you define using a DECLARE GLOBAL TEMPORARY TABLE statement
SQL statements that use temporary tables can run faster because of the following reasons:
• For created temporary tables, Db2 provides no logging. For declared temporary tables, Db2 provides
limited logging that can be further limited by the NOT LOGGED option of the DECLARE GLOBAL
TEMPORARY TABLE statement.
• For created temporary tables, Db2 provides no locking. For declared temporary tables, Db2 provides
limited locking.
Temporary tables are especially useful when you need to sort or query intermediate result tables that
contain a large number of rows, but you want to store only a small subset of those rows permanently.
Temporary tables can also return result sets from stored procedures. The following topics provide more
details about created temporary tables and declared temporary tables:
• “Creating created temporary tables” on page 135
• “Creating declared temporary tables” on page 137
For more information, see “Writing an external procedure to return result sets to a distributed client” on
page 274.
Procedure
To create a declared temporary table:
1. Issue a DECLARE GLOBAL TEMPORARY TABLE statement.
In that statement, you an specify the columns that the table is to contain by performing one of the
following actions:
Unlike columns of created temporary tables, columns of declared temporary tables can include the
WITH DEFAULT clause.
• Use a LIKE clause to copy the definition of a base table, created temporary table, or view. For
example, the following statement defines a declared temporary table called TEMPPROD by copying
the definition of a base table. The base table has an identity column that the declared temporary
table also uses as an identity column.
• If the base table, created temporary table, or view from which you select columns has identity
columns, you can specify that the corresponding columns in the declared temporary table are also
identity columns. To include these identity columns, specify the INCLUDING IDENTITY COLUMN
ATTRIBUTES clause when you define the declared temporary table.
If the source table has a row change timestamp column, you can specify that those column
attributes are inherited in the declared temporary table by specifying INCLUDING ROW CHANGE
TIMESTAMP COLUMN ATTRIBUTES.
• Use a fullselect to choose specific columns from a base table, created temporary table, or view.
For example, the following statement defines a declared temporary table called TEMPPROD by
selecting columns from a view. The view has an identity column that the declared temporary table
also uses as an identity column. The declared temporary table inherits its default column values
from the default column values of a base table on which the view is based.
If you want the declared temporary table columns to inherit the defaults for columns of the table or
view that is named in the fullselect, specify the INCLUDING COLUMN DEFAULTS clause. If you want
the declared temporary table columns to have default values that correspond to their data types,
specify the USING TYPE DEFAULTS clause.
Db2 creates an empty instance of a declared temporary table.
2. Complete one of the following actions:
• Populate the declared temporary table by using INSERT statements.
• Modify the table using searched or positioned UPDATE or DELETE statements.
• Query the table using SELECT statements.
• Create indexes on the declared temporary table. Creating such an index that specifies a buffer pool
or storage group that is different than the default index buffer pool or default storage group of the
work file database, requires additional USE authorization privileges for the buffer pool or storage
group.
3. After you run a DECLARE GLOBAL TEMPORARY TABLE statement, the definition of the declared
temporary table exists as long as the application process runs. If you need to delete the definition
before the application process completes, issue a DROP TABLE statement.
For example, to drop the definition of TEMPPROD, run the following statement:
138 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
DROP TABLE SESSION.TEMPPROD;
Example
The ON COMMIT clause that you specify in the DECLARE GLOBAL TEMPORARY TABLE statement
determines whether Db2 keeps or deletes all the rows from the table when you run a COMMIT statement
in an application with a declared temporary table. ON COMMIT DELETE ROWS, which is the default,
causes all rows to be deleted from the table at a commit point, unless a held cursor is open on the table at
the commit point. ON COMMIT PRESERVE ROWS causes the rows to remain past the commit point.
For example Suppose that you run the following statement in an application program:
When Db2 runs the preceding DECLARE GLOBAL TEMPORARY TABLE statement, Db2 creates an empty
instance of TEMPPROD. The INSERT statement populates that instance with rows from table BASEPROD.
The qualifier, SESSION, must be specified in any statement that references TEMPPROD. When Db2
executes the COMMIT statement, Db2 keeps all rows in TEMPPROD because TEMPPROD is defined with
ON COMMIT PRESERVE ROWS. When the program ends, Db2 drops TEMPPROD.
Related reference
DECLARE GLOBAL TEMPORARY TABLE (Db2 SQL)
Procedure
To complete the definition of a table, use one of the following actions:
• Create a primary index or alter the table to drop the primary key.
• Create a unique index on the unique key or alter the table to drop the unique key.
• Defining a unique index on the ROWID column.
• Create the necessary LOB objects.
Example
To create the primary index for the project activity table, issue the following SQL statement:
140 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Dropping tables
When you drop a table, you delete the data and the table definition. You also delete all synonyms, views,
indexes, referential constraints, and check constraints that are associated with that table.
Use the DROP TABLE statement with care: Dropping a table is not equivalent to deleting all its rows.
When you drop a table, you lose more than its data and its definition. You lose all synonyms, views,
indexes, and referential and check constraints that are associated with that table. You also lose all
authorities that are granted on the table.
Related reference
DROP (Db2 SQL)
Defining a view
A view is a named specification of a result table. Use views to control which users have access to certain
data or to simplify writing SQL statements.
When a program accesses the data that is defined by a view, Db2 uses the view definition to return a set
of rows that the program can access with SQL statements.
To see the departments that are administered by department D01 and the managers of those
departments, run the following statement, which returns information from the VDEPTM view:
When you create a view, you can reference the SESSION_USER and CURRENT SQLID special registers
in the CREATE VIEW statement. When referencing the view, Db2 uses the value of the SESSION_USER
or CURRENT SQLID special register that belongs to the user of the SQL statement (SELECT, UPDATE,
INSERT, or DELETE) rather than the creator of the view. In other words, a reference to a special register in
a view definition refers to its run time value.
You can specify a period specification for a view, subject to certain restrictions. Also, for a view that
references an application-period temporal table or a bitemporal table, you can specify a period clause for
an update or delete operation on the view.
A column in a view might be based on a column in a base table that is an identity column. The column in
the view is also an identity column,except under any of the following circumstances:
• The column appears more than once in the view.
• The view is based on a join of two or more tables.
• The view is based on the union of two or more tables.
• Any column in the view is derived from an expression that refers to an identity column.
Views
A view does not contain data; it is a stored definition of a set of rows and columns. A view can present any
or all of the data in one or more tables.
Although you cannot modify an existing view, you can drop it and create a new one if your base tables
change in a way that affects the view. Dropping and creating views does not affect the base tables or their
data.
142 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
For complex views, you can make insert, update and delete operations possible by defining INSTEAD OF
triggers.
Related tasks
Inserting, updating, and deleting data in views by using INSTEAD OF triggers
INSTEAD OF triggers are triggers that execute instead of the INSERT, UPDATE, or DELETE statement that
activates the trigger. You can define these triggers on views only. Use INSTEAD OF triggers to insert,
update, and delete data in complex views.
Changing data by using views that reference temporal tables (Db2 Administration Guide)
Related reference
CREATE VIEW (Db2 SQL)
Dropping a view
When you drop a view, you also drop all views that are defined on that view. The base table is not
affected.
Example
The following SQL statement drops the VDEPTM view:
Procedure
To created a common table expression use one of the following approaches:
• Specify a WITH clause at the beginning of a SELECT statement.
For example, the following statement finds the department with the highest total pay. The query
involves two levels of aggregation. First, you need to determine the total pay for each department by
using the SUM function and order the results by using the GROUP BY clause. You then need to find the
department with highest total pay based on the total pay for each department.
The result table for the common table expression, DTOTAL, contains the department number and total
pay for each department in the employee table. The fullselect in the previous example uses the result
table for DTOTAL to find the department with the highest total pay. The result table for the entire
statement looks similar to the following results:
WORKDEPT
======
D11
• Use common table expressions by specifying WITH before a fullselect in a CREATE VIEW statement.
The fullselect in the previous example uses the result table for DTOTAL to find the departments that
have a greater-than-average total pay. The result table is saved as the RICH_DEPT view and looks
similar to the following results:
WORKDEPT
======
A00
D11
D21
• Use common table expressions by specifying WITH before a fullselect in an INSERT statement.
For example, the following statement uses the result table for VITALDEPT to find the manager's
number for each department that has a greater-than-average number of senior engineers. Each
manager's number is then inserted into the vital_mgr table.
Related reference
common-table-expression (Db2 SQL)
144 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Related reference
common-table-expression (Db2 SQL)
Assume that the PARTLIST table is populated with the values that are in the following table:
The preceding query includes a common table expression, identified by the name RPL, that expresses the
recursive part of this query. It illustrates the basic elements of a recursive common table expression.
The first operand (fullselect) of the UNION, referred to as the initialization fullselect, gets the direct
subparts of part '01'. The FROM clause of this fullselect refers to the source table and will never refer to
itself (RPL in this case). The result of this first fullselect goes into the common table expression RPL. As in
this example, the UNION must always be a UNION ALL.
The second operand (fullselect) of the UNION uses RPL to compute subparts of subparts by using the
FROM clause to refer to the common table expression RPL and the source table PARTLIST with a join of a
part from the source table (child) to a subpart of the current result contained in RPL (parent). The result
goes then back to RPL again. The second operand of UNION is used repeatedly until no more subparts
exist.
The SELECT DISTINCT in the main fullselect of this query ensures the same part/subpart is not listed
more than once.
The result of the query is shown in the following table:
Observe in the result that part '01' contains subpart '02' which contains subpart '06' and so on. Further,
notice that part '06' is reached twice, once through part '01' directly and another time through part '02'.
In the output, however, the subparts of part '06' are listed only once (this is the result of using a SELECT
DISTINCT).
146 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Remember that with recursive common table expressions it is possible to introduce an infinite loop. In
this example, an infinite loop would be created if the search condition of the second operand that joins
the parent and child tables was coded as follows:
This infinite loop is created by not coding what is intended. You should carefully determining what to code
so that there is a definite end of the recursion cycle.
The result produced by this example could be produced in an application program without using a
recursive common table expression. However, such an application would require coding a different query
for every level of recursion. Furthermore, the application would need to put all of the results back in the
database to order the final result. This approach complicates the application logic and does not perform
well. The application logic becomes more difficult and inefficient for other bill of material queries, such as
summarized and indented explosion queries.
In the preceding query, the select list of the second operand of the UNION in the recursive common table
expression, identified by the name RPL, shows the aggregation of the quantity. To determine how many
of each subpart is used, the quantity of the parent is multiplied by the quantity per parent of a child. If
a part is used multiple times in different places, it requires another final aggregation. This is done by the
grouping the parts and subparts in the common table expression RPL and using the SUM column function
in the select list of the main fullselect.
The result of the query is shown in the following table:
Consider the total quantity for subpart '06'. The value of 15 is derived from a quantity of 3 directly for part
'01' and a quantity of 6 for part '02' which is needed two times by part '01'.
This query is similar to the query in example 1. The column LEVEL is introduced to count the level each
subpart is from the original part. In the initialization fullselect, the value for the LEVEL column is initialized
to 1. In the subsequent fullselect, the level from the parent table increments by 1. To control the number
of levels in the result, the second fullselect includes the condition that the level of the parent must be less
than 2. This ensures that the second fullselect only processes children to the second level.
The result of the query is shown in the following table:
148 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 40. Result table for example 3 (continued)
PART LEVEL SUBPART QUANTITY
06 2 13 10
Creating a trigger
A trigger is a set of SQL statements that execute when a certain event occurs in a table or view. Use
triggers to control changes in Db2 databases. Triggers are more powerful than constraints because they
can monitor a broader range of changes and perform a broader range of actions. This topic describes
support for advanced triggers.
1
CREATE TRIGGER REORDER
2 3 4
AFTER UPDATE OF ON_HAND, MAX_STOCKED ON PARTS
5
REFERENCING NEW AS N_ROW
6
FOR EACH ROW
7
WHEN (N_ROW.ON_HAND < 0.10 * N_ROW.MAX_STOCKED)
8
BEGIN ATOMIC
CALL ISSUE_SHIP_REQUEST(N_ROW.MAX_STOCKED -
N_ROW.ON_HAND,
N_ROW.PARTNO);
END
Executing this statement drops trigger REORDER and its associated trigger package named REORDER.
If you drop table PARTS, Db2 also drops trigger REORDER and its trigger package.
Parts of a trigger:
A trigger contains the following parts:
• trigger name
• subject table
• trigger activation time
• triggering event
• granularity
• correlation names for transition variables and transition tables
• triggered action that consists of an optional search condition and a trigger body
Trigger name:
Specify a name for your trigger. You can use a qualifier or let Db2 determine the qualifier. When Db2
creates a trigger package for the trigger, it uses the same qualifier as the collection ID of the trigger
package.
Subject table or view:
When you perform an insert, update, or delete operation on this table or view, the trigger is activated.
You must name a local table or view in the CREATE TRIGGER statement. You cannot define a trigger on a
catalog table.
Trigger activation time:
The choices for trigger activation time are BEFORE, AFTER, and INSTEAD OF. BEFORE and AFTER triggers
can be defined for a table. INSTEAD OF triggers can be defined for a view.
BEFORE means that the trigger is activated before Db2 makes any changes to the subject table, and that
the triggered action does not activate any other triggers. AFTER means that the trigger is activated after
Db2 makes changes to the subject table and can activate other triggers. INSTEAD OF means that the
trigger is activated when there is an attempt to change the subject view. Triggers with an activation time
of BEFORE are known as before triggers. Triggers with an activation time of AFTER are known as after
triggers. Triggers with an activation time of INSTEAD OF are known as instead of triggers.
150 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Triggering event:
Every trigger is associated with an event. A trigger is activated when the triggering event occurs in the
subject table or view. The triggering event is one of the following SQL operations:
• insert
• update
• delete
A triggering event can also be an update or delete operation that occurs as the result of a referential
constraint with ON DELETE SET NULL or ON DELETE CASCADE.
A trigger can be activated by a MERGE statement for delete, insert, and update operations.
Triggers are not activated as the result of updates made to tables by Db2 utilities, with the exception of
the LOAD utility when it is specified with the RESUME YES and SHRLEVEL CHANGE options.
When the triggering event for a trigger is an update operation, the trigger is called an update trigger.
Similarly, triggers for insert operations are called insert triggers, and triggers for delete operations are
called delete triggers.
The SQL statement that performs the triggering SQL operation is called the triggering SQL statement.
Each triggering event is associated with one subject table or view and one SQL operation.
The following trigger is defined with an insert triggering event:
If the triggering SQL operation is an update operation, the event can be associated with specific columns
of the subject table. In this case, the trigger is activated only if the update operation updates any of the
specified columns.
The following trigger, PAYROLL1, which invokes user-defined function named PAYROLL_LOG, is activated
only if an update operation is performed on the SALARY or BONUS column of table PAYROLL:
Granularity:
The triggering SQL statement might modify multiple rows in the table. The granularity of the trigger
determines whether the trigger is activated only once for the triggering SQL statement or once for every
row that the SQL statement modifies. The granularity values are:
• FOR EACH ROW
The trigger is activated once for each row that Db2 modifies in the subject table or view. If the triggering
SQL statement modifies no rows, the trigger is not activated. However, if the triggering SQL statement
updates a value in a row to the same value, the trigger is activated. For example, if an UPDATE trigger is
defined on table COMPANY_STATS, the following SQL statement will activate the trigger.
Trigger NEW_HIRE is activated once for every row inserted into the employee table.
Transition variables:
When you code a row trigger, you might need to refer to the values of columns in each updated row of the
subject table or view. To do this, specify a correlation name (to use when referencing transition variables)
in the REFERENCING clause of your CREATE TRIGGER statement. The two types of transition variables
are:
• Old transition variables capture the values of columns before the triggering SQL statement updates
them. You can use the REFERENCING OLD clause to define a correlation name for referencing old
transition variables for update and delete triggers.
• New transition variables capture the values of columns after the triggering SQL statement updates
them. You can use the REFERENCING NEW clause to define a correlation name for referencing new
transition variables for update and insert triggers.
Transition variables can be referenced anywhere in an SQL statement where an expression or variable can
be specified in triggers. See References to SQL parameters and variables (Db2 SQL) for more information.
The following example uses transition variables and invocations of the IDENTITY_VAL_LOCAL function to
access values that are assigned to identity columns.
Suppose that you have created tables T and S, with the following definitions:
CREATE TABLE T
(ID SMALLINT GENERATED BY DEFAULT AS IDENTITY (START WITH 100),
C2 SMALLINT,
C3 SMALLINT,
C4 SMALLINT);
CREATE TABLE S
(ID SMALLINT GENERATED ALWAYS AS IDENTITY,
C1 SMALLINT);
Define a before insert trigger on T that uses the IDENTITY_VAL_LOCAL built-in function to retrieve the
current value of identity column ID, and uses transition variables to update the other columns of T with
the identity column value.
This statement inserts a row into S with a value of 5 for column C1 and a value of 1 for identity column ID.
Next, suppose that you execute the following SQL statement, which activates trigger TR1:
152 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
INSERT INTO T (C2)
VALUES (IDENTITY_VAL_LOCAL());
This insert statement, and the subsequent activation of trigger TR1, have the following results:
• The INSERT statement obtains the most recent value that was assigned to an identity column (1), and
inserts that value into column C2 of table T. 1 is the value that Db2 inserted into identity column ID of
table S.
• When the INSERT statement executes, Db2 inserts the value 100 into identity column ID column of C2.
• The first statement in the body of trigger TR1 inserts the value of transition variable N.ID (100) into
column C3. N.ID is the value that identity column ID contains after the INSERT statement executes.
• The second statement in the body of trigger TR1 inserts the null value into column C4. By definition, the
result of the IDENTITY_VAL_LOCAL function in the triggered action of a before insert trigger is the null
value.
• The third statement in the body of trigger TR1 inserts 10 times the value of transition variable N.C2
(10*1) into identity column ID of table T. N.C2 is the value that column C2 contains after the INSERT is
executed.
• The fourth statement in the body of trigger TR1 inserts the null value into column C2. By definition, the
result of the IDENTITY_VAL_LOCAL function in the triggered action of a before insert trigger is the null
value.
Transition tables:
If you want to refer to the entire set of rows that a triggering SQL statement modifies, rather than
to individual rows, use a transition table. Like transition variables, a correlation name (to refer to the
columns of the transition table) can appear in the REFERENCING clause of a CREATE TRIGGER statement.
The names for those columns are the same as the name of the column in the table or view that the trigger
is defined for. Transition tables are valid for both row triggers and statement triggers. The two types of
transition tables are:
• Old transition tables, specified with the OLD TABLE transition-table-name clause, capture the values
of columns before the triggering SQL statement updates them. You can define old transition tables for
update and delete triggers.
• New transition tables, specified with the NEW TABLE transition-table-name clause, capture the values
of columns after the triggering SQL statement updates them. You can define new transition variables for
update and insert triggers.
The scope of old and new transition table names is the trigger body. If correlation names are specified for
both old and new transition variables in the trigger, a reference to a transition variable must be qualified
with the associated correlation name. The name of a transition variable can also be the same as the name
of an SQL variable or global variable, or the name of a column in a table or view that is referenced in
the trigger. Names that are the same should be explicitly qualified. Qualifying a name can clarify whether
the name refers to a column, global variable, SQL variable, SQL parameter, or transition variable. To avoid
ambiguity, qualify a transition variable with the correlation name specified in the REFERENCING clause in
the CREATE TRIGGER or ALTER TRIGGER statement that defined the trigger.
The following example accesses a new transition table to capture the set of rows that are inserted into the
INVOICE table:
The SELECT statement in LRG_ORDER causes user-defined function LARGE_ORDER_ALERT to execute for
each row in transition table N_TABLE that satisfies the WHERE clause (TOTAL_PRICE > 10000).
Trigger body:
In the trigger body, you code the SQL statements that you want to execute whenever the trigger condition
is true. The trigger body can include a single SQL-control-statement, including a compound statement, or
triggered-SQL-statement that is to be executed for the triggered-action. The statements that you can use
in a trigger body depend on the activation time of the trigger. See CREATE TRIGGER (advanced) (Db2 SQL)
and SQL procedural language (SQL PL) (Db2 SQL) for more information about defining SQL triggers. Use
control statements to develop triggers that contain logic.
Because you can include INSERT, DELETE, UPDATE, and MERGE statements in your trigger body,
execution of the trigger body might cause activation of other triggers. See “Trigger cascading” on page
160 for more information.
Examples
Example 1
Define a trigger to increment the count of employees when a new employee is hired. The following
example also explains how to determine why an SQL statement is allowed in the trigger.
The UPDATE statement ( 1 ) is an SQL statement that is allowed because it is listed in the syntax
diagram for triggered-SQL-statement.
Example 2
Define a trigger to return an error condition and back out any changes that are made by the trigger, as
well as actions that result from referential constraints on the subject table. Use the SIGNAL statement
to indicate the error information to be returned. When Db2 executes the SIGNAL statement, it returns
154 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
an SQLCA to the application with SQLCODE -438. The SQLCA also includes the following values, which
you supply in the SIGNAL statement:
• A 5-character value that Db2 uses as the SQLSTATE
• An error message that Db2 places in the SQLERRMC field
In the following example, the SIGNAL statement causes Db2 to return an SQLCA with SQLSTATE
75001 and terminate the salary update operation if an employee's salary increase is over 20%:
Example 3
Define a trigger to assign the current date to the HIRE_DATE column when a row is inserted into
the EMP table. Because before triggers operate on rows of a table before those rows are modified,
you cannot perform operations in the body of a before trigger that directly modify the subject
table. You can, however, use the SET assignment-statement statement to modify the values in a
row before those values go into the table. For example, this trigger uses a new transition variable
(NEW_VAR.HIRE_DATE) to assign today's date for the new employee's hire date:
Example 4
In the following example, table CLASS_SCHED contains a row for the class schedule of each class at a
school. When a class schedule row is added to the table, trigger VALIDATE_SCHED is activated. In the
trigger, SQL control statements are used to check for and respond to the following errors in the class
start and end times:
Procedure
To invoke a stored procedure or user-defined function from a trigger:
1. Ensure that the stored procedure or user-defined function is defined before the trigger is defined.
• Define procedures by using the CREATE PROCEDURE statement.
• Define triggers by using the CREATE FUNCTION statement.
2. Invoke the user-defined function or stored procedure by performing one of the following actions:
• To invoke a user-defined function, include the user-defined function in one of the following
statements in the trigger:
SELECT statement
Use a SELECT statement to execute the function conditionally. The number of times that the
user-defined function executes depends on the number of rows in the result table of the SELECT
statement. For example, in the following trigger, the SELECT statement invokes user-defined
function LARGE_ORDER_ALERT. This function executes once for each row in transition table
N_TABLE with an order price of more than 10000:
VALUES statement
Use the VALUES statement to execute a function unconditionally. The function executes once
for each execution of a statement trigger or once for each row in a row trigger. In the following
example, user-defined function PAYROLL_LOG executes every time the trigger PAYROLL1 is
activated. This trigger is activated when an update operation occurs.
156 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
FOR EACH STATEMENT MODE DB2SQL
BEGIN ATOMIC
VALUES(PAYROLL_LOG(USER, 'UPDATE',
CURRENT TIME, CURRENT DATE));
END
]
• To invoke a stored procedure, include a CALL statement in the trigger. The parameters of this stored
procedure call must be constants, transition variables, table locators, or expressions.
If the parameter is a transition variable or table locator, and the CALL statement is in a BEFORE or
AFTER trigger, Db2 returns a warning.
3. To pass transition tables from the trigger to the user-defined function or stored procedure, use table
locators.
When you call a user-defined function or stored procedure from a trigger, you might want to give the
function or procedure access to the entire set of modified rows. In this case, use table locators to pass
a pointer to the old or new transition table.
Most of the code for using a table locator is in the function or stored procedure that receives the
locator.
To pass the transition table from a trigger, specify the parameter TABLE transition-table-name when
you invoke the function or stored procedure. This parameter causes Db2 to pass a table locator for
the transition table to the user-defined function or stored procedure. For example, the following trigger
passes a table locator for a transition table NEWEMPS to stored procedure CHECKEMP:
Related concepts
Steps to creating and using a user-defined function
A user-defined function is similar to a host language subprogram or function. However, a user-defined
function is often the better choice for an SQL application because you can invoke it in an SQL statement.
Related tasks
Accessing transition tables in a user-defined function or stored procedure
If you want to refer to the entire set of rows that a triggering SQL statement modifies, rather than to
individual rows, use a transition table. You can reference a transition table in user-defined functions and
procedures that are invoked from a trigger.
Creating stored procedures
A stored procedure is executable code that can be called by other programs. The process for creating one
depends on the type of procedure.
Creating a user-defined function
You can extend the SQL functionality of Db2 by adding your own or third party vendor function definitions.
Related reference
CALL (Db2 SQL)
CREATE FUNCTION (Db2 SQL)
CREATE PROCEDURE (Db2 SQL)
select-statement (Db2 SQL)
VALUES (Db2 SQL)
Procedure
To insert, update, or delete data in a view by using INSTEAD OF triggers:
1. Define one or more INSTEAD OF triggers on the view by using a CREATE TRIGGER statement.
You can create one trigger for each of the following operations: INSERT, UPDATE, and DELETE. These
triggers define the action that Db2 is to take for each of these operations.
2. Submit a INSERT, UPDATE, or DELETE statement on the view.
Db2 executes the appropriate INSTEAD OF trigger.
Example
Suppose that you create the following view on the sample tables DSN8C10.EMP and DSN8C10.DEPT:
Suppose that you also define the following three INSTEAD OF triggers:
158 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Because the view is on a query with an inner join, the view is read only. However, the INSTEAD OF triggers
makes insert, update, and delete operations possible.
The following table describes what happens for various insert, update, and delete operations on the EMPV
view.
Related reference
CREATE TRIGGER (basic) (Db2 SQL)
Trigger packages
A trigger package is a special type of package that is created only when you execute a CREATE TRIGGER
statement. A trigger package executes only when the associated trigger is activated.
As with any other package, Db2 marks a trigger package invalid when you drop a table, index, or view
on which the trigger package depends. Db2 executes an automatic rebind the next time the trigger is
activated. However, if the automatic rebind fails, Db2 does not mark the trigger package as inoperative.
Trigger cascading
When a trigger performs an SQL operation, it might modify the subject table or other tables with triggers,
therefore Db2 also activates those triggers. This situation is called trigger cascading.
A trigger that is activated as the result of another trigger can be activated at the same level as the original
trigger or at a different level. Two triggers, A and B, are activated at different levels if trigger B is activated
after trigger A is activated and completes before trigger A completes. If trigger B is activated after trigger
A is activated and completes after trigger A completes, then the triggers are at the same level.
For example, in these cases, trigger A and trigger B are activated at the same level:
• Table X has two triggers that are defined on it, A and B. A is a before trigger and B is an after trigger. An
update to table X causes both trigger A and trigger B to activate.
• Trigger A updates table X, which has a referential constraint with table Y, which has trigger B defined on
it. The referential constraint causes table Y to be updated, which activates trigger B.
In these cases, trigger A and trigger B are activated at different levels:
• Trigger A is defined on table X, and trigger B is defined on table Y. Trigger B is an update trigger. An
update to table X activates trigger A, which contains an UPDATE statement on table Y in its trigger body.
This UPDATE statement activates trigger B.
• Trigger A calls a stored procedure. The stored procedure contains an INSERT statement for table X,
which has insert trigger B defined on it. When the INSERT statement on table X executes, trigger B is
activated.
When triggers are activated at different levels, it is called trigger cascading. Trigger cascading can occur
only for after triggers because Db2 does not support cascading of before triggers.
To prevent the possibility of endless trigger cascading, Db2 supports only 16 levels of cascading of
triggers, stored procedures, and user-defined functions. If a trigger, user-defined function, or stored
procedure at the 17th level is activated, Db2 returns SQLCODE -724 and backs out all SQL changes in the
16 levels of cascading. However, as with any other SQL error that occurs during trigger execution, if any
action occurs that is outside the control of Db2, that action is not backed out.
You can write a monitor program that issues IFI READS requests to collect Db2 trace information about
the levels of cascading of triggers, user-defined functions, and stored procedures in your programs.
Related tasks
Invoking IFI from a monitor program (Db2 Performance)
160 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Activation order of multiple triggers
You can create multiple triggers for the same subject table, event, and activation time. The order in which
those triggers are activated is the order in which the triggers were created.
Db2 records the timestamp when each CREATE TRIGGER statement executes. When an event occurs in a
table that activates more than one trigger, Db2 uses the stored timestamps to determine which trigger to
activate first.
Db2 always activates all before triggers that are defined on a table before the after triggers that are
defined on that table, but within the set of before triggers, the activation order is by timestamp, and within
the set of after triggers, the activation order is by timestamp.
In this example, triggers NEWHIRE1 and NEWHIRE2 have the same triggering event (INSERT), the same
subject table (EMP), and the same activation time (AFTER). Suppose that the CREATE TRIGGER statement
for NEWHIRE1 is run before the CREATE TRIGGER statement for NEWHIRE2:
When an insert operation occurs on table EMP, Db2 activates NEWHIRE1 first because NEWHIRE1 was
created first. Now suppose that someone drops and re-creates NEWHIRE1. NEWHIRE1 now has a later
timestamp than NEWHIRE2, so the next time an insert operation occurs on EMP, NEWHIRE2 is activated
before NEWHIRE1.
If two row triggers are defined for the same action, the trigger that was created earlier is activated
first for all affected rows. Then the second trigger is activated for all affected rows. In the previous
example, suppose that an INSERT statement with a fullselect inserts 10 rows into table EMP. NEWHIRE1
is activated for all 10 rows, then NEWHIRE2 is activated for all 10 rows.
Related reference
CREATE TRIGGER (advanced) (Db2 SQL)
CREATE TRIGGER (basic) (Db2 SQL)
Also suppose that an SQL statement deletes the row with department number E21 from DEPT. Because
of the constraint, Db2 finds the rows in EMP with a WORKDEPT value of E21 and sets WORKDEPT in
those rows to null. This is equivalent to an update operation on EMP, which has update trigger EMPRAISE.
Therefore, because EMPRAISE is an after trigger, EMPRAISE is activated after the constraint action sets
WORKDEPT values to null.
162 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Interactions between triggers and tables that have multilevel security with
row-level granularity
A BEFORE trigger affects the value of the transition variable that is associated with a security label
column.
If a subject table has a security label column, the column in the transition table or transition variable that
corresponds to the security label column in the subject table does not inherit the security label attribute.
This means that the multilevel security check with row-level granularity is not enforced for the transition
table or the transition variable. If you add a security label column to a subject table using the ALTER
TABLE statement, the rules are the same as when you add any column to a subject table because the
column in the transition table or the transition variable that corresponds to the security label column does
not inherit the security label attribute.
If the ID you are using does not have write-down privilege and you execute an insert or update operation,
the security label value of your ID is assigned to the security label column for the rows that you are
inserting or updating.
When a BEFORE trigger is activated, the value of the transition variable that corresponds to the security
label column is the security label of the ID if either of the following conditions is true:
• The user does not have write-down privilege
• The value for the security label column is not specified
If the user does not have write-down privilege, and the trigger changes the transition variable that
corresponds to the security label column, the value of the security label column is changed back to the
security label value of the user before the row is written to the page.
Related concepts
Multilevel security (Managing Security)
Table T1 Table T2
A1 B1
== ==
1 1
2 2
Now suppose that an application executes the following statements to perform a positioned update
operation:
When Db2 executes the FETCH statement that positions cursor C1 for the first time, Db2 evaluates the
subselect, SELECT B1 FROM T2, to produce a result table that contains the two rows of column T2:
1
2
When Db2 executes the positioned UPDATE statement for the first time, trigger TR1 is activated. When
the body of trigger TR1 executes, the row with value 2 is deleted from T2. However, because SELECT B1
FROM T2 is evaluated only once, when the FETCH statement is executed again, Db2 finds the second row
of T1, even though the second row of T2 was deleted. The FETCH statement positions the cursor to the
second row of T1, and the second row of T1 is updated. The update operation causes the trigger to be
activated again, which causes Db2 to attempt to delete the second row of T2, even though that row was
already deleted.
To avoid processing of the second row after it should have been deleted, use a correlated subquery in the
cursor declaration:
In this case, the subquery, SELECT B1 FROM T2 WHERE X.A1 = B1, is evaluated for each FETCH
statement. The first time that the FETCH statement executes, it positions the cursor to the first row of T1.
The positioned UPDATE operation activates the trigger, which deletes the second row of T2. Therefore,
when the FETCH statement executes again, no row is selected, so no update operation or triggered action
occurs.
Example: Effect of row processing order on a triggered action: The following example shows how the
order of processing rows can change the outcome of an after row trigger.
Suppose that tables T1, T2, and T3 look like this:
164 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
UPDATE T1 SET A1 = A1 + 1;
The contents of tables T2 and T3 after the UPDATE statement executes depend on the order in which Db2
updates the rows of T1.
If Db2 updates the first row of T1 first, after the UPDATE statement and the trigger execute for the first
time, the values in the three tables are:
After the second row of T1 is updated, the values in the three tables are:
However, if Db2 updates the second row of T1 first, after the UPDATE statement and the trigger execute
for the first time, the values in the three tables are:
After the first row of T1 is updated, the values in the three tables are:
Procedure
To change an existing basic trigger into an advanced trigger, complete the following steps:
1. Modify the original CREATE TRIGGER statement into a CREATE TRIGGER (advanced) statement by
removing any of the following items:
• The MODE DB2SQL clause. Db2 attempts to creates a basic trigger if that clause is included.
• Stand-alone fullselect or VALUES statements. You can use SELECT INTO statement or VALUES INTO
statements instead.
2. Use one of the following approaches to convert to the new advanced trigger definition:
• Issue the modified CREATE TRIGGER (advanced) statement with the OR REPLACE clause.
• Issue a DROP statement for the original trigger and then issue the new CREATE TRIGGER
statement.
The existing trigger is effectively dropped, and an advanced trigger is defined. If multiple triggers are
defined on the associated table, the trigger activation order changes.
What to do next
If multiple triggers are defined on the associated table, you might need to restore the original the
activation order of the triggers. To do that, you must drop and re-create any triggers that were created
after the converted trigger was originally created, in the same order that they were originally created. For
more information about the activation order of multiple triggers, see “Activation order of multiple triggers”
on page 161.
Related reference
DROP (Db2 SQL)
CREATE TRIGGER (advanced) (Db2 SQL)
SYSTRIGGERS catalog table (Db2 SQL)
Sequence objects
A sequence is a user-defined object that generates a sequence of numeric values according to the
specification with which the sequence was created. Sequences, unlike identity columns, are not
associated with tables. Applications refer to a sequence object to get its current or next value.
The sequence of numeric values is generated in a monotonically ascending or descending order. The
relationship between sequences and tables is controlled by the application, not by Db2.
Your application can reference a sequence object and coordinate the value as keys across multiple rows
and tables. However, a table column that gets its values from a sequence object does not necessarily
have unique values in that column. Even if the sequence object has been defined with the NO CYCLE
clause, some other application might insert values into that table column other than values you obtain by
referencing that sequence object.
Db2 always generates sequence numbers in order of request. However, in a data sharing group where the
sequence values are cached by multiple Db2 members simultaneously, the sequence value assignments
might not be in numeric order. Additionally, you might have gaps in sequence number values for the
following reasons:
166 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
• If Db2 terminates abnormally before it assigns all the cached values
• If your application rolls back a transaction that increments the sequence
• If the statement containing NEXT VALUE fails after it increments the sequence
You create a sequence object with the CREATE SEQUENCE statement, alter it with the ALTER SEQUENCE
statement, and drop it with the DROP SEQUENCE statement. You grant access to a sequence with
the GRANT (privilege) ON SEQUENCE statement, and revoke access to the sequence with the REVOKE
(privilege) ON SEQUENCE statement.
The values that Db2 generates for a sequence depend on how the sequence is created. The START WITH
option determines the first value that Db2 generates. The values advance by the INCREMENT BY value in
ascending or descending order.
The MINVALUE and MAXVALUE options determine the minimum and maximum values that Db2
generates. The CYCLE or NO CYCLE option determines whether Db2 wraps the generated values when it
reaches the maximum value for an ascending sequence or the minimum value in a descending sequence.
Keys across multiple tables: You can use the same sequence number as a key value in two separate
tables by first generating the sequence value with a NEXT VALUE expression to insert the first row in the
first table. You can then reference this same sequence value with a PREVIOUS VALUE expression to insert
the other rows in the second table.
Example: Suppose that an ORDERS table and an ORDER_ITEMS table are defined in the following way:
You create a sequence named ORDER_SEQ to use as key values for both the ORDERS and ORDER_ITEMS
tables:
You can then use the same sequence number as a primary key value for the ORDERS table and as part of
the primary key value for the ORDER_ITEMS table:
The NEXT VALUE expression in the first INSERT statement generates a sequence number value for
the sequence object ORDER_SEQ. The PREVIOUS VALUE expression in the second INSERT statement
retrieves that same value because it was the sequence number most recently generated for that
sequence object within the current application process.
Procedure
Issue the CREATE DISTINCT TYPE statement.
For example, you can create distinct types for euros and yen by issuing the following SQL statements:
Related reference
CREATE TYPE (distinct) (Db2 SQL)
168 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Distinct types
A distinct type is a user-defined data type that shares its internal representation with a built-in data type
(its source type), but is considered to be a separate and incompatible data type for most operations.
Each distinct type has the same internal representation as a built-in data type.
Suppose you want to define some audio and video data in a Db2 table. You can define columns for both
types of data as BLOB, but you might want to use a data type that more specifically describes the data.
To do that, define distinct types. You can then use those types when you define columns in a table or
manipulate the data in those columns. For example, you can define distinct types for the audio and video
data like this:
For more information on LOB data, see “Storing LOB data in a table” on page 121 and Large objects
(LOBs) (Db2 SQL).
After you define distinct types and columns of those types, you can use those data types in the same way
you use built-in types. You can use the data types in assignments, comparisons, function invocations, and
stored procedure calls. However, when you assign one column value to another or compare two column
values, those values must be of the same distinct type. For example, you must assign a column value of
type VIDEO to a column of type VIDEO, and you can compare a column value of type AUDIO only to a
column of type AUDIO. When you assign a host variable value to a column with a distinct type, you can
use any host data type that is compatible with the source data type of the distinct type. For example, to
receive an AUDIO or VIDEO value, you can define a host variable like this:
When you use a distinct type as an argument to a function, a version of that function that accepts
that distinct type must exist. For example, if function SIZE takes a BLOB type as input, you cannot
automatically use a value of type AUDIO as input. However, you can create a sourced user-defined
function that takes the AUDIO type as input. For example:
Using distinct types in application programs: The main reason to use distinct types is because
Db2 enforces strong typing for distinct types. Strong typing ensures that only functions, procedures,
comparisons, and assignments that are defined for a data type can be used.
For example, if you have defined a user-defined function to convert U.S. dollars to euro currency, you do
not want anyone to use this same user-defined function to convert Japanese yen to euros because the
U.S. dollars to euros function returns the wrong amount. Suppose you define three distinct types:
If a conversion function is defined that takes an input parameter of type US_DOLLAR as input, Db2 returns
an error if you try to execute the function with an input parameter of type JAPANESE_YEN.
You have also defined and written user-defined functions to search for and return the following
information about an electronic mail document:
• Subject
• Sender
• Date sent
• Message content
• Indicator of whether the document contains a user-specified string
The user-defined function definitions look like this:
170 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
DETERMINISTIC
NO EXTERNAL ACTION;
The table that contains the electronic mail documents is defined like this:
Because the table contains a column with a source data type of CLOB, the table requires an associated
LOB table space, auxiliary table, and index on the auxiliary table. Use statements like this to define the
LOB table space, the auxiliary table, and the index:
To populate the document table, you write code that executes an INSERT statement to put the first part
of a document in the table, and then executes multiple UPDATE statements to concatenate the remaining
parts of the document. For example:
Now that the data is in the table, you can execute queries to learn more about the documents. For
example, you can execute this query to determine which documents contain the word "performance":
Because the electronic mail documents can be very large, you might want to use LOB locators to
manipulate the document data instead of fetching all of a document into a host variable. You can use
a LOB locator on any distinct type that is defined on one of the LOB types. The following example shows
You cannot retrieve the contents of a column directly into an array. You need to use the ARRAY_AGG
function to create an array that is the intermediate result of a SELECT statement, and then retrieve the
contents of that array into an SQL array variable or parameter. For example:
172 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
You can retrieve data from an array by using the UNNEST specification to assign array elements to an
intermediate result table. For example:
For example, these statements populate an associative array, which must be populated one element at a
time:
A number of built-in functions are available for manipulating arrays. They are:
ARRAY_DELETE
Deletes elements from an array.
ARRAY_FIRST
Returns the minimum array index value of an array.
ARRAY_LAST
Returns the maximum array index value of an array.
ARRAY_NEXT
Returns the next larger array index value, relative to a specified array index value.
ARRAY_PRIOR
Returns the next smaller array index value, relative to a specified array index value.
CARDINALITY
Returns the number of elements in an array.
MAX_CARDINALITY
Returns the maximum number of elements that an array can contain.
TRIM_ARRAY
Deletes elements from the end of an ordinary array.
Related concepts
Array type comparisons (Db2 SQL)
Array type assignments (Db2 SQL)
Array types (Db2 SQL)
Related reference
Array constructor (Db2 SQL)
ARRAY_AGG (Db2 SQL)
ARRAY_DELETE (Db2 SQL)
ARRAY_FIRST (Db2 SQL)
ARRAY_NEXT (Db2 SQL)
ARRAY_PRIOR (Db2 SQL)
CARDINALITY (Db2 SQL)
MAX_CARDINALITY (Db2 SQL)
TRIM_ARRAY (Db2 SQL)
--
-- CREATE ASSOCIATIVE ARRAY TYPES
--
CREATE TYPE CHARARRAY AS CHAR(10) ARRAY[VARCHAR(3)]#
CREATE TYPE BIGINTARRAY AS BIGINT ARRAY[INTEGER]#
--
-- CREATE ORDINARY ARRAY TYPES
--
CREATE TYPE INTARRAY AS INTEGER ARRAY[100]#
CREATE TYPE STRINGARRAY AS VARCHAR(10) ARRAY[100]#
--
-- CREATE TABLES THAT ARE USED IN SQL PROCEDURE PROCESSPERSONS
--
CREATE TABLE PERSONS (ID INTEGER, NAME VARCHAR(10))#
CREATE TABLE ARRAYTEST (CHARCOL CHAR(10), INTCOL INT)#
-- SQL PROCEDURE PROCESSPERSONS HAS THREE ARRAY PARAMETERS:
-- OUTSETARRAY IS AN OUT PARAMETER OF ORDINARY ARRAY TYPE STRINGARRAY.
-- OUTSELECTWITHCURSOR IS AN OUT PARAMETER OF ORDINARY ARRAY TYPE STRINGARRAY.
-- OUTSELECTWITHARRAYAGG IS AN OUT PARAMETER OF ORDINARY ARRAY TYPE INTARRAY.
--
CREATE PROCEDURE PROCESSPERSONS(OUT OUTSETARRAY STRINGARRAY,
INOUT INT0 INT,
OUT OUTSELECTWITHCURSOR STRINGARRAY,
OUT OUTMAXCARDINALITY BIGINT,
OUT OUTSELECTWITHARRAYAGG INTARRAY)
ARRAYDEMO: BEGIN
-- DECLARE SQL VARIABLES OF ORDINARY ARRAY TYPES
DECLARE IDS_ORDARRAYVAR INTARRAY;
DECLARE INT_ORDARRAYVAR INTARRAY;
DECLARE NAMES_ORDARRAYVAR STRINGARRAY;
-- DECLARE SQL VARIABLES OF ASSOCIATIVE ARRAY TYPES
DECLARE CHAR_ASSOCARRAYVAR CHARARRAY;
DECLARE BIGINT_ASSOCARRAYVAR BIGINTARRAY;
-- DECLARE SCALAR SQL VARIABLES
DECLARE DECFLOAT_VAR DECFLOAT;
DECLARE BIGINT_VAR BIGINT;
DECLARE SMALLINT_VAR SMALLINT;
DECLARE INT_VAR INT DEFAULT 1;
DECLARE STMT_VAR CHAR(100);
-- DECLARE A CURSOR
DECLARE C2 CURSOR FOR S1;
174 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
--
-- THE RESULT TABLE OF CURSOR C1 IS AN ARRAY THAT IS POPULATED BY
-- RETRIEVING THE VALUES OF THE NAME COLUMN FROM TABLE PERSONS,
-- ORDERING THE VALUES BY ID, AND USING THE ARRAY_AGG FUNCTION
-- TO ASSIGN THE VALUES TO AN ARRAY.
--
DECLARE C1 CURSOR FOR SELECT ARRAY_AGG(NAME ORDER BY ID) FROM PERSONS
WHERE NAME LIKE 'J%';
--
-- USE ARRAY CONSTRUCTORS TO INITIALIZE ARRAYS
--
SET IDS_ORDARRAYVAR = ARRAY[5,6,7];
SET NAMES_ORDARRAYVAR = ARRAY['BOB', 'ANN', 'SUE'];
SET CHAR_ASSOCARRAYVAR['001']='1';
SET CHAR_ASSOCARRAYVAR['002']='2';
SET CHAR_ASSOCARRAYVAR['003']='3';
SET CHAR_ASSOCARRAYVAR['004']='4';
SET CHAR_ASSOCARRAYVAR['005']='5';
SET CHAR_ASSOCARRAYVAR['006']='6';
SET INT_ORDARRAYVAR = ARRAY[1,INTEGER(2),3+0,4,5,6] ;
SET BIGINT_ASSOCARRAYVAR[1] = 9;
SET BIGINT_ASSOCARRAYVAR[3] = 10;
SET BIGINT_ASSOCARRAYVAR[5] = 11;
SET BIGINT_ASSOCARRAYVAR[7] = 12;
SET BIGINT_ASSOCARRAYVAR[9] = 13;
--
-- ASSIGN A CONSTANT TO AN ARRAY ELEMENT.
--
SET IDS_ORDARRAYVAR[4] = 8;
--
-- ASSIGN AN EXPRESSION TO AN ARRAY ELEMENT.
--
SET IDS_ORDARRAYVAR[5] = 8 * 4 ;
--
-- ASSIGN AN ARRAY ELEMENT TO ANOTHER ARRAY ELEMENT. USE AN EXPRESSION
-- TO IDENTIFY THE TARGET ARRAY ELEMENT.
--
SET NAMES_ORDARRAYVAR[1+INT_VAR] = NAMES_ORDARRAYVAR[5] ;
--
-- POPULATE THE PERSONS TABLE WITH AN INSERT STATEMENT WITH A SUBSELECT:
-- - USE UNNEST TO RETRIEVE VALUES FROM AN ARRAY INTO AN INTERMEDIATE RESULT
-- TABLE.
-- - INSERT THE VALUES FROM THE INTERMEDIATE RESULT TABLE INTO
-- THE PERSONS TABLE.
--
INSERT INTO PERSONS(ID, NAME)
(SELECT T.I, T.N FROM UNNEST(IDS_ORDARRAYVAR, NAMES_ORDARRAYVAR) AS T(I, N));
--
-- USE THE ARRAY_AGG FUNCTION TO CREATE AN ARRAY FROM THE RESULT
-- TABLE OF A SELECT. THEN ASSIGN THAT ARRAY TO AN SQL OUT PARAMETER.
--
SET OUTSETARRAY = (SELECT ARRAY_AGG(NAME ORDER BY ID)
FROM PERSONS
WHERE NAME LIKE '%O%');
--
-- USE THE CARDINALITY FUNCTION TO CONTROL THE NUMBER OF TIMES THAT
-- AN INSERT STATEMENT IS EXECUTED TO POPULATE TABLE ARRAYTEST
-- WITH ARRAY ELEMENTS.
--
SET SMALLINT_VAR = 1;
WHILE SMALLINT_VAR <= CARDINALITY(INT_ORDARRAYVAR) DO
INSERT INTO ARRAYTEST VALUES
(CHAR_ASSOCARRAYVAR[SMALLINT_VAR],
INT_ORDARRAYVAR[SMALLINT_VAR]);
SET SMALLINT_VAR = SMALLINT_VAR+1;
END WHILE;
--
-- DYNAMICALLY EXECUTE AN SQL SELECT STATEMENT WITH A PARAMETER MARKER
-- FOR AN ARRAY, AND A PARAMETER MARKER FOR THE ARRAY INDEX.
--
SET INT_VAR = 3;
SET STMT_VAR =
'SELECT INTCOL FROM ARRAYTEST WHERE INTCOL = ' ||
'CAST(? AS INTARRAY)[?]';
PREPARE S1 FROM STMT_VAR;
OPEN C2 USING INT_ORDARRAYVAR, INT_VAR;
FETCH C2 INTO INT0;
CLOSE C2;
--
-- USE A CURSOR TO FETCH AN ARRAY THAT IS CREATED WITH THE ARRAY_AGG FUNCTION
-- INTO AN ARRAY SQL OUT PARAMETER.
--
Related concepts
Array type comparisons (Db2 SQL)
Array type assignments (Db2 SQL)
Related reference
Array constructor (Db2 SQL)
ARRAY_AGG (Db2 SQL)
CARDINALITY (Db2 SQL)
MAX_CARDINALITY (Db2 SQL)
176 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Each time that the function is invoked, the package executes one or more times. See CREATE
FUNCTION (external scalar) (Db2 SQL).
External table
The function is written in a programming language. It returns a table to the subselect from which
it was started by returning one row at a time, each time that the function is started. The external
executable routine (package) is registered with a database server along with various attributes of the
function. Each time that the function is invoked, the package executes one or more times. See CREATE
FUNCTION (external table) (Db2 SQL).
Sourced
The function is implemented by invoking another function (either built-in, external, SQL, or sourced)
that exists at the server. The function inherits the attributes of the underlying source function. A
sourced function does not have an associated package. See CREATE FUNCTION (sourced) (Db2 SQL).
SQL scalar
The function is written exclusively in SQL statements and returns a scalar value. The body of an SQL
scalar function is written in the SQL procedural language (SQL PL). The function is defined at the
current server along with various attributes of the function.
Db2 supports two types of SQL scalar functions, inlined and compiled:
• Inlined SQL scalar functions contain a single RETURN statement, which returns the value of a
simple expression. The function is not invoked as part of a query; instead, the expression in the
RETURN statement of the function is copied (inlined) into the query itself. Therefore, a package is
not generated for an inlined SQL scalar function.
• Compiled SQL scalar functions support a larger set of functionality, including all of the SQL PL
statements. A package is generated for a compiled SQL scalar function. It contains the body of the
function, including control statements. It might also contain statements generated by Db2. Each
time that the function is invoked, the package executes one or more times.
When a CREATE FUNCTION statement for an SQL scalar function is processed, Db2 attempts to create
an inlined SQL scalar function. If the function cannot be created as an inlined function, Db2 attempts
to create a compiled SQL scalar function. For more information on the syntax and rules for these types
of functions, see CREATE FUNCTION (inlined SQL scalar) (Db2 SQL) and CREATE FUNCTION (compiled
SQL scalar) (Db2 SQL).
To determine what type of SQL scalar function is created, refer to the INLINE column of the
SYSIBM.SYSROUTINES catalog table.
SQL table
The function is written exclusively as an SQL RETURN statement and returns a set of rows. The body
of an SQL table function is written in the SQL procedural language. The function is defined at the
current server along with various attributes. The function is not invoked as part of a query. Instead,
the expression in the RETURN statement of the function is copied (inlined) into the query itself.
Therefore, a package is not generated for an SQL table function. See CREATE FUNCTION (SQL table)
(Db2 SQL).
The environment for user-defined functions includes application address space, from which a program
invokes a user-defined function; a Db2 system, where the packages from the user-defined function are
run; and a WLM-established address space, where the user-defined function may be executed; as shown
in the following figure.
For information on Java user-defined functions, see Java stored procedures and user-defined functions
(Db2 Application Programming for Java). For user-defined functions in other languages, see the following
instructions.
Procedure
To create a user-defined function:
1. Write and prepare the user-defined function, as described in “Writing an external user-defined
function” on page 183.
This step is necessary only for an external user-defined function.
2. Define the user-defined function to Db2 by issuing a CREATE FUNCTION statement that specifies the
type of function that you want to create.
For more information, see CREATE FUNCTION (Db2 SQL).
3. Invoke the user-defined function from an SQL application, as described in “Invoking a user-defined
function” on page 447.
The logic of the function is contained in the function definition as the following statement:
RETURN SIN(X)/COS(X)
What to do next
If you discover after you define the function that you need to change a part of the definition, you can
use an ALTER FUNCTION statement to change the definition. You cannot use ALTER FUNCTION to change
some of the characteristics of a user-defined function definition.
Related concepts
Sample user-defined functions (Db2 SQL)
Related tasks
Controlling user-defined functions (Db2 Administration Guide)
178 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Related reference
CREATE FUNCTION (Db2 SQL)
External functions
An external user-defined function is a function that is written in a programming language. An external
function is defined to the database with a reference to an external program that contains the logic that is
executed when the function is invoked.
An external user-defined function that returns a single value is a scalar function. An external user-defined
function that returns a table is a table function.
You can write an external user-defined function in assembler, C, C++, COBOL, PL/I, or Java. User-defined
functions that are written in COBOL can include object-oriented extensions, just as other Db2 COBOL
programs can. User-defined functions that are written in Java follow coding guidelines and restrictions
specific to Java. For information about writing Java user-defined functions, see Java stored procedures
and user-defined functions (Db2 Application Programming for Java).
Examples
Example 1: Definition for an external user-defined scalar function
A programmer develops a user-defined function that searches for a string of maximum length 200
in a CLOB value whose maximum length is 500 KB. This CREATE FUNCTION statement defines the
user-defined function:
The function returns a status code as an integer. The CAST FROM clause is specified because the
function operation results in a floating point value, and users are expecting an integer result for their
SQL statements. The user-defined function is written in C and contains no SQL statements.
Suppose that you want a FINDSTRING user-defined function to work on BLOB data types, as well as
CLOB types. You can define another instance of a FINDSTRING user-defined function that specifies a
BLOB type as input:
Each instance of FINDSTRING uses a different application program to implement the logic for the
user-defined function.
Example 2: Definition for an external user-defined scalar function
A programmer has written a user-defined function for division. That is, this user-defined function is
invoked when an application program executes a statement using the division operator (/), such as the
following statement:
The user-defined function takes two integer values as input. The output from the user-defined
function is of type integer. The user-defined function is in the MATH schema, is written in assembler,
180 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Compiled SQL scalar functions include support for versions and source code management. You can use
compiled SQL scalar functions for the following tasks:
• Define multiple versions of an SQL scalar function, where one version is considered the "active" version.
• Activate a particular version of an SQL scalar function.
• Alter the routine options that are associated with a version of an SQL scalar function.
• Define a new version of an SQL scalar function by specifying the same function signature as the current
version, and different routine options and function body.
• Replace the definition of an existing version by specifying the same function signature as the current
version, and different routine options and function body.
• Drop a version of an SQL scalar function.
• Fall back to a previous version without requiring an explicit rebind or recompile, by activating the
previous version.
You can deploy compiled SQL scalar functions to multiple servers to allow a wider community to use
functions that have been thoroughly tested, without the risk of changing the logic in the routine body.
Use the Unified Debugger to remotely debug compiled SQL scalar functions that execute on Db2 for z/OS
servers.
To prepare an SQL scalar function for execution, you execute the CREATE FUNCTION statement, either
statically or dynamically.
Sourced functions
A sourced function is a function that invokes another function that already exists at the server. The
function inherits the attributes of the underlying source function. The source function can be built-in,
external, SQL, or sourced. Sourced functions can be used to extend built-in aggregate and scalar
functions for use on distinct types.
You can use sourced functions to build upon existing built-in functions or other user-defined functions.
Sourced functions are useful to extend built-in aggregate and scalar functions for use on distinct types.
To implement a sourced function, issue a CREATE FUNCTION statement and identify the function upon
which you want to base the sourced function in the SOURCE clause.
182 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Related reference
CREATE FUNCTION (sourced) (Db2 SQL)
It contains an application address space, from which a program invokes a user-defined function; a Db2
system, where the packages from the user-defined function are run; and a WLM-established address
space, where the user-defined function is executed. The steps for setting up and maintaining the
user-defined function environment are the same as for setting up and maintaining the environment for
stored procedures in WLM-established address spaces.
• Writing and preparing the user-defined function
This step is necessary only for an external user-defined function.
The person who performs this step is called the user-defined function implementer.
• Defining the user-defined function to Db2
The person who performs this step is called the user-defined function definer.
• Invoking the user-defined function from an SQL application
The person who performs this step is called the user-defined function invoker.
Related concepts
Java stored procedures and user-defined functions (Db2 Application Programming for Java)
Procedure
You can write an external user-defined function in assembler, C, C++, COBOL, PL/I, or Java.
184 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
For example, suppose that the user-defined function uses the scratchpad to count the number of
times it is invoked. If a scratchpad is allocated for each parallel task, this count is the number of
invocations done by the parallel task and not for the entire SQL statement, which is not the result
that is wanted.
• FINAL CALL
If a user-defined function performs an external action, such as sending a note, for each final call to
the function, one note is sent for each parallel task instead of once for the function invocation.
• EXTERNAL ACTION
Some user-defined functions with external actions can receive incorrect results if the function is
executed by parallel tasks.
For example, if the function sends a note for each initial call to the function, one note is sent for each
parallel task instead of once for the function invocation.
• NOT DETERMINISTIC
A user-defined function that is non-deterministic can generate incorrect results if it is run under a
parallel task.
For example, suppose that you execute the following query under parallel tasks:
COUNTER is a user-defined function that increments a variable in the scratchpad every time it is
invoked. Counter is non-deterministic because the same input does not always produce the same
output. Table T1 contains one column, C1, that has the following values:
1
2
3
4
5
6
7
8
9
10
When the query is executed with no parallelism, Db2 invokes COUNTER once for each row of table
T1, and there is one scratchpad for counter, which Db2 initializes the first time that COUNTER
executes. COUNTER returns 1 the first time it executes, 2 the second time, and so on. The result
table for the query has the following values:
1
2
3
4
5
6
7
8
9
10
Now suppose that the query is run with parallelism, and Db2 creates three parallel tasks. Db2
executes the predicate WHERE C1 = COUNTER() for each parallel task. This means that each
parallel task invokes its own instance of the user-defined function and has its own scratchpad. Db2
initializes the scratchpad to zero on the first call to the user-defined function for each parallel task.
If parallel task 1 processes rows 1 to 3, parallel task 2 processes rows 4 to 6, and parallel task 3
processes rows 7 to 10, the following results occur:
– When parallel task 1 executes, C1 has values 1, 2, and 3, and COUNTER returns values 1, 2, and
3, so the query returns values 1, 2, and 3.
186 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Register 1 Addresses of: Data:
1
Result 1 Result 1 data
Indicator 1 Indicator 1
Indicator 2 Indicator 2
SQLSTATE SQLSTATE
Procedure
name Procedure name
Specific
name Specific name
Message
Message text
text
2
Scratchpad Scratchpad
3
Call type Call type
4, 5
DBINFO DBINFO
1. For a user-defined scalar function, only one result and one result indicator are passed.
2. Passed if the SCRATCHPAD option is specificed in the user-defined function definition.
3. Passed if the FINAL CALL option is specified in a user-defined scalar function definition;
always passed for a user-defined table function.
4. For PL/I, this value is the address of a pointer to the DBINFO data.
5. Passed if the DBINFO option is specified in the user-defined function definition.
Table 42. Listing of tables of compatible data types for LOBS, ROWID, and locators
Language Location of compatible data types table
Assembler “Equivalent SQL and assembler data types” on page 560
C “Equivalent SQL and C data types” on page 608
COBOL “Equivalent SQL and COBOL data types” on page 675
PL/I “Equivalent SQL and PL/I data types” on page 718
Result parameters: Set these values in your user-defined function before exiting. For a user-defined
scalar function, you return one result parameter. For a user-defined table function, you return the same
number of parameters as columns in the RETURNS TABLE clause of the CREATE FUNCTION statement.
Db2 allocates a buffer for each result parameter value and passes the buffer address to the user-defined
function. Your user-defined function places each result parameter value in its buffer. You must ensure that
the length of the value you place in each output buffer does not exceed the buffer length. Use the SQL
data type and length in the CREATE FUNCTION statement to determine the buffer length.
See “Parameters for external user-defined functions” on page 186 to determine the host data type to use
for each result parameter value. If the CREATE FUNCTION statement contains a CAST FROM clause, use a
data type that corresponds to the SQL data type in the CAST FROM clause. Otherwise, use a data type that
corresponds to the SQL data type in the RETURNS or RETURNS TABLE clause.
To improve performance for user-defined table functions that return many columns, you can pass values
for a subset of columns to the invoker. For example, a user-defined table function might be defined to
return 100 columns, but the invoker needs values for only two columns. Use the DBINFO parameter to
indicate to Db2 the columns for which you will return values. Then return values for only those columns.
See DBINFO for information about how to indicate the columns of interest.
Input parameter indicators: These are SMALLINT values, which Db2 sets before it passes control to the
user-defined function. You use the indicators to determine whether the corresponding input parameters
are null. The number and order of the indicators are the same as the number and order of the input
parameters. On entry to the user-defined function, each indicator contains one of these values:
0
The input parameter value is not null.
negative
The input parameter value is null.
Code the user-defined function to check all indicators for null values unless the user-defined function is
defined with RETURNS NULL ON NULL INPUT. A user-defined function defined with RETURNS NULL ON
NULL INPUT executes only if all input parameters are not null.
Result indicators: These are SMALLINT values, which you must set before the user-defined function ends
to indicate to the invoking program whether each result parameter value is null. A user-defined scalar
function has one result indicator. A user-defined table function has the same number of result indicators
as the number of result parameters. The order of the result indicators is the same as the order of the
result parameters. Set each result indicator to one of these values:
0 or positive
The result parameter is not null.
negative
The result parameter is null.
SQLSTATE value: This CHAR(5) value represents the SQLSTATE that is passed in to the program from the
database manager. The initial value is set to ‘00000'. Although the SQLSTATE is usually not set by the
program, it can be set as the result SQLSTATE that is used to return an error or a warning. Returned values
that start with anything other than ‘00', ‘01', or ‘02' are error conditions.
188 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
User-defined function name: Db2 sets this value in the parameter list before the user-defined function
executes. This value is VARCHAR(257): 128 bytes for the schema name, 1 byte for a period, and 128
bytes for the user-defined function name. If you use the same code to implement multiple versions of a
user-defined function, you can use this parameter to determine which version of the function the invoker
wants to execute.
Specific name: Db2 sets this value in the parameter list before the user-defined function executes.
This value is VARCHAR(128) and is either the specific name from the CREATE FUNCTION statement
or a specific name that Db2 generated. If you use the same code to implement multiple versions of a
user-defined function, you can use this parameter to determine which version of the function the invoker
wants to execute.
Diagnostic message: Your user-defined function can set this CHAR or VARCHAR value to a character
string of up to 1000 bytes before exiting. Use this area to pass descriptive information about an error or
warning to the invoker.
Db2 allocates a buffer for this area and passes you the buffer address in the parameter list. At least
the first 17 bytes of the value you put in the buffer appear in the SQLERRMC field of the SQLCA that is
returned to the invoker. The exact number of bytes depends on the number of other tokens in SQLERRMC.
Do not use X'FF' in your diagnostic message. Db2 uses this value to delimit tokens.
Scratchpad: If the definer specified SCRATCHPAD in the CREATE FUNCTION statement, Db2 allocates
a buffer for the scratchpad area and passes its address to the user-defined function. Before the user-
defined function is invoked for the first time in an SQL statement, Db2 sets the length of the scratchpad
in the first 4 bytes of the buffer and then sets the scratchpad area to X'00'. Db2 does not reinitialize the
scratchpad between invocations of a correlated subquery.
You must ensure that your user-defined function does not write more bytes to the scratchpad than the
scratchpad length.
Call type: For a user-defined scalar function, if the definer specified FINAL CALL in the CREATE
FUNCTION statement, Db2 passes this parameter to the user-defined function. For a user-defined table
function, Db2 always passes this parameter to the user-defined function.
On entry to a user-defined scalar function, the call type parameter has one of the following values:
-1
This is the first call to the user-defined function for the SQL statement. For a first call, all input
parameters are passed to the user-defined function. In addition, the scratchpad, if allocated, is set to
binary zeros.
0
This is a normal call. For a normal call, all the input parameters are passed to the user-defined
function. If a scratchpad is also passed, Db2 does not modify it.
1
This is a final call. For a final call, no input parameters are passed to the user-defined function. If a
scratchpad is also passed, Db2 does not modify it.
This type of final call occurs when the invoking application explicitly closes a cursor. When a value of 1
is passed to a user-defined function, the user-defined function can execute SQL statements.
255
This is a final call. For a final call, no input parameters are passed to the user-defined function. If a
scratchpad is also passed, Db2 does not modify it.
This type of final call occurs when the invoking application executes a COMMIT or ROLLBACK
statement, or when the invoking application abnormally terminates. When a value of 255 is passed to
the user-defined function, the user-defined function cannot execute any SQL statements, except for
CLOSE CURSOR. If the user-defined function executes any close cursor statements during this type of
final call, the user-defined function should tolerate SQLCODE -501 because Db2 might have already
closed cursors before the final call.
During the first call, your user-defined scalar function should acquire any system resources it needs.
During the final call, the user-defined scalar function should release any resources it acquired during
190 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
DBINFO: If the definer specified DBINFO in the CREATE FUNCTION statement, Db2 passes the DBINFO
structure to the user-defined function. DBINFO contains information about the environment of the user-
defined function caller. It contains the following fields, in the order shown:
Location name length
An unsigned 2-byte integer field. It contains the length of the location name in the next field.
Location name
A 128-byte character field. It contains the name of the location to which the invoker is currently
connected.
Authorization ID length
An unsigned 2-byte integer field. It contains the length of the authorization ID in the next field.
Authorization ID
A 128-byte character field. It contains the authorization ID of the application from which the user-
defined function is invoked, padded on the right with blanks. If this user-defined function is nested
within other user-defined functions, this value is the authorization ID of the application that invoked
the highest-level user-defined function.
Subsystem code page
A 48-byte structure that consists of 10 integer fields and an eight-byte reserved area. These fields
provide information about the CCSIDs of the subsystem from which the user-defined function is
invoked.
Table qualifier length
An unsigned 2-byte integer field. It contains the length of the table qualifier in the next field. If the
table name field is not used, this field contains 0.
Table qualifier
A 128-byte character field. It contains the qualifier of the table that is specified in the table name
field.
Table name length
An unsigned 2-byte integer field. It contains the length of the table name in the next field. If the table
name field is not used, this field contains 0.
Table name
A 128-byte character field. This field contains the name of the table for the update or insert operation
if the reference to the user-defined function in the invoking SQL statement is in one of the following
places:
• The right side of a SET clause in an update operation
• In the VALUES list of an insert operation
Otherwise, this field is blank.
Column name length
An unsigned 2-byte integer field. It contains the length of the column name in the next field. If no
column name is passed to the user-defined function, this field contains 0.
Column name
A 128-byte character field. This field contains the name of the column that the update or insert
operation modifies if the reference to the user-defined function in the invoking SQL statement is in
one of the following places:
• The right side of a SET clause in an update operation
• In the VALUES list of an insert operation
Otherwise, this field is blank.
Product information
An 8-byte character field that identifies the product on which the user-defined function executes.
The product identifier (PRDID) value is an 8-byte character value in pppvvrrm format, where: ppp is a
3-letter product code; vv is the version;rr is the release; and m is the modification level. In Db2 12 for
z/OS, the modification level indicates a range of function levels:
192 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Number of entries in table function column list
An unsigned 2-byte integer field.
Reserved area
26 bytes.
Table function column list pointer
If a table function is defined, this field is a pointer to an array that contains 1000 2-byte integers. Db2
dynamically allocates the array. If a table function is not defined, this pointer is null.
Only the first n entries, where n is the value in the field entitled number of entries in table function
column list, are of interest. n is greater than or equal to 0 and less than or equal to the number
result columns defined for the user-defined function in the RETURNS TABLE clause of the CREATE
FUNCTION statement. The values correspond to the numbers of the columns that the invoking
statement needs from the table function. A value of 1 means the first defined result column, 2 means
the second defined result column, and so on. The values can be in any order. If n is equal to 0, the
first array element is 0. This is the case for a statement like the following one, where the invoking
statement needs no column values.
This array represents an opportunity for optimization. The user-defined function does not need to
return all values for all the result columns of the table function. Instead, the user-defined function can
return only those columns that are needed in the particular context, which you identify by number in
the array. However, if this optimization complicates the user-defined function logic enough to cancel
the performance benefit, you might choose to return every defined column.
Unique application identifier
This field is a pointer to a string that uniquely identifies the application's connection to Db2. The string
is regenerated for each connection to Db2.
The string is the LUWID, which consists of a fully-qualified LU network name followed by a period and
an LUW instance number. The LU network name consists of a 1- to 8-character network ID, a period,
and a 1- to 8-character network LU name. The LUW instance number consists of 12 hexadecimal
characters that uniquely identify the unit of work.
Reserved area
20 bytes.
If you write your user-defined function in C or C++, you can use the declarations in member SQLUDF of
DSN1210.SDSNC.H for many of the passed parameters. To include SQLUDF, make these changes to your
program:
• Put this statement in your source code:
#include <sqludf.h>
• Include the DSN1210.SDSNC.H data set in the SYSLIB concatenation for the compiler step of your
program preparation job.
• Specify the NOMARGINS and NOSEQUENCE options in the compiler step of your program preparation
job.
Examples of receiving parameters in a user-defined function:
The following examples show how a user-defined function that is written in each of the supported host
languages receives the parameter list that is passed by Db2.
These examples assume that the user-defined function is defined with the SCRATCHPAD, FINAL CALL,
and DBINFO parameters.
Assembler: The follow figure shows the parameter conventions for a user-defined scalar function that
is written as a main program that receives two parameters and returns one result. For an assembler
C or C++: For C or C++ user-defined functions, the conventions for passing parameters are different for
main programs and subprograms.
For subprograms, you pass the parameters directly. For main programs, you use the standard argc and
argv variables to access the input and output parameters:
• The argv variable contains an array of pointers to the parameters that are passed to the user-defined
function. All string parameters that are passed back to Db2 must be null terminated.
– argv[0] contains the address of the load module name for the user-defined function.
– argv[1] through argv[n] contain the addresses of parameters 1 through n.
• The argc variable contains the number of parameters that are passed to the external user-defined
function, including argv[0].
The following figure shows the parameter conventions for a user-defined scalar function that is written as
a main program that receives two parameters and returns one result.
#include <stdlib.h>
#include <stdio.h>
main(argc,argv)
int argc;
char *argv[];
{
/***************************************************/
/* Assume that the user-defined function invocation*/
/* included 2 input parameters in the parameter */
194 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
/* list. Also assume that the definition includes */
/* the SCRATCHPAD, FINAL CALL, and DBINFO options, */
/* so DB2 passes the scratchpad, calltype, and */
/* dbinfo parameters. */
/* The argv vector contains these entries: */
/* argv[0] 1 load module name */
/* argv[1-2] 2 input parms */
/* argv[3] 1 result parm */
/* argv[4-5] 2 null indicators */
/* argv[6] 1 result null indicator */
/* argv[7] 1 SQLSTATE variable */
/* argv[8] 1 qualified func name */
/* argv[9] 1 specific func name */
/* argv[10] 1 diagnostic string */
/* argv[11] 1 scratchpad */
/* argv[12] 1 call type */
/* argv[13] + 1 dbinfo */
/* ------ */
/* 14 for the argc variable */
/***************************************************/
if argc<>14
{
⋮
/**********************************************************/
/* This section would contain the code executed if the */
/* user-defined function is invoked with the wrong number */
/* of parameters. */
/**********************************************************/
}
/***************************************************/
/* Assume the first parameter is an integer. */
/* The following code shows how to copy the integer*/
/* parameter into the application storage. */
/***************************************************/
int parm1;
parm1 = *(int *) argv[1];
/***************************************************/
/* Access the null indicator for the first */
/* parameter on the invoked user-defined function */
/* as follows: */
/***************************************************/
short int ind1;
ind1 = *(short int *) argv[4];
/***************************************************/
/* Use the following expression to assign */
/* 'xxxxx' to the SQLSTATE returned to caller on */
/* the SQL statement that contains the invoked */
/* user-defined function. */
/***************************************************/
strcpy(argv[7],"xxxxx");
/***************************************************/
/* Obtain the value of the qualified function */
/* name with this expression. */
/***************************************************/
char f_func[28];
strcpy(f_func,argv[8]);
/***************************************************/
/* Obtain the value of the specific function */
/* name with this expression. */
/***************************************************/
char f_spec[19];
strcpy(f_spec,argv[9]);
/***************************************************/
/* Use the following expression to assign */
/* 'yyyyyyyy' to the diagnostic string returned */
/* in the SQLCA associated with the invoked */
/* user-defined function. */
/***************************************************/
strcpy(argv[10],"yyyyyyyy");
/***************************************************/
/* Use the following expression to assign the */
/* result of the function. */
/***************************************************/
char l_result[11];
strcpy(argv[3],l_result);
The following figure shows the parameter conventions for a user-defined scalar function written as a C
subprogram that receives two parameters and returns one result.
#pragma runopts(plist(os))
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sqludf.h>
l_p1 = *parm1;
strcpy(l_p2,parm2);
l_ind1 = *f_ind1;
l_ind1 = *f_ind2;
strcpy(ludf_sqlstate,udf_sqlstate);
strcpy(ludf_fname,udf_fname);
strcpy(ludf_specname,udf_specname);
l_udf_call_type = *udf_call_type;
strcpy(ludf_msgtext,udf_msgtext);
memcpy(&ludf_scratchpad,udf_scratchpad,sizeof(ludf_scratchpad));
memcpy(&ludf_dbinfo,udf_dbinfo,sizeof(ludf_dbinfo));
⋮
}
The following figure shows the parameter conventions for a user-defined scalar function that is written
as a C++ subprogram that receives two parameters and returns one result. This example demonstrates
that you must use an extern "C" modifier to indicate that you want the C++ subprogram to receive
parameters according to the C linkage convention. This modifier is necessary because the CEEPIPI
CALL_SUB interface, which Db2 uses to call the user-defined function, passes parameters using the C
linkage convention.
#pragma runopts(plist(os))
#include <stdlib.h>
#include <stdio.h>
#include <sqludf.h>
{
/***************************************************/
196 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
/* Define local copies of parameters. */
/***************************************************/
int l_p1;
char l_p2[11];
short int l_ind1;
short int l_ind2;
char ludf_sqlstate[6]; /* SQLSTATE */
char ludf_fname[138]; /* function name */
char ludf_specname[129]; /* specific function name */
char ludf_msgtext[71] /* diagnostic message text*/
sqludf_scratchpad *ludf_scratchpad; /* scratchpad */
long *ludf_call_type; /* call type */
sqludf_dbinfo *ludf_dbinfo /* dbinfo */
/***************************************************/
/* Copy each of the parameters in the parameter */
/* list into a local variable to demonstrate */
/* how the parameters can be referenced. */
/***************************************************/
l_p1 = *parm1;
strcpy(l_p2,parm2);
l_ind1 = *f_ind1;
l_ind1 = *f_ind2;
strcpy(ludf_sqlstate,udf_sqlstate);
strcpy(ludf_fname,udf_fname);
strcpy(ludf_specname,udf_specname);
l_udf_call_type = *udf_call_type;
strcpy(ludf_msgtext,udf_msgtext);
memcpy(&ludf_scratchpad,udf_scratchpad,sizeof(ludf_scratchpad));
memcpy(&ludf_dbinfo,udf_dbinfo,sizeof(ludf_dbinfo));
⋮
}
COBOL: The following figure shows the parameter conventions for a user-defined table function that
is written as a main program that receives two parameters and returns two results. For a COBOL user-
defined function that is a subprogram, the conventions are the same.
CBL APOST,RES,RENT
IDENTIFICATION DIVISION.
⋮
DATA DIVISION.
⋮
LINKAGE SECTION.
*********************************************************
* Declare each of the parameters *
*********************************************************
01 UDFPARM1 PIC S9(9) USAGE COMP.
01 UDFPARM2 PIC X(10).
⋮
*********************************************************
* Declare these variables for result parameters *
*********************************************************
01 UDFRESULT1 PIC X(10).
01 UDFRESULT2 PIC X(10).
⋮
*********************************************************
* Declare a null indicator for each parameter *
*********************************************************
01 UDF-IND1 PIC S9(4) USAGE COMP.
01 UDF-IND2 PIC S9(4) USAGE COMP.
⋮
*********************************************************
* Declare a null indicator for result parameter *
*********************************************************
01 UDF-RIND1 PIC S9(4) USAGE COMP.
01 UDF-RIND2 PIC S9(4) USAGE COMP.
⋮
*********************************************************
* Declare the SQLSTATE that can be set by the *
* user-defined function *
*********************************************************
01 UDF-SQLSTATE PIC X(5).
*********************************************************
* Declare the qualified function name *
*********************************************************
01 UDF-FUNC.
49 UDF-FUNC-LEN PIC 9(4) USAGE BINARY.
49 UDF-FUNC-TEXT PIC X(137).
*********************************************************
* Declare the specific function name *
*********************************************************
*********************************************************
* Declare the scratchpad *
*********************************************************
01 UDF-SCRATCHPAD.
49 UDF-SPAD-LEN PIC 9(9) USAGE BINARY.
49 UDF-SPAD-TEXT PIC X(100).
*********************************************************
* Declare the call type *
*********************************************************
01 UDF-CALL-TYPE PIC 9(9) USAGE BINARY.
*********************************************************
* CONSTANTS FOR DB2-EBCODING-SCHEME. *
*********************************************************
77 SQLUDF-ASCII PIC 9(9) VALUE 1.
77 SQLUDF-EBCDIC PIC 9(9) VALUE 2.
77 SQLUDF-UNICODE PIC 9(9) VALUE 3.
*********************************************************
* Structure used for DBINFO *
*********************************************************
01 SQLUDF-DBINFO.
* location name length
05 DBNAMELEN PIC 9(4) USAGE BINARY.
* location name
05 DBNAME PIC X(128).
* authorization ID length
05 AUTHIDLEN PIC 9(4) USAGE BINARY.
* authorization ID
05 AUTHID PIC X(128).
* environment CCSID information
05 CODEPG PIC X(48).
05 CDPG-DB2 REDEFINES CODEPG.
10 DB2-CCSIDS OCCURS 3 TIMES.
15 DB2-SBCS PIC 9(9) USAGE BINARY.
15 DB2-DBCS PIC 9(9) USAGE BINARY.
15 DB2-MIXED PIC 9(9) USAGE BINARY.
10 ENCODING-SCHEME PIC 9(9) USAGE BINARY.
10 RESERVED PIC X(8).
* other platform-specific deprecated CCSID structures not included here
* schema name length
05 TBSCHEMALEN PIC 9(4) USAGE BINARY.
* schema name
05 TBSCHEMA PIC X(128).
* table name length
05 TBNAMELEN PIC 9(4) USAGE BINARY.
* table name
05 TBNAME PIC X(128).
* column name length
05 COLNAMELEN PIC 9(4) USAGE BINARY.
* column name
05 COLNAME PIC X(128).
* product information
05 VER-REL PIC X(8).
* reserved for expansion
05 RESD0 PIC X(2).
* platform type
05 PLATFORM PIC 9(9) USAGE BINARY.
* number of entries in tfcolumn list array (tfcolumn, below)
05 NUMTFCOL PIC 9(4) USAGE BINARY.
198 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
*
PROCEDURE DIVISION USING UDFPARM1, UDFPARM2, UDFRESULT1,
UDFRESULT2, UDF-IND1, UDF-IND2,
UDF-RIND1, UDF-RIND2,
UDF-SQLSTATE, UDF-FUNC, UDF-SPEC,
UDF-DIAG, UDF-SCRATCHPAD,
UDF-CALL-TYPE, SQLUDF-DBINFO.
PL/I: The following figure shows the parameter conventions for a user-defined scalar function that is
written as a main program that receives two parameters and returns one result. For a PL/I user-defined
function that is a subprogram, the conventions are the same.
*PROCESS SYSTEM(MVS);
MYMAIN: PROC(UDF_PARM1, UDF_PARM2, UDF_RESULT,
UDF_IND1, UDF_IND2, UDF_INDR,
UDF_SQLSTATE, UDF_NAME, UDF_SPEC_NAME,
UDF_DIAG_MSG, UDF_SCRATCHPAD,
UDF_CALL_TYPE, UDF_DBINFO)
OPTIONS(MAIN NOEXECOPS REENTRANT);
Related reference
CREATE FUNCTION (external scalar) (Db2 SQL)
Procedure
Compiling and link-editing your user-defined function as reentrant is recommended. (For an assembler
program, you must also code the user-defined function to be reentrant.)
Reentrant user-defined functions have the following advantages:
• The operating system does not need to load the user-defined function into storage every time the
user-defined function is called.
• Multiple tasks in a WLM-established stored procedures address space can share a single copy of the
user-defined function. This decreases the amount of virtual storage that is needed for code in the
address space.
If your user-defined function consists of several programs, you must bind each program that contains
SQL statements into a separate package. The definer of the user-defined function must have EXECUTE
authority for all packages that are part of the user-defined function.
When the primary program of a user-defined function calls another program, Db2 uses the CURRENT
PACKAGE PATH special register to determine the list of collections to search for the called program's
package. The primary program can change this collection ID by executing the statement SET CURRENT
PACKAGE PATH.
If the value of CURRENT PACKAGE PATH is blank or an empty string, Db2 uses the CURRENT
PACKAGESET special register to determine the collection to search for the called program's package.
The primary program can change this value by executing the statement SET CURRENT PACKAGESET.
If both special registers CURRENT PACKAGE PATH and CURRENT PACKAGESET contain a blank value,
Db2 uses the method described in “Binding an application plan” on page 871 to search for the package.
200 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 43. Characteristics of special registers in a user-defined function or a stored procedure (continued)
Special register Initial value when INHERIT Initial value when DEFAULT Routine can
SPECIAL REGISTERS option SPECIAL REGISTERS option use SET
is specified is specified statement to
modify?
CURRENT APPLICATION The value of bind option The value of bind option Yes
COMPATIBILITY APPLCOMPAT for the user- APPLCOMPAT for the user-
defined function or stored defined function or stored
procedure package procedure package
CURRENT APPLICATION The value of bind option The value of bind option Yes
ENCODING SCHEME ENCODING for the user- ENCODING for the user-
defined function or stored defined function or stored
procedure package procedure package
CURRENT CLIENT_ACCTNG Inherited from the invoking Inherited from the invoking Not
application application applicable5
CURRENT CLIENT_APPLNAME Inherited from the invoking Inherited from the invoking Not
application application applicable5
CURRENT CLIENT_USERID Inherited from the invoking Inherited from the invoking Not
application application applicable5
CURRENT Inherited from the invoking Inherited from the invoking Not
CLIENT_WRKSTNNAME application application applicable5
CURRENT DATE New value for each SQL New value for each SQL Not
statement in the user-defined statement in the user-defined applicable5
function or stored procedure function or stored procedure
package1 package1
CURRENT DEBUG MODE Inherited from the invoking DISALLOW Yes
application
CURRENT DECFLOAT Inherited from the invoking The value of bind option Yes
ROUNDING MODE application ROUNDING for the user-
defined function or stored
procedure package
CURRENT DEGREE CURRENT DEGREE2 The value of field CURRENT Yes
DEGREE on installation panel
DSNTIP8
CURRENT EXPLAIN MODE Inherited from the invoking NO Yes
application
CURRENT Inherited from the invoking The GETACCELARCHIVE bind Yes
GET_ACCEL_ARCHIVE application6; otherwise, the option value if specified for
subsystem parameter value the user-defined function or
will be used stored procedure package;
otherwise, the subsystem
parameter value will be used
CURRENT LOCALE LC_CTYPE Inherited from the invoking The value of field CURRENT Yes
application LC_CTYPE on installation panel
DSNTIPF
CURRENT MAINTAINED TABLE Inherited from the invoking System default value Yes
TYPES FOR OPTIMIZATION application
202 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 43. Characteristics of special registers in a user-defined function or a stored procedure (continued)
Special register Initial value when INHERIT Initial value when DEFAULT Routine can
SPECIAL REGISTERS option SPECIAL REGISTERS option use SET
is specified is specified statement to
modify?
CURRENT SCHEMA Inherited from the invoking The value of CURRENT Yes
application SCHEMA when the routine is
entered
CURRENT SERVER Inherited from the invoking Inherited from the invoking Yes
application application
CURRENT SQLID The primary authorization ID The primary authorization ID Yes8
of the application process or of the application process
inherited from the invoking
application7
CURRENT TEMPORAL Inherited from the invoking NULL Yes
BUSINESS_TIME application
CURRENT TEMPORAL Inherited from the invoking NULL Yes
SYSTEM_TIME application
CURRENT TIME New value for each SQL New value for each SQL Not
statement in the user-defined statement in the user-defined applicable5
function or stored procedure function or stored procedure
package1 package1
CURRENT TIMESTAMP New value for each SQL New value for each SQL Not
statement in the user-defined statement in the user-defined applicable5
function or stored procedure function or stored procedure
package1 package1
CURRENT TIMESTAMP WITH New value for each SQL New value for each SQL Not
TIME ZONE statement in the user-defined statement in the user-defined applicable5
function or stored procedure function or stored procedure
package1 package1
CURRENT TIME ZONE Inherited from the invoking Inherited from the invoking Not
application application applicable5
ENCRYPTION PASSWORD Inherited from the invoking Inherited from the invoking Yes
application application
SESSION TIME ZONE Inherited from the invoking The value of CURRENT TIME Yes
application ZONE when the routine is
entered
SESSION_USER or USER Primary authorization ID of the Primary authorization ID of the Not
application process application process applicable5
Notes:
1. If the user-defined function or stored procedure is invoked within the scope of a trigger, Db2 uses the
timestamp for the triggering SQL statement as the timestamp for all SQL statements in the package.
2. Db2 allows parallelism at only one level of a nested SQL statement. If you set the value of the CURRENT
DEGREE special register to ANY, and parallelism is disabled, Db2 ignores the CURRENT DEGREE value.
3. If the routine definition includes a specification for COLLID, Db2 sets CURRENT PACKAGESET to the value
of COLLID. If both CURRENT PACKAGE PATH and COLLID are specified, the CURRENT PACKAGE PATH value
takes precedence and COLLID is ignored.
4. If the function definition includes a specification for PACKAGE PATH, Db2 sets CURRENT PACKAGE PATH to
the value of PACKAGE PATH.
5. Not applicable because no SET statement exists for the special register.
6. If a program within the scope of the invoking program issues a SET statement for the special register before
the user-defined function or stored procedure is invoked, the special register inherits the value from the
SET statement. Otherwise, the special register contains the value that is set by the bind option for the
user-defined function or stored procedure package.
7. If a program within the scope of the invoking program issues a SET CURRENT SQLID statement before the
user-defined function or stored procedure is invoked, the special register inherits the value from the SET
statement. Otherwise, CURRENT SQLID contains the authorization ID of the application process.
8. If the user-defined function or stored procedure package uses a value other than RUN for the
DYNAMICRULES bind option, the SET CURRENT SQLID statement can be executed. However, it does not
affect the authorization ID that is used for the dynamic SQL statements in the package. The DYNAMICRULES
value determines the authorization ID that is used for dynamic SQL statements.
Related concepts
Dynamic rules options for dynamic SQL statements
The DYNAMICRULES bind option and the runtime environment determine the rules for the dynamic SQL
attributes.
Related reference
BIND and REBIND options for packages, plans, and services (Db2 Commands)
Special registers (Db2 SQL)
204 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Procedure
To access transition tables in a user-defined function or stored procedure:
1. Declare input parameters to receive table locators. You must define each parameter that receives a
table locator as an unsigned 4-byte integer.
2. Declare table locators. You can declare table locators in assembler, C, C++, COBOL, PL/I, and in an SQL
procedure compound statement.
3. Declare a cursor to access the rows in each transition table.
4. Assign the input parameter values to the table locators.
5. Access rows from the transition tables using the cursors that are declared for the transition tables.
Results
The following examples show how a user-defined function that is written in C, C++, COBOL, or PL/I
accesses a transition table for a trigger. The transition table, NEWEMP, contains modified rows of the
employee sample table. The trigger is defined like this:
Assembler: The following example shows how an assembler program accesses rows of transition table
NEWEMPS.
CHECKEMP CSECT
SAVE (14,12) ANY SAVE SEQUENCE
LR R12,R15 CODE ADDRESSABILITY
USING CHECKEMP,R12 TELL THE ASSEMBLER
LR R7,R1 SAVE THE PARM POINTER
USING PARMAREA,R7 SET ADDRESSABILITY FOR PARMS
USING SQLDSECT,R8 ESTABLISH ADDRESSIBILITY TO SQLDSECT
L R6,PROGSIZE GET SPACE FOR USER PROGRAM
GETMAIN R,LV=(6) GET STORAGE FOR PROGRAM VARIABLES
LR R10,R1 POINT TO THE ACQUIRED STORAGE
LR R2,R10 POINT TO THE FIELD
LR R3,R6 GET ITS LENGTH
SR R4,R4 CLEAR THE INPUT ADDRESS
SR R5,R5 CLEAR THE INPUT LENGTH
MVCL R2,R4 CLEAR OUT THE FIELD
ST R13,FOUR(R10) CHAIN THE SAVEAREA PTRS
ST R10,EIGHT(R13) CHAIN SAVEAREA FORWARD
LR R13,R10 POINT TO THE SAVEAREA
USING PROGAREA,R13 SET ADDRESSABILITY
ST R6,GETLENTH SAVE THE LENGTH OF THE GETMAIN
⋮
************************************************************
* Declare table locator host variable TRIGTBL *
************************************************************
TRIGTBL SQL TYPE IS TABLE LIKE EMP AS LOCATOR
************************************************************
* Declare a cursor to retrieve rows from the transition *
* table *
************************************************************
EXEC SQL DECLARE C1 CURSOR FOR X
SELECT LASTNAME FROM TABLE(:TRIGTBL LIKE EMP) X
WHERE SALARY > 100000
************************************************************
* Copy table locator for trigger transition table *
************************************************************
C or C++: The following example shows how a C or C++ program accesses rows of transition table
NEWEMPS.
COBOL: The following example shows how a COBOL program accesses rows of transition table
NEWEMPS.
IDENTIFICATION DIVISION.
PROGRAM-ID. CHECKEMP.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 NAME PIC X(24).
⋮
LINKAGE SECTION.
*********************************************************
* Declare table locator host variable TRIG-TBL-ID *
*********************************************************
01 TRIG-TBL-ID SQL TYPE IS TABLE LIKE EMP AS LOCATOR.
⋮
PROCEDURE DIVISION USING TRIG-TBL-ID.
⋮
*********************************************************
* Declare cursor to retrieve rows from transition table *
*********************************************************
EXEC SQL DECLARE C1 CURSOR FOR
SELECT NAME FROM TABLE(:TRIG-TBL-ID LIKE EMP)
WHERE SALARY > 100000 END-EXEC.
*********************************************************
* Fetch a row from transition table *
*********************************************************
206 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
EXEC SQL OPEN C1 END-EXEC.
EXEC SQL FETCH C1 INTO :NAME END-EXEC.
⋮
EXEC SQL CLOSE C1 END-EXEC.
⋮
PROG-END.
GOBACK.
PL/I: The following example shows how a PL/I program accesses rows of transition table NEWEMPS.
Procedure
To prepare an external user-defined function for execution:
1. Precompile the user-defined function program and bind the DBRM into a package. You need to do this
only if your user-defined function contains SQL statements. You do not need to bind a plan for the
user-defined function.
2. Compile the user-defined function program and link-edit it with Language Environment and RRSAF.
You must compile the program with a compiler that supports Language Environment and link-edit
the appropriate Language Environment components with the user-defined function. You must also
link-edit the user-defined function with RRSAF.
The program preparation JCL samples DSNHASM, DSNHC, DSNHCPP, DSNHICOB, and DSNHPLI show
you how to precompile, compile, and link-edit assembler, C, C++, COBOL, and PL/I Db2 programs. For
object-oriented programs in C++, see JCL sample DSNHCPP2 for program preparation hints.
3. For a user-defined function that contains SQL statements, grant EXECUTE authority on the user-
defined function package to the function definer.
The scratchpad length is not specified, so the scratchpad has the default length of 100 bytes, plus 4 bytes
for the length field. The user-defined function increments an integer value and stores it in the scratchpad
on each execution.
#pragma linkage(ctr,fetchable)
#include <stdlib.h>
#include <stdio.h>
/* Structure scr defines the passed scratchpad for function ctr */
struct scr {
long len;
long countr;
char not_used[96];
};
/***************************************************************/
/* Function ctr: Increments a counter and reports the value */
/* from the scratchpad. */
/* */
/* Input: None */
/* Output: INTEGER out the value from the scratchpad */
/***************************************************************/
void ctr(
long *out, /* Output answer (counter) */
short *outnull, /* Output null indicator */
char *sqlstate, /* SQLSTATE */
char *funcname, /* Function name */
char *specname, /* Specific function name */
208 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
char *mesgtext, /* Message text insert */
struct scr *scratchptr) /* Scratchpad */
{
*out = ++scratchptr->countr; /* Increment counter and */
/* copy to output variable */
*outnull = 0; /* Set output null indicator*/
return;
}
/* end of user-defined function ctr */
UPDATE EMP
SET BONUS = CALC_BONUS(SALARY,COMM);
Notes:
1. This version of ALTDATE has one input parameter, of type VARCHAR(13).
2. This version of ALTDATE has three input parameters, of type VARCHAR(17), VARCHAR(13), and
VARCHAR(13).
3. This version of ALTTIME has one input parameter, of type VARCHAR(14).
4. This version of ALTTIME has three input parameters, of type VARCHAR(11), VARCHAR(14), and
VARCHAR(14).
Member DSN8DUWC contains a client program that shows you how to invoke the WEATHER user-defined
table function.
Member DSNTEJBI shows you how to define and prepare the IBM InfoSphere BigInsights sample user-
defined functions.
Member DSNTEJ2U shows you how to define and prepare the other sample user-defined functions and
the client program.
210 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Related concepts
Job DSNTEJBI (Db2 Installation and Migration)
Job DSNTEJ2U (Db2 Installation and Migration)
Sample user-defined functions (Db2 SQL)
Procedure
Follow the process for the type of stored procedure that you want to create, and issue a CREATE
PROCEDURE statement to register the stored procedure with a database server.
You can create the following types of stored procedures:
Native SQL procedures
The procedure body is written exclusively in SQL statements, including SQL procedural language (SQL
PL) statements. The procedure body is contained and specified in the procedure definition along with
various attributes of the procedure. A package is generated for a native SQL procedure. It contains the
procedure body, including control statements. It might sometimes also include statements generated
by Db2. Each time that the procedure is invoked, the package executes one or more times.
All SQL procedures that are created with a CREATE PROCEDURE statement that does not specify
the FENCED or EXTERNAL options are native SQL procedures. More capabilities are supported for
native SQL procedures, they usually perform better than external SQL procedures, and no associated
C program is generated for them.
For more information, see “Creating native SQL procedures” on page 226.
External stored procedures
The procedure body is an external program that is written in a programming language such as C,
C++, COBOL, or Java and it can contain SQL statements. The source code for an external stored
procedure is separate from the procedure definition and is bound into a package. The name of the
external executable is specified as part of the procedure definition along with various attributes of
the procedure. All programs must be designed to run using Language Environment. Your COBOL and
C++ stored procedures can contain object-oriented extensions. Each time that the stored procedure is
invoked, the logic in the procedure controls whether the package executes and how many times.
For more information, see “Creating external stored procedures” on page 252.
Related concepts
Stored procedures
A stored procedure is a compiled program that can execute SQL statements and is stored at a local or
remote Db2 server. You can invoke a stored procedure from an application program or from the command
line processor. A single call to a stored procedure from a client application can access the database at the
server several times.
External stored procedures
An external stored procedure is a procedure that is written in a host language and can contain SQL
statements. The source code for external procedures is separate from the definition.
SQL procedures
An SQL procedure is a stored procedure that contains only SQL statements.
Related tasks
Obfuscating source code of SQL procedures, SQL functions, and triggers (Db2 Administration Guide)
Related reference
CREATE PROCEDURE (Db2 SQL)
Db2 for z/OS Exchange
Related information
Db2 for z/OS Stored Procedures: Through the CALL and Beyond (IBM Redbooks)
Stored procedures
A stored procedure is a compiled program that can execute SQL statements and is stored at a local or
remote Db2 server. You can invoke a stored procedure from an application program or from the command
line processor. A single call to a stored procedure from a client application can access the database at the
server several times.
A typical stored procedure contains two or more SQL statements and some manipulative or logical
processing in a host language or SQL procedure statements. You can call stored procedures from other
applications or from the command line. Db2 provides some stored procedures, but you can also create
your own.
A stored procedure provides a common piece of code that is written only once and is maintained in
a single instance that can be called from several different applications. Host languages can easily call
procedures that exist on a local system, and SQL can call stored procedures that exist on remote systems.
In fact, a major benefit of procedures in SQL is that they can be used to enhance the performance
characteristics of distributed applications. With stored procedures, you can avoid network transfer of
large amounts of data obtained as part of intermediate results in a long sequence of queries.
The following diagram illustrates the processing for an application that does not use stored procedures.
The client application embeds SQL statements and communicates with the server separately for each
statement. This application design results in increased network traffic and processor costs.
212 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Client Db2 for z/OS
EXEC SQL SELECT …
Perform SQL processing
The following diagram illustrates the processing for an application that uses stored procedures. Because a
stored procedure is used on the server, a series of SQL statements can be executed with a single send and
receive operation, reducing network traffic and the cost of processing these statements.
z/OS system
Db2 stored
Client EXEC SQL Db2 procedures region
CALL PROCX
Schedule PROCX EXEC SQL
DECLARE C1...
EXEC SQL
Perform SQL OPEN C1...
OPEN
EXEC SQL
Perform SQL UPDATE...
UPDATE
EXEC SQL
Perform SQL INSERT...
INSERT
Return values PROCX end
and result set
to client
Stored procedures are useful for client/server applications that do at least one of the following things:
• Execute multiple remote SQL statements. Remote SQL statements can create many network send and
receive operations, which results in increased processor costs. Stored procedures can encapsulate
many of your application's SQL statements into a single message to the Db2 server, reducing network
traffic to a single send and receive operation for a series of SQL statements. Locks on Db2 tables are not
held across network transmissions, which reduces contention for resources at the server.
• Access tables from a dynamic SQL environment where table privileges for the application that is running
are undesirable. Stored procedures allow static SQL authorization from a dynamic environment.
• Access host variables for which you want to guarantee security and integrity. Stored procedures
remove SQL applications from the workstation, which prevents workstation users from manipulating
the contents of sensitive SQL statements and host variables.
• Create a result set of rows to return to the client application.
Stored procedures that are written in embedded static SQL provide the following additional advantages:
• Better performance because static SQL is prepared at precompile time and has no run time overhead for
access plan (package) generation.
• Encapsulation enables programmers to write applications that access data without knowing the details
of database objects.
• Improved security because access privileges are encapsulated within the packages that are associated
with the stored procedures. You can grant access to run a stored procedure that selects data from
tables, without granting SELECT privilege to the user.
214 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
OUT
Output-only parameters, which return values from the stored procedure to the calling program.
INOUT
Input and output parameters, which provide values to and return values from the stored procedure.
If a stored procedure fails to set one or more of the OUT or INOUT parameters, Db2 does not return
an error. Instead, Db2 returns the output parameters to the calling program, with the values that were
established on entry to the stored procedure.
Within a procedure body, the following rules apply to IN, OUT, and INOUT parameters:
• You can use a parameter that you define as IN on the left side or right side of an assignment statement.
However, if you assign a value to an IN parameter, you cannot pass the new value back to the caller. The
IN parameter has the same value before and after the SQL procedure is called.
• You can use a parameter that you define as OUT on the left side or right side of an assignment
statement. The last value that you assign to the parameter is the value that is returned to the caller. The
starting value of an OUT parameter is NULL.
• You can use a parameter that you define as INOUT on the left side or right side of an assignment
statement. The caller determines the first value of the INOUT parameter, and the last value that you
assign to the parameter is the value that is returned to the caller.
Restrictions:
• You cannot pass file reference variables as stored procedure parameters.
• You cannot pass parameters with the type XML to stored procedures. You can specify tables or views
that contain XML columns as table locator parameters. However, you cannot reference the XML columns
in the body of the stored procedure.
Related tasks
Calling a stored procedure from your application
To run a stored procedure, you can either call it from a client program or invoke it from the command line
processor.
Passing large output parameters to stored procedures by using indicator variables
If any output parameters occupy a large amount of storage, passing the entire storage area to a stored
procedure can degrade performance.
Related reference
CALL (Db2 SQL)
CREATE PROCEDURE (Db2 SQL)
8 Control returns
to application
9 EXEC SQL
COMMIT; Result of
(or ROLLBACK) COMMIT or
ROLLBACK
216 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Notes:
1. The workstation application uses the SQL CONNECT statement to create a conversation with Db2.
2. Db2 creates a Db2 thread to process SQL requests.
3. The SQL statement CALL tells the Db2 server that the application is going to run a stored procedure.
The calling application provides the necessary parameters.
4. The plan for the client application contains information from catalog table SYSIBM.SYSROUTINES
about stored procedure A.
5. Db2 passes information about the request to the stored procedures address space, and the stored
procedure begins execution.
6. The stored procedure executes SQL statements.
Db2 verifies that the owner of the package or plan containing the SQL statement CALL has EXECUTE
authority for the package associated with the Db2 stored procedure.
One of the SQL statements opens a cursor that has been declared WITH RETURN. This causes a
result set to be returned to the workstation application when the procedure ends.
Any SQLCODE that is issued within an external stored procedure is not returned to the workstation
application in the SQLCA (as the result of the CALL statement).
7. If an error is not encountered, the stored procedure assigns values to the output parameters and
exits.
Control returns to the Db2 stored procedures address space, and from there to the Db2 system. If the
stored procedure definition contains COMMIT ON RETURN NO, Db2 does not commit or roll back any
changes from the SQL in the stored procedure until the calling program executes an explicit COMMIT
or ROLLBACK statement. If the stored procedure definition contains COMMIT ON RETURN YES,
and the stored procedure executed successfully, Db2 commits all changes. The COMMIT statement
closes the cursor unless it is declared with the WITH HOLD option.
8. Control returns to the calling application, which receives the output parameters and the result set.
Db2 then:
• Closes all cursors that the stored procedure opened, except those that the stored procedure
opened to return result sets.
• Discards all SQL statements that the stored procedure prepared.
• Reclaims the working storage that the stored procedure used.
The application can call more stored procedures, or it can execute more SQL statements. Db2
receives and processes the COMMIT or ROLLBACK request. The COMMIT or ROLLBACK operation
covers all SQL operations, whether executed by the application or by stored procedures, for that unit
of work.
If the application involves IMS or CICS, similar processing occurs based on the IMS or CICS sync
point rather than on an SQL COMMIT or ROLLBACK statement.
9. Db2 returns a reply message to the application describing the outcome of the COMMIT or ROLLBACK
operation.
10. The workstation application executes the following steps to retrieve the contents of table
EMPPROJACT, which the stored procedure has returned in a result set:
a. Declares a result set locator for the result set being returned.
b. Executes the ASSOCIATE LOCATORS statement to associate the result set locator with the result
set.
c. Executes the ALLOCATE CURSOR statement to associate a cursor with the result set.
d. Executes the FETCH statement with the allocated cursor multiple times to retrieve the rows in the
result set.
e. Executes the CLOSE statement to close the cursor.
218 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
All SQL procedures that are created without the FENCED or EXTERNAL options in the CREATE
PROCEDURE statement are native SQL procedures.
Examples
The following examples show how to determine whether an SQL statement is allowed in an SQL
procedure.
The syntax diagrams for the control statements indicate where semicolons are needed in an SQL
procedure. If the procedure contains a single statement that is not a control statement, such as Example
1, then no semicolons are in the CREATE PROCEDURE statement. If the procedure consists of multiple
statements, such as Example 2, use semicolons to separate SQL statements within the SQL procedure. Do
not put a semicolon after the outermost control statement.
Example 1
An SQL variable is defined in a compound statement. SQL variables can be referenced anywhere in the
compound statement in which they are declared, including any SQL statement that is directly or indirectly
nested within that compound statement. For more information, see References to SQL parameters and
variables (Db2 SQL).
220 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
You can perform any operations on SQL variables that you can perform on host variables in SQL
statements.
Related concepts
Host variables
Use host variables to pass a single data item between Db2 and your application.
Using host variables in SQL statements
Use scalar host variables in embedded SQL statements to represent a single value. Host variables are
useful for storing retrieved data or for passing values that are to be assigned or used for comparisons.
Related tasks
Controlling the scope of variables in an SQL procedure
Use nested compound statements within an SQL procedure to define the scope of SQL variables. You
can reference the variable only within the compound statement in which it was declared and within any
nested statements.
Example: Compound statement with nested IF and WHILE statements: The following example shows a
compound statement that includes an IF statement, a WHILE statement, and assignment statements. The
example also shows how to declare SQL variables, cursors, and handlers for classes of error codes.
The procedure receives a department number as an input parameter. A WHILE statement in the
procedure body fetches the salary and bonus for each employee in the department, and uses an SQL
variable to calculate a running total of employee salaries for the department. An IF statement within the
WHILE statement tests for positive bonuses and increments an SQL variable that counts the number of
bonuses in the department. When all employee records in the department have been processed, a NOT
FOUND condition occurs. A NOT FOUND condition handler makes the search condition for the WHILE
statement false, so execution of the WHILE statement ends. Assignment statements then assign the total
employee salaries and the number of bonuses for the department to the output parameters for the stored
procedure.
If any SQL statement in the compound statement P1 receives an error, the SQLEXCEPTION handler
receives control. The handler action sets the output parameter DEPTSALARY to NULL. After the handler
action has completed successfully, the original error condition is resolved (SQLSTATE '00000', SQLCODE
Example: Compound statement with dynamic SQL statements: The following example shows a
compound statement that includes dynamic SQL statements.
The procedure receives a department number (P_DEPT) as an input parameter. In the compound
statement, three statement strings are built, prepared, and executed:
• The first statement string executes a DROP statement to ensure that the table to be created does not
already exist. The table name is the concatenation of the TABLE_PREFIX constant value, the P_DEPT
parameter value, and the TABLE_SUFFIX constant value.
• The next statement string executes a CREATE statement to create DEPT_deptno_T.
• The third statement string inserts rows for employees in department deptno into DEPT_deptno_T.
Just as statement strings that are prepared in host language programs cannot contain host variables,
statement strings in SQL procedures cannot contain SQL variables or stored procedure parameters.
Therefore, the third statement string contains a parameter marker that represents P_DEPT. When the
prepared statement is executed, parameter P_DEPT is substituted for the parameter marker.
222 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
EXECUTE S2;
SET STMT = 'INSERT INTO TABLE '||TABLE_NAME ||
'SELECT EMPNO, FIRSTNME, MIDINIT, LASTNAME, SALARY '||
'FROM EMPLOYEE '||
'WHERE WORKDEPT = ?';
PREPARE S3 FROM STMT;
EXECUTE S3 USING P_DEPT;
END
Autonomous procedures
Autonomous procedures execute under their own units of work, separate from the calling program, and
commit when they finish without committing the work of the calling program.
Autonomous procedures execute as separate units of work that are independent from the calling
application programs. Autonomous procedures follow the rules of the COMMIT ON RETURN YES option
for their changes before returning to the caller. However, their commit does not impact changes
completed by the calling application program. The calling application program controls when its own
updates are committed or rolled back.
If the calling application rolls back its own changes, the committed changes of the autonomous procedure
are not affected. Therefore, autonomous procedures are useful for logging information about error
conditions encountered by an application program. When the application encounters the error and rolls
back its own changes, the committed changes of the autonomous procedure remain available.
Autonomous procedures can be called by normal application programs, other stored procedures, user-
defined functions or triggers. Autonomous procedures can complete the following types of work:
• Execute SQL statements
• Invoke another procedure, function, or trigger, as long as the number of nested levels does not exceed
64, and the called procedure is not autonomous.
• Execute COMMIT and ROLLBACK statements that apply to the SQL operations executed by nested
processes within the autonomous procedure.
The following restrictions apply to autonomous procedures:
• Only native SQL procedures can be defined as autonomous.
• Autonomous procedures and nested procedure, triggers, and functions within autonomous procedures
cannot invoke other autonomous procedures.
• Autonomous procedures cannot see uncommitted changes from the calling application.
• When multiple versions of a procedure exist, all versions must be defined as autonomous.
• Autonomous procedures do not share locks with the calling application, meaning that the autonomous
procedure might timeouts because of lock contention with the calling application.
• Parallelism is disabled for autonomous procedures. All statements in an autonomous procedure and for
any nested levels within are run in sequential processing mode.
• DYNAMIC RESULT SETS 0 must be specified when autonomous procedures are used.
• Stored procedure parameters must not be defined as a LOB data type, or any distinct data type that is
based on a LOB or XML value.
Related tasks
Controlling autonomous procedures (Db2 Administration Guide)
Language requirements for the external stored procedure and its caller
You can write an external stored procedure in Assembler, C, C++, COBOL, Java, REXX, or PL/I. All
programs must be designed to run using Language Environment. Your COBOL and C++ stored procedures
can contain object-oriented extensions.
The program that calls the stored procedure can be in any language that supports the SQL CALL
statement. ODBC applications can use an escape clause to pass a stored procedure call to Db2.
Related concepts
Object-oriented extensions in COBOL
When you use object-oriented extensions in a COBOL application, you need to consider where to place
SQL statements, the SQLCA, the SQLDA, and host variable declarations. You also need to consider the
rules for host variables.
REXX stored procedures
A REXX stored procedure is similar to any other REXX procedure and follows the same rules as stored
procedures in other languages. A REXX stored procedure receives input parameters, executes REXX
commands, optionally executes SQL statements, and returns at most one output parameter. However, a
few differences exist.
Java stored procedures and user-defined functions (Db2 Application Programming for Java)
Examples
Creating a native SQL procedure
The following example shows a definition for an SQL procedure.
224 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
SET SALARY = SALARY * RATE
WHERE EMPNO = EMPNUMBR
Notes:
1
The stored procedure name is UPDATESALARY1.
2
The two parameters have data types of CHAR(10) and DECIMAL(6,2). Both are input parameters.
3
LANGUAGE SQL indicates that this is an SQL procedure, so a procedure body follows the other
parameters.
4
The procedure body consists of a single SQL UPDATE statement, which updates rows in the
employee table.
Creating an external stored procedure
The following example shows a definition for an equivalent external stored procedure that is written in
COBOL. The stored procedure program, which updates employee salaries, is called UPDSAL.
Notes:
1
The stored procedure name is UPDATESALARY1.
2
The two parameters have data types of CHAR(10) and DECIMAL(6,2). Both are input parameters.
3
LANGUAGE COBOL indicates that this is an external procedure, so the code for the stored
procedure is in a separate, COBOL program.
4
The name of the load module that contains the executable stored procedure program is UPDSAL.
Related reference
CREATE PROCEDURE (Db2 SQL)
CREATE PROCEDURE (external) (Db2 SQL)
CREATE PROCEDURE (SQL - native) (Db2 SQL)
226 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
statements that are bound in a Db2 package. Native SQL procedures do not have an associated external
application program. Native SQL procedures are more fully supported, easier to maintain, and typically
perform better than external SQL procedures, which are deprecated.
Procedure
To create a native SQL procedure, perform one of the following actions:
• Use a tool such as Db2 Developer Extension to specify the source statements for the SQL procedure
and deploy the SQL procedure to Db2. For more information, see IBM Db2 for z/OS Developer
Extension for Visual Studio Code.
• Use IBM Data Studio to specify the source statements for the SQL procedure and deploy the SQL
procedure to Db2.
IBM Data Studio also allows you to create copies of the procedure package as needed and to deploy
the procedure to remote servers.
• Manually deploy the native SQL procedure by completing the following steps:
a) Issue the CREATE PROCEDURE statement:
– Include a procedure body written entirely in the SQL procedural language (SQL PL). For more
information about what you can do within the procedure body, see SQL-routine-body in CREATE
PROCEDURE (SQL - native) (Db2 SQL), SQL-control-statement in SQL procedural language (SQL
PL) (Db2 SQL), and the following information:
- “Controlling the scope of variables in an SQL procedure” on page 228
- “Declaring cursors in an SQL procedure with nested compound statements” on page 231
- “Handling SQL conditions in an SQL procedure” on page 232
- “Raising a condition within an SQL procedure by using the SIGNAL or RESIGNAL statements”
on page 241
– Do not include the FENCED or EXTERNAL keywords, which specify the creation of an external
SQL procedures, which are deprecated.
– You can specify the AUTONOMOUS keyword to enable the procedure to commit without
committing the work of the calling application. Autonomous procedures cannot see uncommitted
changes of the calling application, and they cannot call other autonomous procedures.
When you issue this CREATE PROCEDURE statement, the first version of this procedure is defined
to Db2, and a package is implicitly bound with the options that you specify on the CREATE
PROCEDURE statement.
b) If the native SQL procedure contains one or more of the following statements or references, make
copies of the native SQL procedure package, as needed:
– CONNECT
– SET CURRENT PACKAGESET
– SET CURRENT PACKAGE PATH
– A table reference with a three-part name that refers to a location other than the current server or
refers to an alias that resolves to such a name.
c) If you plan to call the native SQL procedure at another Db2 server, deploy the procedure to another
Db2 for z/OS server. You can customize the bind options at the same time.
d) Authorize the appropriate users to call the stored procedure.
What to do next
After you create a native SQL procedure, you can create additional versions of the procedure as needed.
For more information, see “Creating new versions of native SQL procedures” on page 246.
Related concepts
SQL procedures
Procedure
To control the scope of a variable in an SQL procedure:
1. Declare the variable within the compound statement in which you want to reference it. Ensure that the
variable name is unique within the compound statement, not including any nested statements. You can
define variables with the same name in other compound statements in the same SQL procedure.
2. Reference the variable within that compound statement or any nested statements.
Recommendation: If multiple variables with the same name exist within an SQL procedure, qualify the
variable with the label from the compound statement in which it was declared. Otherwise, you might
accidentally reference the wrong variable.
If the variable name is unqualified and multiple variables with that name exist within the same scope,
Db2 uses the variable in the innermost compound statement.
Example
The following example contains three declarations of the variable A. One instance is declared in the
outer compound statement, which has the label OUTER1. The other instances are declared in the inner
compound statements with the labels INNER1 and INNER2. In the INNER1 compound statement, Db2
presumes that the unqualified references to A in the assignment statement and UPDATE statement refer
to the instance of A that is declared in the INNER1 compound statement. To refer to the instance of A that
is declared in the OUTER1 compound statement, qualify the variable as OUTER1.A.
CREATE PROCEDURE P2 ()
LANGUAGE SQL
SET A = A + OUTER1.A; 3
228 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
INNER2: BEGIN 8
DECLARE A INT DEFAULT NULL;
DECLARE Z INT DEFAULT NULL;
SET A = A + OUTER1.A;
END INNER2; 9
-- End of inner compound statement INNER2 ------
END OUTER1 11
CREATE PROCEDURE...
OUTERMOST: BEGIN
...
INNER1: BEGIN
...
INNERMOST: BEGIN
...
...
END INNERMOST;
END INNER1;
INNER2: BEGIN
...
...
END INNER2;
END OUTERMOST
CREATE PROCEDURE P1 ()
LANGUAGE SQL
END INNER1;
--End of inner compound statement INNER1 ------
END OUTER1 7
230 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
5. The beginning of an inner compound statement that is labeled INNER2.
6. A statement that is defined with the label XYZ. This label is acceptable even though another statement
in this procedure has the same label, because the two labels are in different scopes. Neither label is
contained within the scope of the other.
7. The end of the outermost compound statement that is labeled OUTER1.
The following examples show valid and invalid uses of labels:
Invalid example of labels:
L1: BEGIN
L2: SET A = B;
L1: GOTO L2: --This duplicate use of the label L1 causes an error, because
--the same label is already used in the same scope.
END L1;
L1: BEGIN
L2: BEGIN
L4: BEGIN --This line contains the first use of the label L4
DECLARE A CHAR(5);
SET A = B;
END L4;
END L2;
L3: BEGIN
L4: BEGIN --This second use of the label L4 is valid, because
--it is used in a different scope.
DECLARE A CHAR(5);
SET A = B;
END L4;
END L3;
END L1;
Procedure
Specify the DECLARE CURSOR statement within the compound statement in which you want to reference
the cursor. Use a cursor name that is unique within the SQL procedure.
You can reference the cursor within the compound statement in which it is declared and within any nested
statements. If the cursor is declared as a result set cursor, even if the cursor is not declared in the
outermost compound statement, any calling application can reference it.
Example
In the following example, cursor X is declared in the outer compound statement. This cursor can be
referenced within the outer block in which it was declared and within any nested compound statements.
SUB: BEGIN
OPEN X; --references X in outer block
FETCH X INTO I,J; --references X in outer block
SET IR1 = I;
Related reference
CREATE PROCEDURE (SQL - native) (Db2 SQL)
DECLARE CURSOR (Db2 SQL)
Procedure
To handle SQL conditions, use one of the following techniques:
• Include statements called handlers to tell the procedure to perform some other action when an error
or warning occurs.
• Include a RETURN statement in an SQL procedure to return an integer status value to the caller.
• Include a SIGNAL statement or a RESIGNAL statement to raise a specific SQLSTATE and to define the
message text for that SQLSTATE.
• Force a negative SQLCODE to be returned by a procedure if a trigger calls the procedure.
In general, the way that a handler works is that when an error occurs that matches condition, the
SQL-procedure-statement executes. When the SQL-procedure-statement completes, Db2 performs the
action that is indicated by handler-type.
Types of handlers
The handler type determines what happens after the completion of the SQL-procedure-statement. You can
declare the handler type to be either CONTINUE or EXIT:
CONTINUE
Specifies that after SQL-procedure-statement completes, execution continues with the statement after
the statement that caused the error.
EXIT
Specifies that after SQL-procedure-statement completes, execution continues at the end of the
compound statement that contains the handler.
232 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Example: CONTINUE handler: This handler sets flag at_end when no more rows satisfy a query. The
handler then causes execution to continue after the statement that returned no rows.
Example: EXIT handler: This handler places the string 'Table does not exist' into output parameter
OUT_BUFFER when condition NO_TABLE occurs. NO_TABLE is previously declared as SQLSTATE 42704
(name is an undefined name). The handler then causes the SQL procedure to exit the compound
statement in which the handler is declared.
Procedure
To define a condition handler that executes more than one statement when the specified condition
occurs, specify a compound statement within the declaration of that handler.
Examples
Example
The following example shows a condition handler that captures the SQLSTATE value and sets a local
flag to TRUE.
BEGIN
DECLARE SQLSTATE CHAR(5);
DECLARE PrvSQLState CHAR(5) DEFAULT '00000';
DECLARE ExceptState INT;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
BEGIN
SET PrvSQLState = SQLSTATE;
SET ExceptState = TRUE;
END;
...
END
Example
The following example declares a condition handler for SQLSTATE 72822. The subsequent SIGNAL
statement is within the scope of this condition handler and thus activates this handler. The condition
handler tests the value of the SQL variable VAR with an IF statement. Depending on the value of VAR,
the SQLSTATE is changed and the message text is set.
Related reference
compound-statement (Db2 SQL)
Procedure
To control how errors are handled within different scopes in an SQL procedure:
1. Optional: Declare a condition by specifying a DECLARE CONDITION statement within the compound
statement in which you want to reference it. You can reference a condition in the declaration of a
condition handler, a SIGNAL statement, or a RESIGNAL statement.
Restriction: If multiple conditions with that name exist within the same scope, you cannot explicitly
refer to a condition that is not the most local in scope. Db2 uses the condition in the innermost
compound statement.
2. Declare a condition handler by specifying a DECLARE HANDLER statement within the compound
statement to which you want the condition handler to apply. Within the declaration of the condition
handler, you can specify a previously defined condition.
Restriction: Condition handlers that are declared in the same compound statement cannot handle
conditions encountered in each other or themselves.
Examples
Example
In the following example, a condition with the name ABC is declared twice, and a condition named
XYZ is declared once.
CREATE PROCEDURE...
DECLARE ABC CONDITION...
SIGNAL ABC; 2
DECLARE EXIT HANDLER FOR GORP --defines a condition handler for SQLSTATE 33333
L2: BEGIN
DECLARE FOO CONDITION
FOR SQLSTATE '12345'; --defines a condition with the name FOO for SQLSTATE 12345
DECLARE CONTINUE HANDLER FOR FOO --defines a condition handler for SQLSTATE 12345
L3: BEGIN
SET A = 'A';
...more statements...
END L3;
SET B = 'B';
IF...
SIGNAL FOO; --raises SQLSTATE 12345
ELSEIF
234 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
SIGNAL GORP; --raises SQLSTATE 33333
END IF;
END L2;
L4: BEGIN
DECLARE FOO CONDITION
FOR SQLSTATE '54321' --defines a condition with the name FOO for SQLSTATE 54321
DECLARE EXIT HANDLER FOR FOO...; --defines a condition handler for SQLSTATE 54321
L5: BEGIN
DECLARE FOO CONDITION
FOR SQLSTATE '99999'; --defines a condition with the name FOO for SQLSTATE 99999
...more statements...
END L5;
END L4;
--At this point, the procedure cannot reference FOO, because this condition is not defined
--in this outer scope
END L1
Example
In the following example, the compound statement with the label OUTER contains two other
compound statements: INNER1A and INNER1B. The INNER1A compound statement contains
another compound statement, which has the label INNER1A2, and the declaration for a condition
handler HINNER1A. The body of the condition handler HINNER1A contains another compound
statement, which defines another condition handler, HINNER1A_HANDLER.
OUTER:
BEGIN <=============.
-- Handler for OUTER |
DECLARE ... HANDLER -- HOUTER |
BEGIN <---. |
: | |
END; -- End of handler <---. |
: |
: |
|
-- Level 1 - first compound statement |
INNER1A: |
BEGIN <---------. |
-- Handler for INNER1A | |
DECLARE ... HANDLER -- HINNER1A | |
BEGIN <------. | |
-- Handler for handler HINNER1A | |
DECLARE...HANDLER --HINNER1A_HANDLER| | |
BEGIN <---. | | |
: | | | |
END; -- End of handler <---. | | |
: | | |
: -- stmt that gets condition | | | 2
: | | |
: -- more statements in handler | | |
END; -- End of HINNER1A handler<------. | |
| |
INNER1A2: | |
BEGIN <--. | |
DECLARE ... HANDLER...-- HINNER1A2 | | |
BEGIN; <---. | | |
: | | | |
END; -- End of handler <---. | | |
: | | |
: -- statement that gets condition | | | 1
: | | |
: -- statement after statement | | |
: -- that encountered condition | | |
END INNER1A2; <--' | |
: | |
: -- statements in INNER1A | |
END INNER1A; <---------' |
|
-- Level 1 - second compound statement |
INNER1B: |
BEGIN <---------. |
-- Handler for handler INNER1B | |
BEGIN
DECLARE EXIT HANDLER FOR NOT FOUND
SET OUT_OF_DATA_FLAG = ON;
statement1...
statement2... --assume that this statement results in a NOT FOUND condition
statement3...
END;
statement4
...
236 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Example
In the following example, Db2 checks for SQLSTATE 22H11 only for statements inside the INNER
compound statement. Db2 checks for SQLEXCEPTION for all statements in both the OUTER and
INNER blocks.
OUTER: BEGIN
DECLARE var1 INT;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
RETURN -3;
INNER: BEGIN
DECLARE EXIT HANDLER FOR SQLSTATE '22H11'
RETURN -1;
DECLARE C1 CURSOR FOR SELECT col1 FROM table1;
OPEN C1;
CLOSE C1;
:
: -- more statements
END INNER;
:
: -- more statements
Example
In the following example, Db2 checks for SQLSTATE 42704 only for statements inside the A
compound statement.
A: BEGIN 1
DECLARE EXIT HANDLER FOR NO_TABLE 3
BEGIN
SET OUT_BUFFER ='Table does not exist'; 4
END;
The following notes describe a possible flow for the preceding example:
1. A nested compound statement with label A confines the scope of the NO_TABLE exit handler to the
statements that are specified in the A compound statement.
2. If the table JAVELIN does not exist, the DROP statement raises the NO_TABLE condition.
3. The exit handler for NO_TABLE is activated.
4. The variable OUT_BUFFER is set to the string 'Table does not exist.'
5. Execution continues with the INSERT statement. No more statements in the A compound
statement are processed.
Example
The following example illustrates the scope of different condition handlers.
INNER: BEGIN
DECLARE EXIT HANDLER FOR SQLSTATE VALUE '38H03'
RESIGNAL SQLSTATE VALUE '38HI3'
SET MESSAGE_TEXT = '38H03 MANAGED BY INNER ERROR HANDLER';
CASE PARAM
WHEN 1 THEN -- (1)
SIGNAL SQLSTATE VALUE '38H01'
SET MESSAGE_TEXT =
'EXAMPLE 1: ERROR SIGNALED FROM INNER COMPOUND STMT';
ELSE
SET I = 1; /*Do not do anything */
END CASE;
END INNER;
CASE PARAM
WHEN 5 THEN -- (5)
SIGNAL SQLSTATE VALUE '38H05'
SET MESSAGE_TEXT =
'EXAMPLE 5: ERROR SIGNALED FROM OUTER COMPOUND STMT';
WHEN 6 THEN -- (6)
SIGNAL SQLSTATE VALUE '38H06'
SET MESSAGE_TEXT =
'EXAMPLE 6: ERROR SIGNALED FROM OUTER COMPOUND STMT';
ELSE -- (7)
SET I = 1; /*Do not do anything */
END CASE;
END OUTER
Input
value
for
PARM Expected behavior
1 SQLSTATE 38H01 is signaled from the INNER compound statement. Because no
appropriate handler exists, the procedure terminates and returns the unhandled exception
condition, 38H01 with SQLCODE -438, to the calling application.
238 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Input
value
for
PARM Expected behavior
2 SQLSTATE 38H02 is signaled from the INNER compound statement. The condition handler
in the OUTER compound statement is activated. A RESIGNAL statement, with SQLSTATE
38HE0, is issued from within the body of the condition handler. This exception causes
control to be returned to the end of the OUTER compound statement with exception
condition 38HE0 and SQLCODE -438. The procedure terminates and returns the unhandled
condition to the calling application.
3 SQLSTATE 38H03 is signaled from the INNER compound statement. A condition handler
within the INNER compound statement is activated. A RESIGNAL statement, with
SQLSTATE 38HI3, is issued from within the body of the condition handler. Because no
appropriate handler exists, the procedure terminates and returns the unhandled exception
condition, 38HI3 with SQLCODE -438, to the calling application.
4 SQLSTATE 38H04 is signaled from the INNER compound statement. A condition handler
within the INNER compound statement is activated. A RESIGNAL statement, with
SQLSTATE 38HI4, is issued from within the body of the condition handler. A condition
handler in the OUTER compound statement is activated. A RESIGNAL statement, with
SQLSTATE 38HE0, is issued from within the body of the condition handler. This exception
causes control to be returned to the end of the OUTER compound statement with
exception condition 38HE0 and SQLCODE -438. The procedure terminates and returns
the unhandled condition to the calling application.
5 SQLSTATE 38H05 is signaled from the OUTER compound statement. Because no
appropriate handler exists, the procedure terminates and returns the unhandled exception
condition, 38H05 with SQLCODE -438, to the calling application.
6 SQLSTATE 38H06 is signaled from the OUTER compound statement. A condition handler
in the OUTER compound statement is activated. A RESIGNAL statement, with SQLSTATE
38HE0, is issued from within the body of the condition handler. This exception causes
control to be returned to the end of the OUTER compound statement with exception
condition 38HE0 and SQLCODE -438. The procedure terminates and returns the unhandled
condition to the calling application.
7 The ELSE clause of the CASE statement executes and processes the SET statement. A
successful completion code is returned to the calling application.
Example
In the following example SQL procedure, the condition handler for exception1 is not within the scope
of the condition handler for exception0. If exception condition exception1 is raised in the body of the
condition handler for exception0, no appropriate handler exists, and the procedure terminates with an
unhandled exception.
OPEN CURSOR1;
END
Procedure
You can include a GET DIAGNOSTICS statement in a handler to retrieve error or warning information.
If you include GET DIAGNOSTICS, it must be the first statement that is specified in the handler.
Procedure
Declare a condition handler that contains an empty compound statement.
Example
The following example shows a condition handler that is declared as a way of ignoring a condition.
Assume that your SQL procedure inserts rows into a table that has a unique column. If the value to be
inserted for that column already exists in the table, the row is not inserted. However, in this case, you do
not want Db2 to notify the application about this condition, which is indicated by SQLSTATE 23505.
Related concepts
Handlers in an SQL procedure
240 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
If an error occurs when an SQL procedure executes, the procedure ends unless you include statements to
tell the procedure to perform some other action. These statements are called handlers.
Related reference
SQLSTATE values and common error codes (Db2 Codes)
RETURNED_SQLSTATE xxxxx
MESSAGE_TEXT 'this is my message'
1 MESSAGE_TEXT 'this is my
message'
2 MESSAGE_TEXT 'APPLICATION
RAISED ERROR WITH
DIAGNOSTIC TEXT: this is my
message'
Note:
In this example, the SIGNAL statement is in the handler. However, you can use the SIGNAL statement to
invoke a handler when a condition occurs that will result in an error.
Related concepts
Example of the RESIGNAL statement in a handler
242 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
You can use the RESIGNAL statement in an SQL procedure to assign a different value to the condition that
activated the handler. T
A3: BEGIN
DECLARE c1 INT DEFAULT 1;
DECLARE CONTINUE HANDLER
FOR SQLSTATE VALUE '01ABC'
BEGIN
SET RC = 1; 4
RESIGNAL SQLSTATE VALUE '01ABX' 5
SET MESSAGE_TEXT = 'get out of here';
SET RC = 2; 7
END;
END
244 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
is the collection ID. For the first copy that is created on a remote server, you can specify the same schema
qualifier. For other copies on that remote server, specify a different schema qualifier.
If you later change the native SQL procedure, you might need to explicitly rebind any local or remote
copies of the package that exist for that version of the procedure.
Examples
Example
Because the following native SQL procedure contains a CONNECT statement, you must create a copy
of the package at the target server, which in this case is at location SAN_JOSE. The subsequent
BIND command creates a copy of the package for version ABC of the procedure TEST.MYPROC. This
package is created at location SAN_JOSE and is used by Db2 when this procedure is executed.
Example
The following native SQL procedure sets the CURRENT PACKAGESET special register to ensure that
Db2 uses the package with the collection ID COLL2 for this version of the procedure. Consequently,
you must create such a package. The subsequent BIND command creates this package with collection
ID COLL2. This package is a copy of the package for version ABC of the procedure TEST.MYPROC. Db2
uses this package to process the SQL statements in this procedure.
Related tasks
Regenerating an existing version of a native SQL procedure
When you apply Db2 maintenance that changes how native SQL procedures are generated, you need
to regenerate any affected procedures. When you regenerate a version of a native SQL procedure, Db2
rebinds the associated package for that version of the procedure.
Replacing copies of a package for a version of a native SQL procedure
When you change a version of a native SQL procedure and the ALTER PROCEDURE REPLACE statement
contains certain options, you must replace any local or remote copies of the package that exist for that
version of the procedure.
Related reference
ALTER PROCEDURE (SQL - native) (Db2 SQL)
246 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Important: Do not create additional versions of procedures that are supplied with Db2 by specifying the
VERSION keyword. Only versions that are supplied with Db2 are supported. Additional versions of such
routines cause the installation and configuration of the supplied routines to fail.
Procedure
To create a new version of a procedure, issue one of the following:
• FL 507 The CREATE PROCEDURE statement with the following items:
– The OR REPLACE clause.
– The VERSION clause with a new version identifier.
• The ALTER PROCEDURE statement with the following items:
– The ADD VERSION clause with a name for the new version.
For either statement, you must include the following:
• The name of the native SQL procedure for which you want to create a new version.
• The parameter list of the procedure that you want to change. For ALTER PROCEUDRE ADD VERSION,
this parameter list must be the same as the original procedure.
• Any procedure options. These options can be different than the options for other versions of this
procedure. If you do not specify a value for a particular option, the default value is used, regardless of
the value that is used by the current active version of this procedure.
• A procedure body. This body can be different than the procedure body for other versions of this
procedure.
Examples
Example 1
For example, the following CREATE PROCEDURE statement defines a new native SQL procedure called
UPDATE_BALANCE. The version of the procedure is V1, and it is the active version.
CREATE PROCEDURE
UPDATE_BALANCE
(IN CUSTOMER_NO INTEGER,
IN AMOUNT DECIMAL(9,2))
VERSION V1
LANGUAGE SQL
READS SQL DATA
BEGIN
DECLARE CUSTOMER_NAME CHAR(20);
SELECT CUSTNAME
INTO CUSTOMER_NAME
FROM ACCOUNTS
WHERE CUSTNO = CUSTOMER_NO;
END
Example 2
The following ALTER PROCEDURE statement creates a new version of the UPDATE_BALANCE
procedure. The version name of the new version is V2. This new version has a different procedure
body.
ALTER PROCEDURE
UPDATE_BALANCE
ADD VERSION V2
(IN CUSTOMER_NO INTEGER,
IN AMOUNT DECIMAL (9,2) )
MODIFIES SQL DATA
BEGIN
UPDATE ACCOUNTS
SET BAL = BAL + AMOUNT
WHERE CUSTNO = CUSTOMER_NO;
END
What to do next
After you create a new version, if you want that version to be invoked by all subsequent calls to this
procedure, you need to make that version the active version. You can use the ACTIVATE VERSION clause
on either an ALTER PROCEDURE statement or a CREATE PROCEDURE statement with the OR REPLACE
clause.
Related reference
ALTER PROCEDURE (SQL - native) (Db2 SQL)
CREATE PROCEDURE (SQL - native) (Db2 SQL)
248 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
– Parameter CCSIDs
– Whether a parameter is an input or output parameter, as defined by the IN, OUT, and INOUT options
If you need to specify different values for any of the preceding items, create a new native SQL
procedure, instead of a new version.
• When the AUTONOMOUS option is specified for one version of a procedure, it must be specified for
every version of that procedure.
Procedure
Issue the BIND PACKAGE command with the following options:
DEPLOY
Specify the name of the procedure whose logic you want to use on the target server.
Tip: When specifying the parameters for the DEPLOY option, consider the following naming rules for
native SQL procedures:
• The collection ID is the same as the schema name in the original CREATE PROCEDURE statement.
• The package ID is the same as the procedure name in the original CREATE PROCEDURE statement.
COPYVER
Specify the version of the procedure whose logic you want to use on the target server.
ACTION(ADD) or ACTION(REPLACE)
Specify whether you want Db2 to create a new version of the native SQL procedure and its associated
package or to replace the specified version.
Optionally, you can also specify the bind options QUALIFIER or OWNER if want to change them.
Examples
Deploying the same version of a procedure at another location
The following BIND command creates a native SQL procedure with the name PRODUCTION.MYPROC
at the CHICAGO location. This procedure is created from the procedure TEST.MYPROC at the current
site. Both native SQL procedures have the same content and version, ABC. However, the package for
the procedure CHICAGO.PRODUCTION.MYPROC has XYZ as its qualifier.
Related concepts
Communications database for the server (Managing Security)
Related reference
BIND and REBIND options for packages, plans, and services (Db2 Commands)
BIND PACKAGE (DSN) (Db2 Commands)
Related information
Db2 for z/OS Stored Procedures: Through the CALL and Beyond (IBM Redbooks)
Procedure
Issue the ALTER PROCEDURE statement with the DROP VERSION clause and the name of the version that
you want to drop. If you instead want to drop all versions of the procedure, use the DROP statement.
Examples
Example of dropping a version that is not active
The following statement drops the OLD_PRODUCTION version of the P1 procedure.
Related tasks
Designating the active version of a native SQL procedure
When a native SQL procedure is called, Db2 uses the version that is designated as the active version.
250 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Procedure
To regenerate an existing version of a native SQL procedure:
1. Issue the ALTER PROCEDURE statement with the REGENERATE clause and specify the version to be
regenerated.
2. If copies of the package for the specified version of the procedure exist at remote sites, replace those
packages. Issue the BIND PACKAGE command with the COPY option and appropriate location for each
remote package.
3. If copies of the package for the specified version of the procedure exist locally with different schema
names, replace those packages. Issue the BIND PACKAGE command with the COPY option and
appropriate schema for each local package.
Example
The following ALTER PROCEDURE statement regenerates the active version of the UPDATE_SALARY_1
procedure.
Procedure
To change an existing version of a native SQL procedure, issue one of the following statements:
• FL 507The CREATE PROCEDURE statement with the OR REPLACE and the VERSION clause that
identifies the version to be replaced.
• The ALTER PROCEDURE statement with the REPLACE VERSION clause.
Any option that you do not explicitly specify inherits the system default values. This inheritance occurs
even if those options were explicitly specified for a prior version by using a CREATE PROCEDURE
statement, ALTER PROCEDURE statement, or REBIND command.
Examples
Example 1
The following ALTER PROCEDURE statement updates version V2 of the UPDATE_BALANCE procedure.
ALTER PROCEDURE
TEST.UPDATE_BALANCE
REPLACE VERSION V2
(IN CUSTOMER_NO INTEGER,
IN AMOUNT DECIMAL(9,2))
MODIFIES SQL DATA
ASUTIME LIMIT 100
BEGIN
UPDATE ACCOUNTS
SET BAL = BAL + AMOUNT
WHERE CUSTNO = CUSTOMER_NO
AND CUSTSTAT = 'A';
END
Example 2
FL 507
The following CREATE PROCEDURE statement will replace the version V2 of the UPDATE_BALANCE
procedure if version V2 already exists or will create it if version V2 has not yet been defined:
Related tasks
Creating new versions of native SQL procedures
A new version of a native SQL procedure can have different parameter names, procedure options, or
procedure body.
Related reference
REBIND PACKAGE (DSN) (Db2 Commands)
ALTER PROCEDURE (SQL - native) (Db2 SQL)
CREATE PROCEDURE (SQL - native) (Db2 SQL)
Procedure
To create an external stored procedure:
1. Write the external stored procedure body in assembler, C, C++, COBOL, REXX, or PL/I.
Ensure that the procedure body that you write follows the guidelines for external stored procedures
that are described in the following information:
• “Accessing other sites in an external procedure” on page 272
• “Accessing non-Db2 resources in your stored procedure” on page 272
• “Writing an external procedure to access IMS databases” on page 273
• “Writing an external procedure to return result sets to a distributed client” on page 274
• “Restrictions when calling other programs from an external stored procedure” on page 275
• “External stored procedures as main programs and subprograms” on page 276
• “Data types in stored procedures” on page 278
• “COMMIT and ROLLBACK statements in a stored procedure” on page 225
Restrictions:
• Do not include explicit attachment facility calls. External stored procedures that run in a WLM-
established address space use Resource Recovery Services attachment facility (RRSAF) calls
implicitly. If an external stored procedure makes an explicit attachment facility call, Db2 rejects
the call.
252 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
• Do not include SRRCMIT or SRRBACK service calls. If an external stored procedure invokes either
SRRCMIT or SRRBACK, Db2 puts the transaction in a state where a rollback operation is required and
the CALL statement fails.
For REXX procedures, continue with step “3” on page 253.
2. For assembler, C, C++, COBOL, or PL/I stored procedures, prepare the external procedure by
completing the following tasks:
a) Precompile, compile, and link-edit the application by using one of the following techniques:
• The Db2 precompiler and JCL instructions to compile and link-edit the program
• The SQL statement coprocessor
Recommendation: Compile and link-edit code as reentrant.
Link-edit the application by using DSNRLI, the language interface module for the Resource
Recovery Services attachment facility, or DSNULI, the Universal language interface module. You
must specify the parameter AMODE(31) when you link-edit the application with either of these
modules. (24-bit applications are not supported.)
If you want to make the stored procedure reentrant, see “Creating an external stored procedure as
reentrant” on page 276
If you want to run your procedure as a z/OS-authorized program, you must also perform the
following tasks when you link-edit the application:
• Indicate that the load module can use restricted system services by specifying the parameter
value AC=1.
• Put the load module for the stored procedure in an APF-authorized library.
You can compile COBOL stored procedures with either the DYNAM or NODYNAM COBOL compiler
options. If you use DYNAM, ensure that the correct Db2 language interface module is loaded
dynamically by performing one of the following actions:
• Specify the ATTACH(RRSAF) SQL processing option.
• Copy the DSNRLI module into a load library that is concatenated in front of the Db2 libraries. Use
the member name DSNHLI.
b) Bind the DBRM into a Db2 package by issuing the BIND PACKAGE command.
If you want to control access to a stored procedure package, specify the ENABLE bind option with
the system connection type of the calling application.
Stored procedures require only a package. You do not need to bind a plan for the stored procedure
or bind the stored procedure package to the plan for the calling application. For remote access
scenarios, you need a package at both the requester and server sites.
For more information about stored procedure packages, see “Packages for external stored
procedures” on page 271.
The following example BIND PACKAGE command binds the DBRM EMPDTL1P to the collection
DEVL7083.
BIND PACKAGE(DEVL7083) -
MEMBER(EMPDTL1P) ACT(REP) ISO(UR) ENCODING(EBCDIC) -
OWNER(DEVL7083) LIBRARY('SG247083.DEVL.DBRM')
3. Define the stored procedure to Db2 by issuing the CREATE PROCEDURE statement with the EXTERNAL
option. Use the EXTERNAL NAME clause to specify the name of the load module for the program that
runs when this procedure is called.
If you want to run your procedure as a z/OS-authorized program, specify an appropriate environment
with the WLM ENVIRONMENT option. The stored procedure must run in an address space with a
startup procedure in which all libraries in the STEPLIB concatenation are APF-authorized.
MSGFILE(OUTFILE),RPTSTG(ON),RPTOPTS(ON)
• The stored procedure is part of the WLM application environment that is named PAYROLL.
• The stored procedure runs as a main program.
• The stored procedure does not access non-Db2 resources, so it does not need a special RACF
environment.
• The stored procedure can return at most 10 result sets.
• When control returns to the client program, Db2 does not commit updates automatically.
The following CREATE PROCEDURE statement defines the stored procedure to Db2:
254 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
DYNAMIC RESULT SETS 10
COMMIT ON RETURN NO;
What to do next
You can now invoke the stored procedure from an application program or command line processor.
Related concepts
“Universal language interface (DSNULI)” on page 113
The universal language interface (DSNULI) subcomponent determines the runtime environment and
dynamically loads and branches to the appropriate language interface module.
Java stored procedures and user-defined functions (Db2 Application Programming for Java)
Related tasks
Implementing Db2 stored procedures (Db2 Administration Guide)
Related reference
BIND and REBIND options for packages, plans, and services (Db2 Commands)
CREATE PROCEDURE (external) (Db2 SQL)
GRANT (function or procedure privileges) (Db2 SQL)
Related information
Db2 for z/OS Stored Procedures: Through the CALL and Beyond (IBM Redbooks)
Procedure
When you define the stored procedure with the CREATE PROCEDURE statement, specify one of the
following values for the PARAMETER STYLE option:
• GENERAL
• GENERAL WITH NULLS
• SQL
SQL is the default.
Indicator n
Figure 13. Parameter convention GENERAL WITH NULLS for a stored procedure
SQL
Specify the SQL linkage convention when you want both of the following conditions:
• The calling program to be able to supply a null value for any parameter that is passed to the stored
procedure.
• Db2 to pass input and output parameters to the stored procedure that contain the following
information:
– The SQLSTATE that is to be returned to Db2. This value is a CHAR(5) parameter that represents
the SQLSTATE that is passed into the program from the database manager. The initial value is set
to ‘00000'. Although the SQLSTATE is usually not set by the program, it can be set as the result
SQLSTATE that is used to return an error or a warning. Returned values that start with anything
other than ‘00', ‘01', or ‘02' are error conditions.
– The qualified name of the stored procedure. This is a VARCHAR(128) value.
– The specific name of the stored procedure. The specific name is a VARCHAR(128) value that is
the same as the unqualified name.
– The SQL diagnostic string that is to be returned to Db2. This is a VARCHAR(1000) value. Use this
area to pass descriptive information about an error or warning to the caller.
Restriction: You cannot use the SQL linkage convention for a REXX language stored procedure.
The following figure shows the structure of the parameter list for PARAMETER STYLE SQL.
256 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Register 1 Addresses of: Data:
Indicator 1 Indicator 1
Indicator 2 Indicator 2
..
.
Indicator n Indicator n
SQLSTATE SQLSTATE
Procedure
Procedure name
name
Specific
name Specific name
Diagnostic
data Diagnostic data
1, 2
DBINFO DBINFO
1
For PL/I, this value is the address of a pointer to the DBINFO data.
2
Passed if the DBINFO option is specified in the user-defined function definition.
Related concepts
Example programs that call stored procedures
Examples can be used as models when you write applications that call stored procedures. In
addition, prefix.SDSNSAMP contains sample jobs DSNTEJ6P and DSNTEJ6S and programs DSN8EP1 and
DSN8EP2, which you can run.
Related reference
CREATE PROCEDURE (external) (Db2 SQL)
SQLSTATE values and common error codes (Db2 Codes)
Examples
The following examples demonstrate how an assembler, C, COBOL, or PL/I stored procedure uses the
GENERAL linkage convention to receive parameters.
For these examples, assume that a COBOL application has the following parameter declarations and CALL
statement:
************************************************************
* PARAMETERS FOR THE SQL STATEMENT CALL *
************************************************************
01 V1 PIC S9(9) USAGE COMP.
01 V2 PIC X(9).
⋮
EXEC SQL CALL A (:V1, :V2) END-EXEC.
*******************************************************************
* CODE FOR AN ASSEMBLER LANGUAGE STORED PROCEDURE THAT USES *
* THE GENERAL LINKAGE CONVENTION. *
*******************************************************************
A CEEENTRY AUTO=PROGSIZE,MAIN=YES,PLIST=OS
USING PROGAREA,R13
*******************************************************************
* BRING UP THE LANGUAGE ENVIRONMENT. *
*******************************************************************
⋮
*******************************************************************
* GET THE PASSED PARAMETER VALUES. THE GENERAL LINKAGE CONVENTION*
* FOLLOWS THE STANDARD ASSEMBLER LINKAGE CONVENTION: *
* ON ENTRY, REGISTER 1 POINTS TO A LIST OF POINTERS TO THE *
* PARAMETERS. *
*******************************************************************
L R7,0(R1) GET POINTER TO V1
MVC LOCV1(4),0(R7) MOVE VALUE INTO LOCAL COPY OF V1
⋮
L R7,4(R1) GET POINTER TO V2
MVC 0(9,R7),LOCV2 MOVE A VALUE INTO OUTPUT VAR V2
⋮
CEETERM RC=0
*******************************************************************
* VARIABLE DECLARATIONS AND EQUATES *
*******************************************************************
R1 EQU 1 REGISTER 1
R7 EQU 7 REGISTER 7
PPA CEEPPA , CONSTANTS DESCRIBING THE CODE BLOCK
LTORG , PLACE LITERAL POOL HERE
PROGAREA DSECT
ORG *+CEEDSASZ LEAVE SPACE FOR DSA FIXED PART
LOCV1 DS F LOCAL COPY OF PARAMETER V1
LOCV2 DS CL9 LOCAL COPY OF PARAMETER V2
⋮
PROGSIZE EQU *-PROGAREA
CEEDSA , MAPPING OF THE DYNAMIC SAVE AREA
CEECAA , MAPPING OF THE COMMON ANCHOR AREA
END A
C example
The following figure shows how a stored procedure that is written in the C language receives these
parameters.
#pragma runopts(PLIST(OS))
#pragma options(RENT)
#include <stdlib.h>
#include <stdio.h>
/*****************************************************************/
/* Code for a C language stored procedure that uses the */
/* GENERAL linkage convention. */
/*****************************************************************/
main(argc,argv)
int argc; /* Number of parameters passed */
char *argv[]; /* Array of strings containing */
/* the parameter values */
{
long int locv1; /* Local copy of V1 */
char locv2[10]; /* Local copy of V2 */
/* (null-terminated) */
⋮
/***************************************************************/
/* Get the passed parameters. The GENERAL linkage convention */
/* follows the standard C language parameter passing */
/* conventions: */
/* - argc contains the number of parameters passed */
/* - argv[0] is a pointer to the stored procedure name */
/* - argv[1] to argv[n] are pointers to the n parameters */
/* in the SQL statement CALL. */
/***************************************************************/
if(argc==3) /* Should get 3 parameters: */
258 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
{ /* procname, V1, V2 */
locv1 = *(int *) argv[1];
/* Get local copy of V1 */
⋮
strcpy(argv[2],locv2);
/* Assign a value to V2 */
⋮
}
}
COBOL example
The following figure shows how a stored procedure that is written in the COBOL language receives these
parameters.
CBL RENT
IDENTIFICATION DIVISION.
************************************************************
* CODE FOR A COBOL LANGUAGE STORED PROCEDURE THAT USES THE *
* GENERAL LINKAGE CONVENTION. *
************************************************************
PROGRAM-ID. A.
⋮
DATA DIVISION.
⋮
LINKAGE SECTION.
************************************************************
* DECLARE THE PARAMETERS PASSED BY THE SQL STATEMENT *
* CALL HERE. *
************************************************************
01 V1 PIC S9(9) USAGE COMP.
01 V2 PIC X(9).
⋮
PROCEDURE DIVISION USING V1, V2.
************************************************************
* THE USING PHRASE INDICATES THAT VARIABLES V1 AND V2 *
* WERE PASSED BY THE CALLING PROGRAM. *
************************************************************
⋮
****************************************
* ASSIGN A VALUE TO OUTPUT VARIABLE V2 *
****************************************
MOVE '123456789' TO V2.
PL/I example
The following figure shows how a stored procedure that is written in the PL/I language receives these
parameters.
*PROCESS SYSTEM(MVS);
A: PROC(V1, V2) OPTIONS(MAIN NOEXECOPS REENTRANT);
/***************************************************************/
/* Code for a PL/I language stored procedure that uses the */
/* GENERAL linkage convention. */
/***************************************************************/
/***************************************************************/
/* Indicate on the PROCEDURE statement that two parameters */
/* were passed by the SQL statement CALL. Then declare the */
/* parameters in the following section. */
/***************************************************************/
DCL V1 BIN FIXED(31),
V2 CHAR(9);
⋮
V2 = '123456789'; /* Assign a value to output variable V2 */
Examples
The following examples demonstrate how an assembler, C, COBOL, or PL/I stored procedure uses the
GENERAL WITH NULLS linkage convention to receive parameters.
For these examples, assume that a C application has the following parameter declarations and CALL
statement:
/************************************************************/
/* Parameters for the SQL statement CALL */
/************************************************************/
long int v1;
char v2[10]; /* Allow an extra byte for */
/* the null terminator */
/************************************************************/
/* Indicator structure */
/************************************************************/
struct indicators {
short int ind1;
short int ind2;
} indstruc;
⋮
indstruc.ind1 = 0; /* Remember to initialize the */
/* input parameter's indicator*/
/* variable before executing */
/* the CALL statement */
EXEC SQL CALL B (:v1 :indstruc.ind1, :v2 :indstruc.ind2);
⋮
Assembler example
The following figure shows how a stored procedure that is written in assembler language receives these
parameters.
*******************************************************************
* CODE FOR AN ASSEMBLER LANGUAGE STORED PROCEDURE THAT USES *
* THE GENERAL WITH NULLS LINKAGE CONVENTION. *
*******************************************************************
B CEEENTRY AUTO=PROGSIZE,MAIN=YES,PLIST=OS
USING PROGAREA,R13
*******************************************************************
* BRING UP THE LANGUAGE ENVIRONMENT. *
*******************************************************************
⋮
*******************************************************************
* GET THE PASSED PARAMETER VALUES. THE GENERAL WITH NULLS LINKAGE*
* CONVENTION IS AS FOLLOWS: *
* ON ENTRY, REGISTER 1 POINTS TO A LIST OF POINTERS. IF N *
* PARAMETERS ARE PASSED, THERE ARE N+1 POINTERS. THE FIRST *
* N POINTERS ARE THE ADDRESSES OF THE N PARAMETERS, JUST AS *
* WITH THE GENERAL LINKAGE CONVENTION. THE N+1ST POINTER IS *
* THE ADDRESS OF A LIST CONTAINING THE N INDICATOR VARIABLE *
* VALUES. *
*******************************************************************
L R7,0(R1) GET POINTER TO V1
MVC LOCV1(4),0(R7) MOVE VALUE INTO LOCAL COPY OF V1
L R7,8(R1) GET POINTER TO INDICATOR ARRAY
MVC LOCIND(2*2),0(R7) MOVE VALUES INTO LOCAL STORAGE
LH R7,LOCIND GET INDICATOR VARIABLE FOR V1
LTR R7,R7 CHECK IF IT IS NEGATIVE
BM NULLIN IF SO, V1 IS NULL
⋮
L R7,4(R1) GET POINTER TO V2
MVC 0(9,R7),LOCV2 MOVE A VALUE INTO OUTPUT VAR V2
L R7,8(R1) GET POINTER TO INDICATOR ARRAY
MVC 2(2,R7),=H(0) MOVE ZERO TO V2'S INDICATOR VAR
260 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
⋮
CEETERM RC=0
*******************************************************************
* VARIABLE DECLARATIONS AND EQUATES *
*******************************************************************
R1 EQU 1 REGISTER 1
R7 EQU 7 REGISTER 7
PPA CEEPPA , CONSTANTS DESCRIBING THE CODE BLOCK
LTORG , PLACE LITERAL POOL HERE
PROGAREA DSECT
ORG *+CEEDSASZ LEAVE SPACE FOR DSA FIXED PART
LOCV1 DS F LOCAL COPY OF PARAMETER V1
LOCV2 DS CL9 LOCAL COPY OF PARAMETER V2
LOCIND DS 2H LOCAL COPY OF INDICATOR ARRAY
⋮
PROGSIZE EQU *-PROGAREA
CEEDSA , MAPPING OF THE DYNAMIC SAVE AREA
CEECAA , MAPPING OF THE COMMON ANCHOR AREA
END B
C example
The following figure shows how a stored procedure that is written in the C language receives these
parameters.
#pragma options(RENT)
#pragma runopts(PLIST(OS))
#include <stdlib.h>
#include <stdio.h>
/*****************************************************************/
/* Code for a C language stored procedure that uses the */
/* GENERAL WITH NULLS linkage convention. */
/*****************************************************************/
main(argc,argv)
int argc; /* Number of parameters passed */
char *argv[]; /* Array of strings containing */
/* the parameter values */
{
long int locv1; /* Local copy of V1 */
char locv2[10]; /* Local copy of V2 */
/* (null-terminated) */
short int locind[2]; /* Local copy of indicator */
/* variable array */
short int *tempint; /* Used for receiving the */
/* indicator variable array */
⋮
/***************************************************************/
/* Get the passed parameters. The GENERAL WITH NULLS linkage */
/* convention is as follows: */
/* - argc contains the number of parameters passed */
/* - argv[0] is a pointer to the stored procedure name */
/* - argv[1] to argv[n] are pointers to the n parameters */
/* in the SQL statement CALL. */
/* - argv[n+1] is a pointer to the indicator variable array */
/***************************************************************/
if(argc==4) /* Should get 4 parameters: */
{ /* procname, V1, V2, */
/* indicator variable array */
locv1 = *(int *) argv[1];
/* Get local copy of V1 */
tempint = argv[3]; /* Get pointer to indicator */
/* variable array */
locind[0] = *tempint;
/* Get 1st indicator variable */
locind[1] = *(++tempint);
/* Get 2nd indicator variable */
if(locind[0]<0) /* If 1st indicator variable */
{ /* is negative, V1 is null */
⋮
}
⋮
strcpy(argv[2],locv2);
/* Assign a value to V2 */
*(++tempint) = 0; /* Assign 0 to V2's indicator */
/* variable */
}
}
CBL RENT
IDENTIFICATION DIVISION.
************************************************************
* CODE FOR A COBOL LANGUAGE STORED PROCEDURE THAT USES THE *
* GENERAL WITH NULLS LINKAGE CONVENTION. *
************************************************************
PROGRAM-ID. B.
⋮
DATA DIVISION.
⋮
LINKAGE SECTION.
************************************************************
* DECLARE THE PARAMETERS AND THE INDICATOR ARRAY THAT *
* WERE PASSED BY THE SQL STATEMENT CALL HERE. *
************************************************************
01 V1 PIC S9(9) USAGE COMP.
01 V2 PIC X(9).
*
01 INDARRAY.
10 INDVAR PIC S9(4) USAGE COMP OCCURS 2 TIMES.
⋮
PROCEDURE DIVISION USING V1, V2, INDARRAY.
************************************************************
* THE USING PHRASE INDICATES THAT VARIABLES V1, V2, AND *
* INDARRAY WERE PASSED BY THE CALLING PROGRAM. *
************************************************************
⋮
***************************
* TEST WHETHER V1 IS NULL *
***************************
IF INDARRAY(1) < 0
PERFORM NULL-PROCESSING.
⋮
****************************************
* ASSIGN A VALUE TO OUTPUT VARIABLE V2 *
* AND ITS INDICATOR VARIABLE *
****************************************
MOVE '123456789' TO V2.
MOVE ZERO TO INDARRAY(2).
PL/I example
The following figure shows how a stored procedure that is written in the PL/I language receives these
parameters.
*PROCESS SYSTEM(MVS);
A: PROC(V1, V2, INDSTRUC) OPTIONS(MAIN NOEXECOPS REENTRANT);
/***************************************************************/
/* Code for a PL/I language stored procedure that uses the */
/* GENERAL WITH NULLS linkage convention. */
/***************************************************************/
/***************************************************************/
/* Indicate on the PROCEDURE statement that two parameters */
/* and an indicator variable structure were passed by the SQL */
/* statement CALL. Then declare them in the following section.*/
/* For PL/I, you must declare an indicator variable structure, */
/* not an array. */
/***************************************************************/
DCL V1 BIN FIXED(31),
V2 CHAR(9);
DCL
01 INDSTRUC,
02 IND1 BIN FIXED(15),
02 IND2 BIN FIXED(15);
⋮
IF IND1 < 0 THEN
CALL NULLVAL; /* If indicator variable is negative */
/* then V1 is null */
⋮
V2 = '123456789'; /* Assign a value to output variable V2 */
IND2 = 0; /* Assign 0 to V2's indicator variable */
262 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Example of SQL linkage convention
Specify the SQL linkage convention when you want diagnostic information to be passed in the parameters
and allow null values.
Examples
The following examples demonstrate how an assembler, C, COBOL, or PL/I stored procedure uses the SQL
linkage convention to receive parameters. These examples also show how a stored procedure receives
the DBINFO structure.
For these examples, assume that a C application has the following parameter declarations and CALL
statement:
/************************************************************/
/* Parameters for the SQL statement CALL */
/************************************************************/
long int v1;
char v2[10]; /* Allow an extra byte for */
/* the null terminator */
/************************************************************/
/* Indicator variables */
/************************************************************/
short int ind1;
short int ind2;
⋮
ind1 = 0; /* Remember to initialize the */
/* input parameter's indicator*/
/* variable before executing */
/* the CALL statement */
EXEC SQL CALL B (:v1 :ind1, :v2 :ind2);
⋮
Assembler example
The following figure shows how a stored procedure that is written in assembler language receives these
parameters.
*******************************************************************
* CODE FOR AN ASSEMBLER LANGUAGE STORED PROCEDURE THAT USES
*
* THE SQL LINKAGE CONVENTION. *
*******************************************************************
B CEEENTRY AUTO=PROGSIZE,MAIN=YES,PLIST=OS
USING PROGAREA,R13
*******************************************************************
* BRING UP THE LANGUAGE ENVIRONMENT.
*
*******************************************************************
⋮
*******************************************************************
* GET THE PASSED PARAMETER VALUES. THE SQL LINKAGE *
* CONVENTION IS AS FOLLOWS:
*
* ON ENTRY, REGISTER 1 POINTS TO A LIST OF POINTERS. IF N
*
* PARAMETERS ARE PASSED, THERE ARE 2N+4 POINTERS. THE FIRST
*
* N POINTERS ARE THE ADDRESSES OF THE N PARAMETERS, JUST AS
*
* WITH THE GENERAL LINKAGE CONVENTION. THE NEXT N POINTERS ARE
*
* THE ADDRESSES OF THE INDICATOR VARIABLE VALUES. THE LAST
*
* 4 POINTERS (5, IF DBINFO IS PASSED) ARE THE ADDRESSES OF
*
* INFORMATION ABOUT THE STORED PROCEDURE ENVIRONMENT AND
*
* EXECUTION RESULTS.
*
*******************************************************************
* VARIABLE DECLARATIONS AND EQUATES
*
*******************************************************************
R1 EQU 1 REGISTER 1
R7 EQU 7 REGISTER 7
PPA CEEPPA , CONSTANTS DESCRIBING THE CODE BLOCK
LTORG , PLACE LITERAL POOL HERE
PROGAREA DSECT
ORG *+CEEDSASZ LEAVE SPACE FOR DSA FIXED PART
LOCV1 DS F LOCAL COPY OF PARAMETER V1
LOCV2 DS CL9 LOCAL COPY OF PARAMETER V2
LOCI1 DS H LOCAL COPY OF INDICATOR 1
LOCI2 DS H LOCAL COPY OF INDICATOR 2
LOCSQST DS CL5 LOCAL COPY OF SQLSTATE
LOCSPNM DS H,CL27 LOCAL COPY OF STORED PROC NAME
LOCSPSNM DS H,CL18 LOCAL COPY OF SPECIFIC NAME
LOCDIAG DS H,CL1000 LOCAL COPY OF DIAGNOSTIC DATA
LOCDBINF DS 0H LOCAL COPY OF DBINFO DATA
DBNAMELN DS H DATABASE NAME LENGTH
DBNAME DS CL128 DATABASE NAME
AUTHIDLN DS H APPL AUTH ID LENGTH
AUTHID DS CL128 APPL AUTH ID
ASC_SBCS DS F ASCII SBCS CCSID
ASC_DBCS DS F ASCII DBCS CCSID
ASC_MIXD DS F ASCII MIXED CCSID
EBC_SBCS DS F EBCDIC SBCS CCSID
EBC_DBCS DS F EBCDIC DBCS CCSID
EBC_MIXD DS F EBCDIC MIXED CCSID
UNI_SBCS DS F UNICODE SBCS CCSID
UNI_DBCS DS F UNICODE DBCS CCSID
UNI_MIXD DS F UNICODE MIXED CCSID
ENCODE DS F PROCEDURE ENCODING SCHEME
RESERV0 DS CL20 RESERVED
TBQUALLN DS H TABLE QUALIFIER LENGTH
TBQUAL DS CL128 TABLE QUALIFIER
TBNAMELN DS H TABLE NAME LENGTH
TBNAME DS CL128 TABLE NAME
CLNAMELN DS H COLUMN NAME LENGTH
COLNAME DS CL128 COLUMN NAME
RELVER DS CL8 DBMS RELEASE AND VERSION
RESERV1 DS CL2 RESERVED
PLATFORM DS F DBMS OPERATING SYSTEM
NUMTFCOL DS H NUMBER OF TABLE FUNCTION COLS USED
RESERV2 DS CL26 RESERVED
TFCOLNUM DS A POINTER TO TABLE FUNCTION COL LIST
APPLID DS A POINTER TO APPLICATION ID
RESERV3 DS CL20 RESERVED
DBINFLN EQU *-LOCDBINF LENGTH OF DBINFO
⋮
PROGSIZE EQU *-PROGAREA
CEEDSA , MAPPING OF THE DYNAMIC SAVE AREA
CEECAA , MAPPING OF THE COMMON ANCHOR AREA
END B
264 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
C example
The following figure shows how a stored procedure that is written as a main program in the C language
receives these parameters.
#pragma runopts(plist(os))
#include <;stdlib.h>
#include <;stdio.h>
main(argc,argv)
int argc;
char *argv[];
{
int parm1;
short int ind1;
char p_proc[28];
char p_spec[19];
/***************************************************/
/* Assume that the SQL CALL statement included */
/* 3 input/output parameters in the parameter list.*/
/* The argv vector will contain these entries: */
/* argv[0] 1 contains load module */
/* argv[1-3] 3 input/output parms */
/* argv[4-6] 3 null indicators */
/* argv[7] 1 SQLSTATE variable */
/* argv[8] 1 qualified proc name */
/* argv[9] 1 specific proc name */
/* argv[10] 1 diagnostic string */
/* argv[11] + 1 dbinfo */
/* ------ */
/* 12 for the argc variable */
/***************************************************/
if argc<>12 {
⋮
/* We end up here when invoked with wrong number of parms */
}
/***************************************************/
/* Assume the first parameter is an integer. */
/* The following code shows how to copy the integer*/
/* parameter into the application storage. */
/***************************************************/
parm1 = *(int *) argv[1];
/***************************************************/
/* We can access the null indicator for the first */
/* parameter on the SQL CALL as follows: */
/***************************************************/
ind1 = *(short int *) argv[4];
/***************************************************/
/* We can use the following expression */
/* to assign 'xxxxx' to the SQLSTATE returned to */
/* caller on the SQL CALL statement. */
/***************************************************/
strcpy(argv[7],"xxxxx/0");
/***************************************************/
/* We obtain the value of the qualified procedure */
/* name with this expression. */
/***************************************************/
strcpy(p_proc,argv[8]);
/***************************************************/
/* We obtain the value of the specific procedure */
/* name with this expression. */
/***************************************************/
strcpy(p_spec,argv[9]);
/***************************************************/
/* We can use the following expression to assign */
/* 'yyyyyyyy' to the diagnostic string returned */
/* in the SQLDA associated with the CALL statement.*/
/***************************************************/
strcpy(argv[10],"yyyyyyyy/0");
⋮
}
The following figure shows how a stored procedure that is written as a subprogram in the C language
receives these parameters.
#pragma linkage(myproc,fetchable)
#include <stdlib.h>
strcpy(l_p2,parm2);
l_ind1 = *p_ind1;
l_ind1 = *p_ind2;
strcpy(l_sqlstate,p_sqlstate);
strcpy(l_proc,p_proc);
strcpy(l_spec,p_spec);
strcpy(l_diag,p_diag);
memcpy(&ludf_dbinfo,udf_dbinfo,sizeof(ludf_dbinfo));
⋮
}
COBOL example
The following figure shows how a stored procedure that is written in the COBOL language receives these
parameters.
CBL RENT
IDENTIFICATION DIVISION.
⋮
DATA DIVISION.
⋮
LINKAGE SECTION.
* Declare each of the parameters
01 PARM1 …
01 PARM2 …
⋮
* Declare a null indicator for each parameter
01 P-IND1 PIC S9(4) USAGE COMP.
01 P-IND2 PIC S9(4) USAGE COMP.
⋮
* Declare the SQLSTATE that can be set by stored proc
01 P-SQLSTATE PIC X(5).
266 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* Declare the qualified procedure name
01 P-PROC.
49 P-PROC-LEN PIC 9(4) USAGE BINARY.
49 P-PROC-TEXT PIC X(27).
* Declare the specific procedure name
01 P-SPEC.
49 P-SPEC-LEN PIC 9(4) USAGE BINARY.
49 P-SPEC-TEXT PIC X(18).
* Declare SQL diagnostic message token
01 P-DIAG.
49 P-DIAG-LEN PIC 9(4) USAGE BINARY.
49 P-DIAG-TEXT PIC X(1000).
*********************************************************
* Structure used for DBINFO *
*********************************************************
01 SQLUDF-DBINFO.
* Location name length
05 DBNAMELEN PIC 9(4) USAGE BINARY.
* Location name
05 DBNAME PIC X(128).
* authorization ID length
05 AUTHIDLEN PIC 9(4) USAGE BINARY.
* authorization ID
05 AUTHID PIC X(128).
* environment CCSID information
05 CODEPG PIC X(48).
05 CDPG-DB2 REDEFINES CODEPG.
10 DB2-CCSIDS OCCURS 3 TIMES.
15 DB2-SBCS PIC 9(9) USAGE BINARY.
15 DB2-DBCS PIC 9(9) USAGE BINARY.
15 DB2-MIXED PIC 9(9) USAGE BINARY.
10 ENCODING-SCHEME PIC 9(9) USAGE BINARY.
10 RESERVED PIC X(20).
* other platform-specific
deprecated CCSID structures not included here
* schema name length
05 TBSCHEMALEN PIC 9(4) USAGE BINARY.
* schema name
05 TBSCHEMA PIC X(128).
* table name length
05 TBNAMELEN PIC 9(4) USAGE BINARY.
* table name
05 TBNAME PIC X(128).
* column name length
05 COLNAMELEN PIC 9(4) USAGE BINARY.
* column name
05 COLNAME PIC X(128).
* product information
05 VER-REL PIC X(8).
* reserved
05 RESD0 PIC X(2).
* platform type
05 PLATFORM PIC 9(9) USAGE BINARY.
* number of entries in the TF column list array (tfcolumn, below)
05 NUMTFCOL PIC 9(4) USAGE BINARY.
* reserved
05 RESD1 PIC X(26).
* tfcolumn will be allocated dynamically of it is defined
* otherwise this will be a null pointer
05 TFCOLUMN USAGE IS POINTER.
* application identifier
05 APPL-ID USAGE IS POINTER.
* reserved
05 RESD2 PIC X(20).
*
⋮
PROCEDURE DIVISION USING PARM1, PARM2,
P-IND1, P-IND2,
P-SQLSTATE, P-PROC, P-SPEC, P-DIAG,
SQLUDF-DBINFO.
⋮
*PROCESS SYSTEM(MVS);
MYMAIN: PROC(PARM1, PARM2, ...,
P_IND1, P_IND2, ...,
P_SQLSTATE, P_PROC, P_SPEC, P_DIAG, DBINFO)
OPTIONS(MAIN NOEXECOPS REENTRANT);
268 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
DBINFO structure
Use the DBINFO structure to pass environment information to user-defined functions and stored
procedures. Some fields in the structure are not used for stored procedures.
DBINFO is a structure that contains information such as the name of the current server, the application
run time authorization ID and identification of the version and release of the database manager that
invoked the procedure.
The DBINFO structure includes the following information:
Location name length
An unsigned 2-byte integer field. It contains the length of the location name in the next field.
Location name
A 128-byte character field. It contains the name of the location to which the invoker is currently
connected.
Authorization ID length
An unsigned 2-byte integer field. It contains the length of the authorization ID in the next field.
Authorization ID
A 128-byte character field. It contains the authorization ID of the application from which the stored
procedure is invoked, padded on the right with blanks. If this stored procedure is nested within
other routines (user-defined functions or stored procedures), this value is the authorization ID of the
application that invoked the highest-level routine.
Subsystem code page
A 48-byte structure that consists of 10 integer fields and an eight-byte reserved area. These fields
provide information about the CCSIDs of the subsystem from which the stored procedure is invoked.
Table qualifier length
An unsigned 2-byte integer field. This field contains 0.
Table qualifier
A 128-byte character field. This field is not used for stored procedures.
Table name length
An unsigned 2-byte integer field. This field contains 0.
Table name
A 128-byte character field. This field is not used for stored procedures.
Column name length
An unsigned 2-byte integer field. This field contains 0.
Column name
A 128-byte character field. This field is not used for stored procedures.
Product information
An 8-byte character field that identifies the product on which the stored procedure executes.
The product identifier (PRDID) value is an 8-byte character value in pppvvrrm format, where: ppp is a
3-letter product code; vv is the version;rr is the release; and m is the modification level. In Db2 12 for
z/OS, the modification level indicates a range of function levels:
DSN12015 for V12R1M500 or higher.
DSN12010 for V12R1M100.
For more information, see Product identifier (PRDID) values in Db2 for z/OS (Db2 Administration
Guide).
Reserved area
2 bytes.
Operating system
A 4-byte integer field. It identifies the operating system on which the program that invokes the
user-defined function runs. The value is one of these:
270 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
The string is the LUWID, which consists of a fully-qualified LU network name followed by a period
and an LUW instance number. The LU network name consists of a one- to eight-character network ID,
a period, and a one- to eight-character network LU name. The LUW instance number consists of 12
hexadecimal characters that uniquely identify the unit of work.
Reserved area
20 bytes.
You can control access to the stored procedure package by specifying the ENABLE bind option when you
bind the package.
In the following situations, the stored procedure might use more than one package:
• You bind a DBRM several times into several versions of the same package, all of which have the same
package name but reside in different package collections. Your stored procedure can switch from one
version to another by using the SET CURRENT PACKAGESET statement.
• The stored procedure calls another program that contains SQL statements. This program has an
associated package. This package must exist at the location where the stored procedure is defined
and at the location where the SQL statements are executed.
Related reference
BIND and REBIND options for packages, plans, and services (Db2 Commands)
BIND PACKAGE (DSN) (Db2 Commands)
SET CURRENT PACKAGESET (Db2 SQL)
Procedure
To access non-Db2 resources in your stored procedure:
1. Consider serializing access to non-Db2 resources within your application.
Not all non-Db2 resources can tolerate concurrent access by multiple TCBs in the same address space.
2. To access CICS, use one of the following methods:
• Stored procedure DSNACICS
• Message Queue Interface (MQI) for asynchronous execution of CICS transactions
• External CICS interface (EXCI) for synchronous execution of CICS transactions
• Advanced Program-to-Program Communication (APPC), using the Common Programming Interface
Communications (CPI Communications) application programming interface
If your system is running a release of CICS that uses z/OS RRS, z/OS RRS controls commitment of all
resources.
3. To access IMS DL/I data, use one of the following methods
• Open Database Access interface (ODBA)
• Stored procedures DSNAIMS and DSNAIMS2
If your system is not running a release of IMS that uses z/OS RRS, take one of the following actions:
• Use the CICS EXCI interface to run a CICS transaction synchronously. That CICS transaction can, in
turn, access DL/I data.
• Invoke IMS transactions asynchronously using the MQI.
• Use APPC through the Common Programming Interface (CPI) Communications application
programming interface.
4. Determine which of the following authorization IDs you want to use to access the non-Db2 resources.
272 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 46. Authorization IDs for accessing non-Db2 resources from a stored procedure
ID that you want to use to access the non-Db2 SECURITY value to specify in the CREATE
resources PROCEDURE statement
The authorization ID that is associated with the SECURITY Db2
stored procedures address space
The authorization ID under which the CALL SECURITY USER
statement is executed
The authorization ID under which the CREATE SECURITY DEFINER
PROCEDURE statement is executed
5. Issue the CREATE PROCEDURE statement with the appropriate SECURITY option that you determined
in the previous step.
Results
When the stored procedure runs, Db2 establishes a RACF environment for accessing non-Db2 resources
and uses the specified authorization ID to access protected z/OS resources.
Related tasks
Calling a stored procedure from your application
To run a stored procedure, you can either call it from a client program or invoke it from the command line
processor.
Implementing RRS for stored procedures during installation (Db2 Installation and Migration)
Controlling stored procedure access to non-Db2 resources by using RACF (Managing Security)
Related reference
DSNACICS stored procedure (Db2 SQL)
DSNAIMS stored procedure (Db2 SQL)
DSNAIMS2 stored procedure (Db2 SQL)
CREATE PROCEDURE (SQL - external) (deprecated) (Db2 SQL)
APPC/MVS Configuration (Multiplatform APPC Configuration Guide)
Related information
Db2 for z/OS Stored Procedures: Through the CALL and Beyond (IBM Redbooks)
External CICS interface (EXCI) (CICS Transaction Server for z/OS)
Procedure
• For each result set you want returned, your stored procedure must complete the following steps:
a) Declare a cursor with the option WITH RETURN.
b) Open the cursor.
c) If the cursor is scrollable, ensure that the cursor is positioned before the first row of the result
table.
d) Leave the cursor open.
For example, suppose you want to return a result set that contains entries for all employees in
department D11. First, declare a cursor that describes this subset of employees:
Db2 returns the result set and the name of the SQL cursor for the stored procedure to the client.
When the stored procedure ends, Db2 returns the rows in the query result set to the client.
Db2 does not return result sets for cursors that are closed before the stored procedure terminates.
The stored procedure must execute a CLOSE statement for each cursor associated with a result set
that should not be returned to the DRDA client.
• Use meaningful cursor names for returning result sets.
The name of the cursor that is used to return result sets is made available to the client application
through extensions to the DESCRIBE statement.
Use cursor names that are meaningful to the DRDA client application, especially when the stored
procedure returns multiple result sets.
• You can use any of these objects in the SELECT statement that is associated with the cursor for a result
set:
Tables, synonyms, views, created temporary tables, declared temporary tables, and aliases defined at
the local Db2 subsystem.
• Return a subset of rows to the client by issuing FETCH statements with a result set cursor. does not
return the fetched rows to the client program.
274 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Db2 does not return the fetched rows to the client program. For example, if you declare a cursor
WITH RETURN and then execute the statements OPEN, FETCH, and FETCH, the client receives data
beginning with the third row in the result set. If the result set cursor is scrollable and you fetch rows
with it, you need to position the cursor before the first row of the result table after you fetch the rows
and before the stored procedure ends.
• You can use a created temporary table or declared temporary table to return result sets from a stored
procedure.
This capability can be used to return non-relational data to a DRDA client. For example, you can access
IMS data from a stored procedure by using the following process:
a) Use APPC/MVS to issue an IMS transaction.
b) Receive the IMS reply message, which contains data that should be returned to the client.
c) Insert the data from the reply message into a temporary table.
d) Open a cursor against the temporary table. When the stored procedure ends, the rows from the
temporary table are returned to the client.
Related tasks
Writing a program to receive the result sets from a stored procedure
You can write a program to receive results set from a stored procedure for either a fixed number of result
sets, for which you know the contents, or a variable number of result sets, for which you do not know the
contents.
Procedure
To create an external stored procedure as reentrant:
1. Compile the procedure as reentrant and link-edit it as reentrant and reusable.
For instructions on compiling programs to be reentrant, see the information for the programming
language that you are using. For C and C++ procedures, you can use the z/OS binder to produce
reentrant and reusable load modules.
If your stored procedure cannot be reentrant, link-edit it as non-reentrant and non-reusable. The
non-reusable attribute prevents multiple tasks from using a single copy of the stored procedure at the
same time.
2. Specify STAY RESIDENT YES in the CREATE PROCEDURE or ALTER PROCEDURE statement for the
stored procedure. This option makes a reentrant stored procedure remain in storage.
A non-reentrant stored procedure must not remain in storage. You therefore need to specify STAY
RESIDENT NO in the CREATE PROCEDURE or ALTER PROCEDURE statement for a non-reentrant stored
procedure. STAY RESIDENT NO is the default.
Related concepts
Making programs reentrant (Enterprise COBOL for z/OS Programming Guide)
Related reference
Compiler options (COBOL) (Enterprise COBOL for z/OS Programming Guide)
ALTER PROCEDURE (external) (Db2 SQL)
CREATE PROCEDURE (external) (Db2 SQL)
Binder options reference (MVS Program Management: User's Guide and Reference)
Language restricted (Enterprise PL/I for z/OS Compiler and Runtime Migration Guide)
Compile-time option descriptions (PL/I) (Enterprise PL/I for z/OS Programming Guide:)
Reentrancy (XL C/C++ User's Guide)
276 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
• Avoid using statements that terminate the Language Environment enclave when the program ends.
Examples of such statements are STOP or EXIT in a PL/I subprogram, or STOP RUN in a COBOL
subprogram. If the enclave terminates when a stored procedure ends, and the client program calls
another stored procedure that runs as a subprogram, Language Environment must build a new enclave.
As a result, the benefits of coding a stored procedure as a subprogram are lost.
• In COBOL stored procedures that are defined as PROGRAM TYPE SUB and STAY RESIDENT YES, if you
use stored procedure parameters as host variables, set the SQL-INIT-FLAG variable to 0. This variable
is generated by the Db2 precompiler. Setting it to 0 ensures that the SQLDA is updated with the current
addresses.
The following table summarizes the characteristics that define a main program and a subprogram.
/******************************************************************/
/* This C subprogram is a stored procedure that uses linkage */
/* convention GENERAL and receives 3 parameters. */
/******************************************************************/
#pragma linkage(cfunc,fetchable)
#include <stdlib.h>
void cfunc(char p1[11],long *p2,short *p3)
{
/****************************************************************/
/* Declare variables used for SQL operations. These variables */
/* are local to the subprogram and must be copied to and from */
/* the parameter list for the stored procedure call. */
/****************************************************************/
EXEC SQL BEGIN DECLARE SECTION;
char parm1[11];
long int parm2;
short int parm3;
EXEC SQL END DECLARE SECTION;
/*************************************************************/
/* Receive input parameter values into local variables. */
/*************************************************************/
strcpy(parm1,p1);
parm2 = *p2;
parm3 = *p3;
/*************************************************************/
/* Perform operations on local variables. */
/*************************************************************/
⋮
/*************************************************************/
/* Set values to be passed back to the caller. */
/*************************************************************/
strcpy(parm1,"SETBYSP");
parm2 = 100;
parm3 = 200;
/*************************************************************/
/* Copy values to output parameters. */
/*************************************************************/
strcpy(p1,parm1);
*p2 = parm2;
The following code shows an example of coding a C++ stored procedure as a subprogram.
/******************************************************************/
/* This C++ subprogram is a stored procedure that uses linkage */
/* convention GENERAL and receives 3 parameters. */
/* The extern statement is required. */
/******************************************************************/
extern "C" void cppfunc(char p1[11],long *p2,short *p3);
#pragma linkage(cppfunc,fetchable)
#include <stdlib.h>
EXEC SQL INCLUDE SQLCA;
void cppfunc(char p1[11],long *p2,short *p3)
{
/****************************************************************/
/* Declare variables used for SQL operations. These variables */
/* are local to the subprogram and must be copied to and from */
/* the parameter list for the stored procedure call. */
/****************************************************************/
EXEC SQL BEGIN DECLARE SECTION;
char parm1[11];
long int parm2;
short int parm3;
EXEC SQL END DECLARE SECTION;
/*************************************************************/
/* Receive input parameter values into local variables. */
/*************************************************************/
strcpy(parm1,p1);
parm2 = *p2;
parm3 = *p3;
/*************************************************************/
/* Perform operations on local variables. */
/*************************************************************/
⋮
/*************************************************************/
/* Set values to be passed back to the caller. */
/*************************************************************/
strcpy(parm1,"SETBYSP");
parm2 = 100;
parm3 = 200;
/*************************************************************/
/* Copy values to output parameters. */
/*************************************************************/
strcpy(p1,parm1);
*p2 = parm2;
*p3 = parm3;
}
278 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 48. Compatible assembler language declarations for LOBs, ROWIDs, and locators
SQL data type in definition Assembler declaration
ROWID DS HL2,CL40
char data[n+1];
struct
{short len;
char data[n];
} var;
Note:
1. This row does not apply to VARCHAR(n) FOR BIT DATA. BIT DATA is always passed in a structured
representation.
For LOBs, ROWIDs, and locators, the following table shows compatible declarations for the C language.
BLOB(n) struct
{unsigned long length;
char data[n];
} var;
CLOB(n) struct
{unsigned long length;
char var_data[n];
} var;
DBCLOB(n) struct
{unsigned long length;
sqldbchar data[n];
} var;
ROWID struct
{short int length;
char data[40];
} var;
For LOBs, ROWIDs, and locators, the following table shows compatible declarations for COBOL.
Table 50. Compatible COBOL declarations for LOBs, ROWIDs, and locators
SQL data type in definition COBOL declaration
BLOB(n) 01 var.
49 var-LENGTH PIC S9(9) COMP-5.
49 var-DATA PIC X(n).
CLOB(n) 01 var.
49 var-LENGTH PIC S9(9) COMP-5.
49 var-DATA PIC X(n).
DBCLOB(n) 01 var.
49 var-LENGTH PIC S9(9) COMP-5.
49 var-DATA PIC G(n) DISPLAY-1.
ROWID 01 var.
49 var-LEN PIC S9(4) COMP-5.
49 var-DATA PIC X(40).
For LOBs, ROWIDs, and locators, the following table shows compatible declarations for PL/I.
280 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 51. Compatible PL/I declarations for LOBs, ROWIDs, and locators
SQL data type in definition PL/I
01 var,
03 var_LENGTH
BIN FIXED(31),
03 var_DATA
CHAR(n);
If n > 32767:
01 var,
02 var_LENGTH
BIN FIXED(31),
02 var_DATA,
03 var_DATA1(n)
CHAR(32767),
03 var_DATA2
CHAR(mod(n,32767));
01 var,
03 var_LENGTH
BIN FIXED(31),
03 var_DATA
CHAR(n);
If n > 32767:
01 var,
02 var_LENGTH
BIN FIXED(31),
02 var_DATA,
03 var_DATA1(n)
CHAR(32767),
03 var_DATA2
CHAR(mod(n,32767));
01 var,
03 var_LENGTH
BIN FIXED(31),
03 var_DATA
GRAPHIC(n);
If n > 16383:
01 var,
02 var_LENGTH
BIN FIXED(31),
02 var_DATA,
03 var_DATA1(n)
GRAPHIC(16383),
03 var_DATA2
GRAPHIC(mod(n,16383));
282 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
DSNREXRR
Repeatable read (RR)
DSNREXRS
Read stability (RS)
DSNREXCS
Cursor stability (CS)
DSNREXUR
Uncommitted read (UR)
This topic shows an example of a REXX stored procedure that executes Db2 commands. The stored
procedure performs the following actions:
• Receives one input parameter, which contains a Db2 command.
• Calls the IFI COMMAND function to execute the command.
• Extracts the command result messages from the IFI return area and places the messages in a created
temporary table. Each row of the temporary table contains a sequence number and the text of one
message.
• Opens a cursor to return a result set that contains the command result messages.
• Returns the unformatted contents of the IFI return area in an output parameter.
The following example shows the definition of the stored procedure.
The following example shows the COMMAND stored procedure that executes Db2 commands.
/* REXX */
PARSE UPPER ARG CMD /* Get the DB2 command text */
/* Remove enclosing quotation marks */
IF LEFT(CMD,1) = "'" & RIGHT(CMD,1) = "'" THEN
CMD = SUBSTR(CMD,2,LENGTH(CMD)-2)
ELSE
IF LEFT(CMD,1) = '"' & RIGHT(CMD,1) = '"' THEN
CMD = SUBSTR(CMD,2,LENGTH(CMD)-2)
COMMAND = SUBSTR("COMMAND",1,18," ")
/****************************************************************/
/* Set up the IFCA, return area, and output area for the */
/* IFI COMMAND call. */
/****************************************************************/
IFCA = SUBSTR('00'X,1,180,'00'X)
IFCA = OVERLAY(D2C(LENGTH(IFCA),2),IFCA,1+0)
IFCA = OVERLAY("IFCA",IFCA,4+1)
RTRNAREASIZE = 262144 /*1048572*/
RTRNAREA = D2C(RTRNAREASIZE+4,4)LEFT(' ',RTRNAREASIZE,' ')
OUTPUT = D2C(LENGTH(CMD)+4,2)||'0000'X||CMD
BUFFER = SUBSTR(" ",1,16," ")
/****************************************************************/
/* Make the IFI COMMAND call. */
/****************************************************************/
ADDRESS LINKPGM "DSNWLIR COMMAND IFCA RTRNAREA OUTPUT"
WRC = RC
RTRN= SUBSTR(IFCA,12+1,4)
REAS= SUBSTR(IFCA,16+1,4)
TOTLEN = C2D(SUBSTR(IFCA,20+1,4))
/****************************************************************/
/* Set up the host command environment for SQL calls. */
/****************************************************************/
"SUBCOM DSNREXX" /* Host cmd env available? */
/****************************************************************/
/* Set up SQL statements to insert command output messages */
/* into a temporary table. */
/****************************************************************/
SQLSTMT='INSERT INTO SYSIBM.SYSPRINT(SEQNO,TEXT) VALUES(?,?)'
ADDRESS DSNREXX "EXECSQL DECLARE C1 CURSOR FOR S1"
IF SQLCODE ¬= 0 THEN CALL SQLCA
ADDRESS DSNREXX "EXECSQL PREPARE S1 FROM :SQLSTMT"
IF SQLCODE ¬= 0 THEN CALL SQLCA
/****************************************************************/
/* Extract messages from the return area and insert them into */
/* the temporary table. */
/****************************************************************/
SEQNO = 0
OFFSET = 4+1
DO WHILE ( OFFSET < TOTLEN )
LEN = C2D(SUBSTR(RTRNAREA,OFFSET,2))
SEQNO = SEQNO + 1
TEXT = SUBSTR(RTRNAREA,OFFSET+4,LEN-4-1)
ADDRESS DSNREXX "EXECSQL EXECUTE S1 USING :SEQNO,:TEXT"
IF SQLCODE ¬= 0 THEN CALL SQLCA
OFFSET = OFFSET + LEN
END
/****************************************************************/
/* Set up a cursor for a result set that contains the command */
/* output messages from the temporary table. */
/****************************************************************/
SQLSTMT='SELECT SEQNO,TEXT FROM SYSIBM.SYSPRINT ORDER BY SEQNO'
ADDRESS DSNREXX "EXECSQL DECLARE C2 CURSOR FOR S2"
IF SQLCODE ¬= 0 THEN CALL SQLCA
ADDRESS DSNREXX "EXECSQL PREPARE S2 FROM :SQLSTMT"
IF SQLCODE ¬= 0 THEN CALL SQLCA
/****************************************************************/
/* Open the cursor to return the message output result set to */
/* the caller. */
/****************************************************************/
ADDRESS DSNREXX "EXECSQL OPEN C2"
IF SQLCODE ¬= 0 THEN CALL SQLCA
S_RC = RXSUBCOM('DELETE','DSNREXX','DSNREXX') /* REMOVE CMD ENV */
EXIT SUBSTR(RTRNAREA,1,TOTLEN+4)
/****************************************************************/
/* Routine to display the SQLCA */
/****************************************************************/
SQLCA:
SAY 'SQLCODE ='SQLCODE
SAY 'SQLERRMC ='SQLERRMC
SAY 'SQLERRP ='SQLERRP
SAY 'SQLERRD ='SQLERRD.1',',
|| SQLERRD.2',',
|| SQLERRD.3',',
|| SQLERRD.4',',
|| SQLERRD.5',',
|| SQLERRD.6
SAY 'SQLWARN ='SQLWARN.0',',
|| SQLWARN.1',',
|| SQLWARN.2',',
|| SQLWARN.3',',
|| SQLWARN.4',',
|| SQLWARN.5',',
|| SQLWARN.6',',
|| SQLWARN.7',',
|| SQLWARN.8',',
|| SQLWARN.9',',
|| SQLWARN.10
SAY 'SQLSTATE='SQLSTATE
SAY 'SQLCODE ='SQLCODE
EXIT 'SQLERRMC ='SQLERRMC';' ,
|| 'SQLERRP ='SQLERRP';' ,
|| 'SQLERRD ='SQLERRD.1',',
|| SQLERRD.2',',
|| SQLERRD.3',',
|| SQLERRD.4',',
|| SQLERRD.5',',
|| SQLERRD.6';' ,
|| 'SQLWARN ='SQLWARN.0',',
|| SQLWARN.1',',
284 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
|| SQLWARN.2',',
|| SQLWARN.3',',
|| SQLWARN.4',',
|| SQLWARN.5',',
|| SQLWARN.6',',
|| SQLWARN.7',',
|| SQLWARN.8',',
|| SQLWARN.9',',
|| SQLWARN.10';' ,
|| 'SQLSTATE='SQLSTATE';'
Related reference
Calling a stored procedure from a REXX procedure
The format of the parameters that you pass in the CALL statement in a REXX procedure must be
compatible with the data types of the parameters in the CREATE PROCEDURE statement.
TSO/E services available under IKJTSOEV (TSO/E Programming Services)
Procedure
To modify an external stored procedure definition:
1. Issue one of the following:
• FL 507The CREATE PROCEDURE statement with the OR REPLACE clause and the SPECIFIC clause
in the following cases:
– When the parameter list of the existing procedure includes a table parameter.
– When the CREATE statement specifies changes to the parameter list other than parameter
names.
• The ALTER PROCEDURE statement with the appropriate options.
This new definition replaces the existing definition.
2. Prepare the external stored procedure again, as you did when you originally created the external
stored procedure.
Example
Suppose that an existing C stored procedure was defined with the following statement:
Assume that you need to make the following changes to the stored procedure definition:
• The stored procedure selects data from Db2 tables but does not modify Db2 data.
• The parameters can have null values, and the stored procedure can return a diagnostic string.
• The length of time that the stored procedure runs is unlimited.
ALTER PROCEDURE B
READS SQL DATA
ASUTIME NO LIMIT
PARAMETER STYLE SQL
WLM ENVIRONMENT (PAYROLL,*);
Related tasks
Creating external stored procedures
An external stored procedure is a procedure that is written in a host language and can contain SQL
statements. The source code for external procedures is separate from the definition.
Related reference
ALTER PROCEDURE (external) (Db2 SQL)
Procedure
To create an external SQL procedure:
1. Use one of the following methods to create the external SQL procedure:
• IBM Data Studio. See Developing database routines (IBM Data Studio, IBM Optim Database
Administrator, IBM infoSphere Data Architect, IBM Optim Development Studio).
• Use JCL
286 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
• Use the Db2 for z/OS SQL procedure processor (DSNTPSMP)
The preceding methods that you use to create an external SQL procedure perform the following
actions:
• Convert the external SQL procedure source statements into a C language program by using the Db2
precompiler
• Create an executable load module and a Db2 package from the C language program.
• Define the external SQL procedure to Db2 by issuing a CREATE PROCEDURE statement either
statically or dynamically.
2. Authorize the appropriate users to use the stored procedure by issuing the GRANT EXECUTE
statement.
Example
For examples of how to prepare and run external SQL procedures, see “Sample programs to help you
prepare and run external SQL procedures” on page 302.
Related concepts
SQL procedures
An SQL procedure is a stored procedure that contains only SQL statements.
Related tasks
Implementing Db2 stored procedures (Db2 Administration Guide)
Related reference
CREATE PROCEDURE (SQL - external) (deprecated) (Db2 SQL)
GRANT (function or procedure privileges) (Db2 SQL)
Procedure
To migrate an external SQL procedure to a native SQL procedure, complete the following steps:
1. Find and save the existing CREATE PROCEDURE and GRANT EXECUTE statements for the existing
external SQL procedure.
In the preceding example, if P1 is an external SQL procedure, C1 is a parameter. For native SQL
procedures, C1 is a column in table T1. If such a column does not exist, C1 is a parameter.
4. Issue the same GRANT EXECUTE statements that you used to originally grant privileges for this stored
procedure.
5. Increase the value of the TIME parameter on the job statement for applications that call stored
procedures.
Important: This change is necessary because time for SQL external stored procedures is charged to
the WLM address space, while time for native SQL stored procedures is charged to the address space
of the task.
6. Test your new native SQL procedure.
Related tasks
Using the Db2 precompiler to assist you in converting an external SQL procedure to a native SQL
procedure
The Db2 precompiler can be useful when considering any conversion of an external SQL procedure to a
native SQL procedure.
Creating native SQL procedures
A native SQL procedure is a procedure whose body is written entirely in SQL and is created by issuing a
single SQL statement, CREATE PROCEDURE.
Related reference
CREATE PROCEDURE (SQL - native) (Db2 SQL)
GRANT (function or procedure privileges) (Db2 SQL)
DROP (Db2 SQL)
Using the Db2 precompiler to assist you in converting an external SQL procedure to a native SQL procedure
The Db2 precompiler can be useful when considering any conversion of an external SQL procedure to a
native SQL procedure.
Procedure
To inspect the quality of native SQL PL source coding using the Db2 precompiler:
1. Copy the original SQL PL source code to a FB80 data set. Reformat the source as needed to fit within
the precompiler margins.
288 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
2. Precompile the SQL PL source by executing program DSNHPSM with the HOST(SQLPL) option.
3. Inspect the produced listing (SYSPRINT). Pay attention to error and warning messages.
4. Modify the SQL PL source to address coding problems that are identified by messages in the listing.
5. Repeat steps “1” on page 288 - “4” on page 289 until all error and warning messages are resolved.
Then address informational messages as needed.
6. Copy the modified SQL PL source file back to its original source format, reformatting as needed.
Results
Sample JCL DSNTEJ67 demonstrates this process for an external SQL procedure that was produced using
the Db2 SQL procedure processor DSNTPSMP.
Related tasks
Migrating an external SQL procedure to a native SQL procedure
You can migrate an existing external SQL procedure, which is deprecated, to a native SQL procedure by
dropping the existing procedure and creating it again as a native SQL procedure. Native SQL procedures
are more fully supported, easier to maintain, and typically perform better than external SQL procedures,
which are deprecated.
Related reference
Sample programs to help you prepare and run external SQL procedures
Db2 provides sample jobs to help you prepare and run external SQL procedures. All samples are in data
set DSN1210.SDSNSAMP. Before you can run the samples, you must customize them for your installation.
Any privileges that are required for the SQL Syntax varies depending on the SQL procedure
statements and that are contained within the body
SQL procedure body. These privileges must be
associated with the OWNER authorization-id that
is specified in your bind options. The default owner
is the user that is invoking DSNTPSMP.
Procedure
To create an external SQL procedure by using DSNTPSMP:
1. Write an application program that calls DSNTPSMP. Include the following items in your program:
• A CLOB host variable that contains a CREATE PROCEDURE statement for the external SQL procedure.
That statement should include the FENCED keyword or the EXTERNAL keyword, and the procedure
body, which is written in SQL.
Alternatively, instead of defining a host variable for the CREATE PROCEDURE statement, you can
store the statement in a data set member.
• An SQL CALL statement with the BUILD function. The CALL statement should use the proper syntax
for invoking DSNTPSMP.
Pass the SQL procedure source to DSNTPSMP as one of the following input parameters:
SQL-procedure-source
Use this parameter if you defined a host variable in your application to contain the CREATE
PROCEDURE statement.
source-data-set-name
Use this parameter if you stored the CREATE PROCEDURE statement in a data set.
• Based on the return value from the CALL statement, issue either an SQL COMMIT or a ROLLBACK
statement. If the return value is 0 or 4, issue a COMMIT statement. Otherwise, issue a ROLLBACK
statement.
You must process the result set before issuing the COMMIT or ROLLBACK statement.
A QUERYLEVEL request must be followed by the COMMIT statement.
2. Precompile, compile, and link-edit the application program.
3. Bind a package for the application program.
4. Run the application program.
Related concepts
SQL procedure body
290 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
The body of an SQL procedure contains one or more SQL statements. In the SQL procedure body, you can
also declare and use variables, conditions, return codes, statements, cursors, and handlers.
Related reference
CREATE PROCEDURE (SQL - external) (deprecated) (Db2 SQL)
Notes:
1
APPLENV specifies the application environment in which DSNTPSMP runs. To ensure that DSNTPSMP
always uses the correct data sets and parameters for preparing each external SQL procedure, you
can set up different application environments for preparing stored procedures with different program
preparation requirements. For example, if all payroll applications use the same set of data sets during
program preparation, you could set up an application environment called PAYROLL for preparing only
payroll applications. The startup procedure for PAYROLL would point to the data sets that are used for
payroll applications.
DB2SSN specifies the Db2 subsystem name.
NUMTCB specifies the number of programs that can run concurrently in the address space. You should
always set NUMTCB to 1 to ensure that executions of DSNTPSMP occur serially.
2
WLMTPSMP specifies the address space in which DSNTPSMP runs.
DYNAMNBR reserves space for dynamic allocation of data sets during the SQL procedure preparation
process.
3
STEPLIB specifies the Db2 load libraries, the z/OS C/C++ compiler library, and the Language
Environment run time library that DSNTPSMP uses when it runs. At least one library must not be
APF authorized.
4
SYSEXEC specifies the library that contains the REXX exec DSNTPSMP.
5
SQLDBRM is an output data set that specifies the library into which DSNTPSMP puts the DBRM that it
generates when it precompiles your external SQL procedure.
6
SQLCSRC is an output data set that specifies the library into which DSNTPSMP puts the C source code
that it generates from the external SQL procedure source code. This data set should have a logical
record length of 80.
7
SQLLMOD is an output data set that specifies the library into which DSNTPSMP puts the load module
that it generates when it compiles and link-edits your external SQL procedure.
8
SQLLIBC specifies the library that contains standard C header files. This library is used during
compilation of the generated C program.
9
SQLLIBL specifies the following libraries, which DSNTPSMP uses when it link-edits the external SQL
procedure:
• Language Environment link-edit library
• Db2 load library
10
SYSMSGS specifies the library that contains messages that are used by the C prelink-edit utility.
292 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
11
CFGTPSMP specifies an optional data set that you can use to customize DSNTPSMP, including
specifying the compiler level. For details on all of the options that you can set in this file and how
to set them, see the DSNTPSMP CLIST comments.
12
The DD statements that follow describe work file data sets that are used by DSNTPSMP.
Related tasks
Converting from the AMI-based MQ functions to the MQI-based MQ functions (Db2 Installation and
Migration)
, alter-statement , source-data-set-name ,
empty-string empty-string
empty-string empty-string
294 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
DESTROY
Deletes the following objects for an existing external SQL procedure:
• The DBRM, from the data set that DD name SQLDBRM points to
• The load module, from the data set that DD name SQLLMOD points to
• The C language source code for the external SQL procedure, from the data set that DD name
SQLCSRC points to
• The stored procedure package
• The stored procedure definition
The following input parameter is required for the DESTROY function:
SQL-procedure name
ALTER
Updates the registration for an existing external SQL procedure.
The following input parameters are required for the ALTER function:
SQL-procedure name
alter-statement
ALTER_REBUILD
Updates an existing external SQL procedure.
The following input parameters are required for the ALTER_REBUILD function:
SQL-procedure name
SQL-procedure-source or source-data-set-name
ALTER_REBUILD_DEBUG
Updates an existing external SQL procedure, and includes the preparation necessary to debug the
external SQL procedure with the SQL Debugger and the Unified Debugger.
The following input parameters are required for the ALTER_REBUILD_DEBUG function:
SQL-procedure name
SQL-procedure-source or source-data-set-name
ALTER_REBIND
Updates the registration and binds the SQL package for an existing external SQL procedure.
The following input parameters are required for the ALTER_REBIND function:
SQL-procedure name
alter-statement
QUERYLEVEL
Obtains the interface level of the build utility invoked. No other input is required.
SQL-procedure-name
A VARCHAR(261) input parameter that specifies the external SQL procedure name.
The name can be qualified or unqualified. The name must match the procedure name that is
specified within the CREATE PROCEDURE statement that is provided in SQL-procedure-source or that
is obtained from source-data-set-name. In addition, the name must match the procedure name that
is specified within the ALTER PROCEDURE statement that is provided in alter-statement. Do not mix
qualified and unqualified references.
SQL-procedure-source
A CLOB(2M) input parameter that contains the CREATE PROCEDURE statement for the external SQL
procedure. If you specify an empty string for this parameter, you need to specify the name source-
data-set-name of a data set that contains the external SQL procedure source code.
296 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
998
APF environment setup error
997
DSNREXX setup error
996
Global temporary table setup error
995
Internal REXX programming error
1.2x
Where x is a digit between 0 and 9. Level of DSNTPSMP when request is QUERYLEVEL. The calling
application can retrieve the result set for additional information about the release and service
level and then issue the required SQL COMMIT statement.
Related reference
Descriptions of SQL processing options
You can specify any SQL processing options regardless of whether you use the Db2 precompiler or the
Db2 coprocessor. However, the Db2 coprocessor might ignore certain options because host language
compiler options exist that provide the same information.
BIND and REBIND options for packages, plans, and services (Db2 Commands)
Compiler Options (C/C++) (XL C/C++ User's Guide)
Binder options reference (MVS Program Management: User's Guide and Reference)
DSNTPSMP REBUILD function: Call DSNTPSMP to re-create an existing external SQL procedure. The
information that DSNTPMSP needs is listed in the following table:
If you want to re-create an existing external SQL procedure for debugging with the SQL Debugger and the
Unified Debugger, use the following CALL statement, which includes the REBUILD_DEBUG function:
DSNTPSMP REBIND function: Call DSNTPSMP to rebind the package for an existing external SQL
procedure. The information that DSNTPMSP needs is listed in the following table:
298 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 56. The functions DSNTPSMP needs to REBIND an SQL procedure
Function REBIND
ExternalSQL procedure name MYSCHEMA.SQLPROC
Bind options VALIDATE(RUN), ISOLATION(RR)
Return value String returned in varying-length host variable returnval
Procedure
To create an external SQL procedure by using JCL, include the following job steps in your JCL job:
1. Issue a CREATE PROCEDURE statement that includes either the FENCED keyword or the EXTERNAL
keyword and the procedure body, which is written in SQL.
Alternatively, you can issue the CREATE PROCEDURE statement dynamically by using an application
such as SPUFI, DSNTEP2, DSNTIAD, or the command line processor.
Tip: If the routine body of the CREATE PROCEDURE statement contains embedded semicolons,
change the default SQL terminator character from a semicolon to some other special character, such
as the percent sign (%).
This statement defines the stored procedure to Db2. Db2 stores the definition in the Db2 catalog.
2. Run program DSNHPC with the HOST(SQL) option.
This program converts the external SQL procedure source statements into a C language program.
DSNHPC also writes a new CREATE PROCEDURE statement in the data set that is specified in the
SYSUT1 DD statement.
3. Precompile, compile, and link-edit the generated C program by using one of the following techniques:
• The Db2 precompiler and JCL instructions to compile and link-edit the program
• The SQL statement coprocessor
When you perform this step, specify the following settings:
• Give the DBRM the same name as the name of the load module for the external SQL procedure.
• Specify MARGINS(1,80) for the MARGINS SQL processing option.
• Specify the NOSEQ compiler option.
This process produces an executable C language program.
4. Bind the resulting DBRM into a package.
Example
Suppose that you define an external SQL procedure by issuing the following CREATE PROCEDURE
statement dynamically:
300 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
DECLARE SQLCODE INTEGER;
DECLARE SQLSTATE CHAR(5);
DECLARE EXIT HANDLER FOR SQLEXCEPTION SET PSQLCODE = SQLCODE;
SELECT
FIRSTNME
, MIDINIT
, LASTNAME
, WORKDEPT
, HIREDATE
, SALARY
INTO PFIRSTNME
, PMIDINIT
, PLASTNAME
, PWORKDEPT
, PHIREDATE
, PSALARY
FROM EMP
WHERE EMPNO = PEMPNO
;
END
You can use JCL that is similar to the following JCL to prepare the procedure:
Related concepts
SQL procedure body
The body of an SQL procedure contains one or more SQL statements. In the SQL procedure body, you can
also declare and use variables, conditions, return codes, statements, cursors, and handlers.
The Db2 command line processor (Db2 Commands)
Related tasks
Changing SPUFI defaults
Sample programs to help you prepare and run external SQL procedures
Db2 provides sample jobs to help you prepare and run external SQL procedures. All samples are in data
set DSN1210.SDSNSAMP. Before you can run the samples, you must customize them for your installation.
Deprecated function: External SQL procedures are deprecated and not as fully supported as native
SQL procedures. For best results, create native SQL procedures instead. For more information, see
“Creating native SQL procedures” on page 226 and “Migrating an external SQL procedure to a native
SQL procedure” on page 287.
See the prolog of each sample for specific instructions.
The following table lists the sample jobs that Db2 provides for external SQL procedures.
302 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 57. External SQL procedure samples shipped with Db2 (continued)
Member that
contains source
code Contents Purpose
DSN8ES2 External SQL A stored procedure that accepts one input parameter
procedure and returns two output parameters. The input parameter
specifies a bonus to be awarded to managers. The
external SQL procedure updates the BONUS column of
DSN1210.SDSNSAMP. If no SQL error occurs when the
external SQL procedure runs, the first output parameter
contains the total of all bonuses awarded to managers and the
second output parameter contains a null value. If an SQL error
occurs, the second output parameter contains an SQLCODE.
DSN8ED4 C program Calls the SQL procedure processor, DSNTPSMP, to prepare
DSN8ES2 for execution
DSN8WLMP JCL procedure A sample startup procedure for the WLM-established stored
procedures address space in which DSNTPSMP runs
DSN8ED5 C program Calls external SQL procedure DSN8ES2
DSNTEJ65 JCL job Prepares and executes programs DSN8ED4 and DSN8ED5.
DSNTEJ65 uses DSNTPSMP, the SQL procedure processor,
which requires that the default EBCDIC CCSID that is used
by Db2 also be compatible with the C compiler. Do not
run DSNTEJ65 if the default EBCDIC CCSID for Db2 is not
compatible with the C compiler. Examples of incompatible
CCSIDs include 290, 930, 1026, and 1155.
DSNTIJRT JCL job Prepares a Db2 for z/OS server for operation with the SQL
Debugger and the Unified Debugger
DSN8ED4
Demonstrates how to use an application program to call DSNTPSMP, the Db2 SQL Procedures Processor.
/********************************************************************* 00010000
* Module name = DSN8ED4 (sample program) * 00020000
* * 00030000
* DESCRIPTIVE NAME: Sample client for: * 00040000
* DSNTPSMP (DB2 SQL Procedures Processor) * 00050000
* * 00060000
* LICENSED MATERIALS - PROPERTY OF IBM * 00070000
* 5625-DB2 * 00080000
* (C) COPYRIGHT 1982, 2003 IBM CORP. ALL RIGHTS RESERVED. * 00090000
* * 00100000
* STATUS = VERSION 8 * 00110000
* * 00120000
* Function: Demonstrates how to use an application program to call * 00130000
* DSNTPSMP, the DB2 SQL Procedures Processor. DSN8ED4 * 00140000
* collects and passes user-provided SQL Procedure source * 00150000
* code and prep options to DSNTPSMP, and outputs the * 00160000
* report(s), if any, returned from DSNTPSMP by result set. * 00170000
* * 00180000
304 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* * 01010000
* External References: * 01020000
* - Routines/Services: DSNTIAR: DB2 msg text formatter * 01030000
* - Data areas : None * 01040000
* - Control blocks : None * 01050000
* * 01060000
* * 01070000
* Pseudocode: * 01080000
* DSN8ED4: * 01090000
* - call getCallParms to receive and validate call parm arguments* 01100000
* - case action * 01110000
* - when BUILD, call getReBuildData * 01120000
* - when DESTROY, call getDestroyData * 01130000
* - when REBUILD, call getReBuildData * 01140000
* - when REBIND, call getRebindData * 01150000
* - when QUERYLEVEL, call getLevelData * 01160003
* - otherwise call issueInvalidActionError * 01170000
* - call connectToLocation * 01180000
* - call setAuthID to set the current authorization id @pq53353 * 01190003
* - call callDSNTPSMP to invoke the DB2 SQL Procedures Processor * 01200000
* - call processDSNTPSMPresultSet to write reports from DSNTPSMP * 01210000
* - If no errors, call processSqlCommit to commit work @04 * 01220000
* Else call processSqlRollback to undo work @04 * 01230000
* End DSN8ED4 * 01240000
* * 01250000
* * 01260000
* Change activity = * 01270000
* PQ46962 03/28/2001 changed line feed character to hex 25 @01 * 01280000
* PQ43444 04/12/2001 Disable LEOPTS DD (LE options are not @02 * 01290000
* processed by DSNTPSMP). Remission the @02 * 01300000
* leOptions hostvar as alterStmt. @02 * 01310000
* PQ56601 03/06/2002 Trim +/- continuation characters from @03 * 01320000
* BIND options to prevent BIND errors. @03 * 01330000
* These characters are often used to con- @03 * 01340000
* tinue BIND statements being processed @03 * 01350000
* by the DB2 DSN command processor (which @03 * 01360000
* uses TSO i/o services that recognize @03 * 01370000
* them as continuation characters) but @03 * 01380000
* they are not otherwise valid in DB2 @03 * 01390000
* commands. @03 * 01400000
* PQ61782 07/16/2002 Distinguish between DSNTPSMP return code @04 * 01410000
* and DSN8ED4 return code; Issue SQL COMMIT@04 * 01420000
* when DSNTPSMP returns rc = 0 or rc = 4; @04 * 01430000
* Otherwise issue SQL ROLLBACK @04 * 01440000
* D55199 12/08/2003 Adjust to use DSNTPSMP 1.2x interface @05 * 01450004
* D56462 02/12/2004 Allocate maximum of 6 output reports @06 * 01460005
*********************************************************************/ 01470000
01480000
/********************** C library definitions ***********************/ 01490000
#include <errno.h> 01500000
#include <stdio.h> 01510000
#include <stdlib.h> 01520000
#include <string.h> 01530000
01540000
/**************************** Constants *****************************/ 01550000
#define NULLCHAR '\0' /* Null character */ 01560000
#define RETNRM 0 /* Normal return code @04*/ 01570000
#define RETWRN 4 /* Warning return code */ 01580000
#define RETERR 8 /* Error return code */ 01590000
#define RETSEV 12 /* Severe error return code */ 01600000
#define INTERFACE "1.2" /* DSNTPSMP innterface level */ 01610003
01620000
enum flag {No, Yes}; /* Settings for flags */ 01630000
01640000
01650000
/***************** Input: SQL Procedure Source Code *****************/ 01660000
FILE *sqlInFile; /* Pointer to SQL source DD */ 01670000
01680000
01690000
/*********** Output: DB2 SQL Procedures Processor Reports ***********/ 01700000
FILE *reportDD; /* Pointer to curr report DD */ 01710000
char reportDDName[12]; /* For generated DD name */ 01720000
unsigned short reportLRECL; /* length req'd for output rec*/ 01730000
01740000
01750000
/************************ Working variables *************************/ 01760000
unsigned short resultSetReturned = 0;/* DSNTPSMP result set stat@04*/ 01770000
long int DSNTPSMP_rc = -1; /* DSNTPSMP return code @04*/ 01780000
long int rc = 0; /* program return code */ 01790000
char levelquery ='N'; /* Is this a level check? @05*/ 01800004
01810000
01820000
306 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
void issueDataSetClosingError /* Handler for ds close error */ 02650000
( char *DDname, /* - in: name of errant DD */ 02660000
int LEerrno /* - in: LE diagnostic errno */ 02670000
); 02680000
void issueDataSetOpeningError /* Handler for ds open error */ 02690000
( char *DDname, /* - in: name of errant DD */ 02700000
int LEerrno /* - in: LE diagnostic errno */ 02710000
); 02720000
void issueDataSetReadingError /* Handler for ds read error */ 02730000
( char *DDname, /* - in: name of errant DD */ 02740000
int LEerrno /* - in: LE diagnostic errno */ 02750000
); 02760000
void issueInvalidCallParmCountError /* Handler for parm count err */ 02770000
( int argc /* - in: no. parms received */ 02780000
); 02790000
void issueInvalidActionError /* Handler for unknown action */ 02800000
( char *action /* - in: action specified */ 02810000
); 02820000
void issueInvalidLevelError /* Handler for wrong DSNTPSMP */ 02830003
( char *level /* - in: level encountered */ 02840003
); 02850003
void issueInvalidDDnumError /* Handler for unknown DD seq */ 02860000
( short invalidDDnum /* - in: invalid DD sequ. no. */ 02870000
); 02880000
void issueInvalidParmLengthError /* Handler for parm len error */ 02890000
( char *parmName, /* - in: identify of parm */ 02900000
int minLength, /* - in: min valid length */ 02910000
int maxLength /* - in: max valid length */ 02920000
); 02930000
void issueSqlError /* Handler for SQL error */ 02940000
( char *locMsg /* - in: Call location */ 02950000
); 02960000
02970000
02980000
int main /* DSN8ED4 driver */ 02990000
( int argc, /* - Input argument count */ 03000000
char *argv[] /* - Input argument vector */ 03010000
) 03020000
/******************************************************************* 03030000
* Main Driver: * 03040000
* - Gets arguments for call parms * 03050000
* - Gets processing options and data * 03060000
* - Connects to remote location, if one was specified * 03070000
* - Calls the DB2 SQL Procedure Processor, DSNTSPMP * 03080000
* - Processes any result set(s) returned from DSNTPSMP * 03090000
* * 03100000
*******************************************************************/ 03110000
{ /***************************************************************** 03120000
* Extract the following information from the call parms: * 03130000
* (1) DB2 location name where where SQL Procedure is to be built,* 03140000
* destroyed, rebuilt, rebound, etc.) * 03150000
* (2) DB2 SQL Procedure Processor action (Build,Destroy,...) * 03160000
* (3) Name of SQL Procedure to be built, destroyed, rebound, etc.* 03170000
*****************************************************************/ 03180000
getCallParms( argc,argv ); 03190000
03200000
/***************************************************************** 03210000
* Collect DSNTPSMP parms appropriate for the user-passed action * 03220000
*****************************************************************/ 03230000
if( rc < RETSEV ) 03240000
{ if( memcmp( action,"BUILD",5 ) == 0 ) 03250000
{ getReBuildData(); 03260000
} 03270000
else if( memcmp( action,"DESTROY",7 ) == 0 ) 03280000
{ getDestroyData(); 03290000
} 03300000
else if( memcmp( action,"REBUILD",7 ) == 0 ) 03310000
{ getReBuildData(); 03320000
} 03330000
else if( memcmp( action,"REBIND",6 ) == 0 ) 03340000
{ getRebindData(); 03350000
} 03360000
else if( memcmp( action,"QUERYLEVEL",10 ) == 0 ) 03370003
{ getLevelData(); 03380003
levelquery='Y'; 03390003
} 03400003
else 03410000
{ issueInvalidActionError( action ); 03420000
} 03430000
} 03440000
03450000
/***************************************************************** 03460000
308 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
04290000
} /* end of getCallParms */ 04300000
04310000
04320000
void getReBuildData( void ) /* Get SQL Proc re/build data */ 04330000
/******************************************************************* 04340000
* Collects the prep options and source data needed by DSNTPSMP to * 04350000
* perform a BUILD or REBUILD operation. * 04360000
*******************************************************************/ 04370000
{ 04380000
/***************************************************************** 04390000
* Get program prep, bind, and runtime options * 04400000
*****************************************************************/ 04410000
getOptions( precompOptions,255,"PCOPTS" ); 04420000
if( rc < RETSEV ) 04430000
getOptions( compileOptions,255,"COPTS" ); 04440000
if( rc < RETSEV ) 04450000
getOptions( prelinkOptions,255,"PLKDOPTS" ); 04460000
if( rc < RETSEV ) 04470000
getOptions( linkOptions,255,"LKEDOPTS" ); 04480000
if( rc < RETSEV ) 04490000
getOptions( bindOptions,1024,"BINDOPTS" ); 04500000
/* if( rc < RETSEV ) @02*/ 04510000
/* getOptions( LeOptions,254,"LEOPTS" ); @02*/ 04520000
04530000
/***************************************************************** 04540000
* Get the source for the SQL procedure to be prepared * 04550000
*****************************************************************/ 04560000
if( rc < RETSEV ) 04570000
getSqlSource(); 04580000
} /* end of getReBuildData */ 04590000
04600000
04610000
void getDestroyData( void ) /* Get SQL Proc destroy data */ 04620000
/******************************************************************* 04630000
* Gets the name of the package to be freed by DSNTPSMP during a * 04640000
* DESTROY operation. * 04650000
*******************************************************************/ 04660000
{ 04670000
/***************************************************************** 04680000
* Set program prep and runtime options to NULLCHAR * 04690000
*****************************************************************/ 04700000
sqlSource.length = 0; /*@05*/ 04710004
sqlSource.data[0] = NULLCHAR; /*@05*/ 04720004
precompOptions[0] = NULLCHAR; 04730000
compileOptions[0] = NULLCHAR; 04740000
prelinkOptions[0] = NULLCHAR; 04750000
linkOptions[0] = NULLCHAR; 04760000
alterStmt[0] = NULLCHAR; /*@02*/ 04770000
sqlSourceDsn[0] = NULLCHAR; 04780000
outputString[0] = NULLCHAR; 04790000
04800000
/***************************************************************** 04810000
* Get name of package to free * 04820000
*****************************************************************/ 04830000
getOptions( bindOptions,1024,"BINDOPTS" ); 04840000
04850000
} /* end of getDestroyData */ 04860000
04870000
04880000
void getRebindData( void ) /* Rebind an SQL Procedure */ 04890000
/******************************************************************* 04900000
* Gets the name of the package to be rebound by DSNTPSMP during a * 04910000
* REBIND operation. * 04920000
*******************************************************************/ 04930000
{ 04940000
/***************************************************************** 04950000
* Set program prep and runtime options to NULLCHAR * 04960000
*****************************************************************/ 04970000
sqlSource.length = 0; /*@05*/ 04980004
sqlSource.data[0] = NULLCHAR; /*@05*/ 04990004
precompOptions[0] = NULLCHAR; 05000000
compileOptions[0] = NULLCHAR; 05010000
prelinkOptions[0] = NULLCHAR; 05020000
linkOptions[0] = NULLCHAR; 05030000
alterStmt[0] = NULLCHAR; /*@02*/ 05040000
sqlSourceDsn[0] = NULLCHAR; 05050000
outputString[0] = NULLCHAR; 05060000
05070000
/***************************************************************** 05080000
* Get parameters to pass for rebind * 05090000
*****************************************************************/ 05100000
310 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
05930000
void getSqlSource( void ) /* Read SQL Procedure Source */ 05940000
/******************************************************************* 05950000
* Reads up to 2M bytes of SQL Procedure source code from the * 05960000
* SQLIN DD. * 05970000
*******************************************************************/ 05980000
{ char sourceRec[80]; /* Source file input record */ 05990000
short int recordLength = 0; /* Length of record */ 06000000
unsigned short moreRecords = Yes; /* EOF indicator */ 06010000
06020000
/***************************************************************** 06030000
* Open the data set having the source for the SQL Procedure * 06040000
*****************************************************************/ 06050000
errno = 0; /* clear LE errno */ 06060000
sqlInFile = fopen( "DD:SQLIN", 06070000
"rb,lrecl=80,type=record" ); 06080000
if( sqlInFile == NULL ) 06090000
issueDataSetOpeningError( "DD:SQLIN",errno ); 06100000
06110000
while( moreRecords == Yes && rc < RETSEV ) 06120000
{ recordLength 06130000
= fread( sourceRec, /* Read into source rec area */ 06140000
1, /* ..1 record */ 06150000
80, /* ..of 80 bytes */ 06160000
sqlInFile ); /* ..from SQL Proc source file*/ 06170000
06180000
if( ferror(sqlInFile) ) /* Handle IO errors */ 06190000
issueDataSetReadingError( "DD:SQLIN",errno ); 06200000
06210000
else if( feof(sqlInFile) ) /* Handle EOF */ 06220000
moreRecords = No; 06230000
/* Discard bytes 73-80, strip */ 06240000
else /* trailing blanks,add NL char*/ 06250000
{ sourceRec[72] = NULLCHAR; 06260000
trimTrailingBlanks( sourceRec ); 06270000
strncat( sourceRec,"\x25",1 ); 06280000
strcat( sqlSource.data, sourceRec ); 06290000
sqlSource.length = strlen(sqlSource.data); 06300003
} 06310000
/* Throw exception if not enough room for next record ... */ 06320003
if( moreRecords == Yes && sqlSource.length >((2*1048576)-72) ) 06330003
issueInvalidParmLengthError( "DD:SQLIN",0,((2*1048576)-72) ); 06340000
} 06350000
06360000
if( rc < RETSEV ) 06370000
if( fclose( sqlInFile ) != 0 ) 06380000
issueDataSetClosingError( "DD:SQLIN",errno ); 06390000
06400000
} /* end of getSQLsource */ 06410000
06420000
06430000
void connectToLocation( void ) /* Connect to DB2 location */ 06440000
/******************************************************************* 06450000
* Connects to the DB2 location specified in call parm number 4 * 06460000
*******************************************************************/ 06470000
{ EXEC SQL 06480000
CONNECT TO :locationName; 06490000
06500000
if( SQLCODE != 0 ) 06510000
{ issueSqlError( "Connect to location failed" ); 06520000
} 06530000
} /* end of connectToLocation */ 06540000
06550000
06560003
void setAuthID( void ) /* Set the current DB2 auth id*/ 06570003
/******************************************************************* 06580003
* Changes the current authorization id to the one specified in * 06590003
* call parm number 3 * 06600003
*******************************************************************/ 06610003
{ EXEC SQL 06620003
SET CURRENT SQLID = :authID; 06630003
06640003
if( SQLCODE != 0 ) 06650003
{ issueSqlError( "Set current SQLID failed" ); 06660003
} 06670003
} /* end of setAuthID */ 06680003
06690003
06700000
void callDSNTPSMP( void ) /* Run SQL Procedure Processor*/ 06710000
/******************************************************************* 06720000
* Calls the DSNTPSMP (DB2 SQL Procedures Processor) * 06730000
*******************************************************************/ 06740000
312 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* Outputs data from the result set returned by DSNTPSMP * 07570000
*******************************************************************/ 07580000
{ 07590000
/***************************************************************** 07600000
* Associate a locator with the result set from DSNTPSMP * 07610000
*****************************************************************/ 07620000
associateResultSetLocator(); 07630000
07640000
/***************************************************************** 07650000
* Allocate a cursor for the result set * 07660000
*****************************************************************/ 07670000
if( rc < RETSEV ) 07680000
allocateResultSetCursor(); 07690000
07700000
/***************************************************************** 07710000
* Output reports returned in the result set * 07720000
*****************************************************************/ 07730000
if( rc < RETSEV ) 07740000
writeDSNTPSMPreports(); 07750000
07760000
} /* end of processDSNTPSMPresultSet */ 07770000
07780000
07790000
void associateResultSetLocator(void) /* Assoc DSNTPSMP RS locator */ 07800000
/******************************************************************* 07810000
* Associates the result set from DSNTPSMP with a result set locator* 07820000
*******************************************************************/ 07830000
{ EXEC SQL 07840000
ASSOCIATE 07850000
LOCATORS( :DSNTPSMP_rs_loc1 ) 07860000
WITH PROCEDURE SYSPROC.DSNTPSMP; 07870000
07880000
if( SQLCODE != 0 ) 07890000
{ issueSqlError( "Associate locator call failed" ); 07900000
} 07910000
07920000
} /* end of associateResultSetLocator */ 07930000
07940000
07950000
void allocateResultSetCursor( void ) /* Alloc DSNTPSMP RS cursor */ 07960000
/******************************************************************* 07970000
* Allocates a cursor to the locator for the DSNTPSMP result set * 07980000
*******************************************************************/ 07990000
{ EXEC SQL 08000000
ALLOCATE DSNTPSMP_RS_CSR1 08010000
CURSOR FOR RESULT SET :DSNTPSMP_rs_loc1; 08020000
08030000
if( SQLCODE != 0 ) 08040000
{ issueSqlError( "Allocate result set cursor " 08050000
"call failed" ); 08060000
} 08070000
08080000
} /* end of allocateResultSetCursor */ 08090000
08100000
08110000
void writeDSNTPSMPreports( void ) /* Print DSNTPSMP report */ 08120000
/******************************************************************* 08130000
* Outputs the reports returned in the result set from DSNTPSMP * 08140000
******************************************************************** 08150000
* The result set returned by DSNTPSMP contains one or more reports.* 08160000
* * 08170000
* Within the result set, reports are distinguished from one anoth- * 08180000
* er by the STEP and FILE columns: * 08190000
* - STEP refers to the phase (e.g. precompile, compile, bind, etc.)* 08200000
* of DSNTPSMP that generated the report. * 08210000
* - FILE distinguishes reports that are generated by the same STEP.* 08220000
* * 08230000
* Report line data are stored in the LINE column, and arranged ac- * 08240000
* cording to the sequence number in the SEQN column. * 08250000
* * 08260000
* In summary, STEPs contain FILEs, FILEs contain LINEs, and LINEs * 08270000
* are ordered according to SEQN (sequence). * 08280000
*******************************************************************/ 08290000
{ short int reportNumber = 1; /* Sequence number of report */ 08300000
char prevStepName[17]; /* Track step name changes */ 08310000
char prevFileName[9]; /* Track file name changes */ 08320000
short int recordLength = 0; /* Length of record */ 08330000
08340000
/***************************************************************** 08350000
* Get the first entry in the result set * 08360000
*****************************************************************/ 08370000
fetchFromResultSetCursor(); 08380000
314 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
*******************************************************************/ 09210000
{ char reportDDdcb[36]; /* for generated DCB */ 09220000
09230000
if( reportNumber < 1 || reportNumber > 99 ) 09240000
issueInvalidDDnumError( reportNumber ); 09250000
09260000
else 09270000
{ sprintf( reportDDName, /* Generate DD name REPORTnn */ 09280000
"DD:REPORT%2.2i\0", /* ..where nn is the sequence */ 09290000
reportNumber ); /* ..number of the report */ 09300000
09310000
if( reportLine[0] == '1' ) /* Does this look like FBA? */ 09320000
sprintf( reportDDdcb, /* Yes: Specify */ 09330000
"wb,recfm=FBA," /* ..record output, recfm=fba */ 09340000
"lrecl=256" ); /* ..and lrecl 255 */ 09350000
else 09360000
sprintf( reportDDdcb, /* No: Specify */ 09370000
"wb,recfm=FB," /* ..record output, recfm=fb */ 09380000
"lrecl=256" ); /* ..and lrecl 255 */ 09390000
09400000
errno = 0; /* clear LE errno */ 09410000
reportDD = fopen( reportDDName,reportDDdcb ); 09420000
09430000
if( reportDD == NULL ) /* If unable to open data set */ 09440000
issueDataSetOpeningError( reportDDName,errno ); 09450000
} 09460000
} /* end of openReportDataSet */ 09470000
09480000
09490000
void closeReportDataSet( void ) /* Dealloc DD for a report */ 09500000
/******************************************************************* 09510000
* Closes the DD associated with the file handler reportDD. * 09520000
*******************************************************************/ 09530000
{ if( fclose(reportDD) != 0 ) 09540000
issueDataSetClosingError( reportDDName,errno ); 09550000
} /* end of closeReportDataSet */ 09560000
09570000
09580000
void trimTrailingBlanks /* Strip off trailing blanks */ 09590000
( char *string /* - in: string to be trimmed */ 09600000
) 09610000
/******************************************************************* 09620000
* Strips trailing blanks from a string * 09630000
*******************************************************************/ 09640000
{ int i; 09650000
for( i = strlen(string) - 1; string[i] == ' '; i-- ); 09660000
string[++i] = '\0'; 09670000
} /* end of trimTrailingBlanks */ 09680000
09690000
/*begin @03*/ 09700000
void stripContinuationCharacter /* Strip off trailing - or + */ 09710000
( char *string /* - in: string to be trimmed */ 09720000
) 09730000
/******************************************************************* 09740000
* Strips trailing '+' or '-' from a blank-trimmed string * 09750000
*******************************************************************/ 09760000
{ int i; 09770000
i = strlen(string) - 1; 09780000
if( string[i] == '+' || string[i] == '-' ) 09790000
string[i] = '\0'; 09800000
trimTrailingBlanks( string ); 09810000
} /* end of trimstripContinuationCharacter */ 09820000
/*end @03*/ 09830000
09840000
/*begin @04*/ 09850000
void processSqlCommit( void ) /* Commit SQL changes */ 09860000
/******************************************************************* 09870000
* Commits the current unit of SQL work * 09880000
*******************************************************************/ 09890000
{ EXEC SQL 09900000
COMMIT; 09910000
09920000
if( SQLCODE != 0 ) 09930000
{ issueSqlError( "*** Commit failed " ); 09940000
} 09950000
else 09960000
{ printf( "* SQL changes have been committed\n" ); 09970000
} 09980000
09990000
} /* end of processSqlCommit */ 10000000
10010000
10020000
316 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
*******************************************************************/ 10850000
{ printf( "ERROR: Invalid sequence "/* Issue error messages */ 10860000
"number <%i> specified " /* ..for DD REPORTnn */ 10870000
"for REPORTnn DD\n", /* ..where nn is the sequence */ 10880000
invalidDDnum ); /* ..number of the result set */ 10890000
printf( "-----> Processing halted\n" ); 10900000
rc = RETSEV; 10910000
} /* end of issueInvalidDDnumError */ 10920000
10930000
10940000
void issueInvalidActionError /* Handler for unknown action */ 10950000
( char *action /* - in: action specified */ 10960000
) 10970000
/******************************************************************* 10980000
* Called when an unexpected argument is specified for the DB2 SQL * 10990000
* Procedures Processor action * 11000000
*******************************************************************/ 11010000
{ printf( "ERROR: The argument specified for the action " 11020000
"parameter is invalid\n",action ); 11030000
printf( "-----> Processing halted\n" ); 11040000
rc = RETSEV; 11050000
} /* end of issueInvalidActionError */ 11060000
11070000
11080000
void issueInvalidParmLengthError /* Handler for parm len error */ 11090000
( char *parmName, /* - in: identify of parm */ 11100000
int minLength, /* - in: min valid length */ 11110000
int maxLength /* - in: max valid length */ 11120000
) 11130000
/******************************************************************* 11140000
* Called when the length of an argument specified for a DSNTPSMP * 11150000
* parameter (parmName) does not fall within the valid bounds for * 11160000
* size (minLength and maxLength) for that parameter * 11170000
*******************************************************************/ 11180000
{ printf( "ERROR: The length of the argument specified for the %s " 11190000
"parameter\n",parmName ); 11200000
printf( " does not fall within the required bounds of %i " 11210000
"and %i\n",minLength,maxLength ); 11220000
printf( "-----> Processing halted\n" ); 11230000
rc = RETSEV; 11240000
} /* end of issueInvalidParmLengthError */ 11250000
11260003
11270003
void issueInvalidLevelError /* Handler for wrong DSNTPSMP */ 11280003
( char *level /* - in: level encountered */ 11290003
) 11300003
/******************************************************************* 11310003
* Called when a DSNTPSMP QUERYLEVEL request returns a level not * 11320003
* handled by this sample client. * 11330003
*******************************************************************/ 11340003
{ printf( "ERROR: The DSNTPSMP interface level %s is not " 11350003
"supported by this client\n",level ); 11360003
printf( "-----> Processing halted\n" ); 11370003
rc = RETSEV; 11380003
} /* end of issueInvalidLevelError */ 11390003
11400000
11410000
#pragma linkage(dsntiar, OS) 11420000
void issueSqlError /* Handler for SQL error */ 11430000
( char *locMsg /* - in: Call location */ 11440000
) 11450000
/******************************************************************* 11460000
* Called when an unexpected SQLCODE is returned from a DB2 call * 11470000
*******************************************************************/ 11480000
{ struct error_struct { /* DSNTIAR message structure */ 11490000
short int error_len; 11500000
char error_text[10][80]; 11510000
} error_message = {10 * 80}; 11520000
11530000
extern short int dsntiar( struct sqlca *sqlca, 11540000
struct error_struct *msg, 11550000
int *len ); 11560000
11570000
short int DSNTIARrc; /* DSNTIAR Return code */ 11580000
int j; /* Loop control */ 11590000
static int lrecl = 80; /* Width of message lines */ 11600000
11610000
/***************************************************************** 11620000
* print the locator message * 11630000
*****************************************************************/ 11640000
printf( "ERROR: %-80s\n", locMsg ); 11650000
printf( "-----> Processing halted\n" ); 11660000
Related reference
“Sample programs to help you prepare and run external SQL procedures” on page 302
Db2 provides sample jobs to help you prepare and run external SQL procedures. All samples are in data
set DSN1210.SDSNSAMP. Before you can run the samples, you must customize them for your installation.
DSN8WLMP
This JCL can be customized to establish the WLM startup PROC needed to run DSNTPSMP, the Db2 SQL
Procedures Processor, and to run ADMIN_UPDATE_SYSPARM, the Db2 stored procedure that changes
subsystem parameters.
//*********************************************************************
//* Name = DSN8WLMP
//*
//* Descriptive Name =
//* DB2 Sample WLM startup PROC for DSNTSPMP, the DB2 SQL Procedures
//* Processor, and for ADMIN_UPDATE_SYSPARM, the DB2 stored
//* procedure that changes subsystem parameters.
//*
//*
//* Licensed Materials - Property of IBM
//* 5635-DB2
//* (C) COPYRIGHT 1982, 2006 IBM Corp. All Rights Reserved.
//*
//* STATUS = Version 11
//*
//* Function =
//* This JCL can be customized to establish the WLM startup PROC
//* needed to run DSNTPSMP, the DB2 SQL Procedures Processor,
//* and to run ADMIN_UPDATE_SYSPARM, the DB2 stored procedure
//* that changes subsystem parameters.
//*
//* Before you can use this procedure, you need to have defined a
//* WLM Application Environment for running DSNTPSMP and
//* ADMIN_UPDATE_SYSPARM.
//*
//* *** *** *** *** *** *** IMPORTANT *** *** *** *** *** *** ***
//* For DSNTPSMP and ADMIN_UPDATE_SYSPARM, NUMTCB=1 is required.
//* Specify no other value. This assures concurrent executions
//* of DSNTPSMP and ADMIN_UPDATE_SYSPARM will run in their
//* own address space, which is needed for proper dataset
//* operation from within a REXX/TSO DB2 stored procedure.
//*
//* (1) Customize this proc for use on your system by locating and
//* changing all occurrences of the following strings as
//* indicated:
//* (A) '!WLMENV!' to the name of the WLM Application Environment
//* you have chosen for running DSNTPSMP and
//* ADMIN_UPDATE_SYSPARM
//* (B) '!DSN8WLMP!' to the name of the WLM Procedure associated
//* with that environment
//* (C) '!DSN!' to the name of your DB2 subsystem
//* (D) 'CBC!!' to the prefix of your target library for
318 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
//* IBM C/C++ for z/OS
//* (E) 'CEE!!' to the prefix of your target library for
//* IBM Language Environment for z/OS
//* (F) 'DSN!!0' to the prefix of your target library for
//* DB2 for z/OS
//* (2) Copy the customized proc to your MVS proclib, to the member
//* you specified as the WLM procedure name for the WLM
//* application environment you have chosen for running DSNTPSMP
//* and ADMIN_UPDATE_SYSPARM
//* Note: This should be the same value as you specified in
//* step 1B, above.
//*
//* CHANGE LOG:
//* 09/20/2012 Add ZPMDFLTS for ADMIN_UPDATE_SYSPARM DK1557/PM71114
//*
//*********************************************************************
//!DSN8WLMP! PROC DB2SSN=!DSN!,NUMTCB=1,APPLENV=!WLMENV!
//*
//NUMTCB@1 SET NUMTCB= <== Null NUMTCB symbol
//*
//DSNTPSMP EXEC PGM=DSNX9WLM,TIME=1440,
// PARM='&DB2SSN,1,&APPLENV', <== Use 1, not NUMTCB
// REGION=0M,DYNAMNBR=5 <== Allow for Dyn Allocs
//* Include SDSNEXIT to use Secondary Authids (DSN3@ATH DSN3@SGN exits)
//STEPLIB DD DISP=SHR,DSN=DSN!!0.SDSNEXIT
// DD DISP=SHR,DSN=DSN!!0.SDSNLOAD
// DD DISP=SHR,DSN=CBC!!.SCCNCMP <== C Compiler
// DD DISP=SHR,DSN=CEE!!.SCEERUN <== LE runtime
//SYSEXEC DD DISP=SHR, <== Location of DSNTPSMP
// DSN=DSN!!0.SDSNCLST and DSNADMUZ
//SYSTSPRT DD SYSOUT=*
//CEEDUMP DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSABEND DD DUMMY
//DSNTRACE DD SYSOUT=*
//*
//**** Data sets required by the SQL Procedures Processor
//SQLDBRM DD DISP=SHR, <== DBRM Library
// DSN=DSN!!0.DBRMLIB.DATA
//SQLCSRC DD DISP=SHR, <== Generated C Source
// DSN=DSN!!0.SRCLIB.DATA
//SQLLMOD DD DISP=SHR, <== Application Loadlib
// DSN=DSN!!0.RUNLIB.LOAD
//SQLLIBC DD DISP=SHR, <== C header files
// DSN=CEE!!.SCEEH.H
// DD DISP=SHR,
// DSN=CEE!!.SCEEH.SYS.H
// DD DISP=SHR, <== Debug header file
// DSN=DSN!!0.SDSNC.H
//SQLLIBL DD DISP=SHR, <== Linkedit includes
// DSN=CEE!!.SCEELKED
// DD DISP=SHR,
// DSN=DSN!!0.SDSNLOAD
//SYSMSGS DD DISP=SHR, <== Prelinker msg file
// DSN=CEE!!.SCEEMSGP(EDCPMSGE)
//*
//**** DSNTPSMP Configuration File - CFGTPSMP (optional)
//* A site provided sequential dataset or member, used to
//* define customized operation of DSNTPSMP in this APPLENV.
//*CFGTPSMP DD DISP=SHR,DSN=
//*
//**** Workfiles required by the SQL Procedures Processor
//SQLSRC DD UNIT=SYSALLDA,SPACE=(23440,(20,20)),
// DCB=(RECFM=FB,LRECL=80,BLKSIZE=23440)
//SQLPRINT DD UNIT=SYSALLDA,SPACE=(23476,(20,20)),
// DCB=(RECFM=VB,LRECL=137,BLKSIZE=23476)
//SQLTERM DD UNIT=SYSALLDA,SPACE=(23476,(20,20)),
// DCB=(RECFM=VB,LRECL=137,BLKSIZE=23476)
//SQLOUT DD UNIT=SYSALLDA,SPACE=(23476,(20,20)),
// DCB=(RECFM=VB,LRECL=137,BLKSIZE=23476)
//SQLCPRT DD UNIT=SYSALLDA,SPACE=(23476,(20,20)),
// DCB=(RECFM=VB,LRECL=137,BLKSIZE=23476)
//SQLUT1 DD UNIT=SYSALLDA,SPACE=(23440,(20,20)),
// DCB=(RECFM=FB,LRECL=80,BLKSIZE=23440)
//SQLUT2 DD UNIT=SYSALLDA,SPACE=(23440,(20,20)),
// DCB=(RECFM=FB,LRECL=80,BLKSIZE=23440)
//SQLCIN DD UNIT=SYSALLDA,SPACE=(32000,(20,20))
//SQLLIN DD UNIT=SYSALLDA,SPACE=(3200,(30,30)),
// DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200)
//SQLDUMMY DD DUMMY
//SYSMOD DD UNIT=SYSALLDA,SPACE=(23440,(20,20)), <= PRELINKER
// DCB=(RECFM=FB,LRECL=80,BLKSIZE=23440)
Related reference
“Sample programs to help you prepare and run external SQL procedures” on page 302
Db2 provides sample jobs to help you prepare and run external SQL procedures. All samples are in data
set DSN1210.SDSNSAMP. Before you can run the samples, you must customize them for your installation.
DSN8ED5
Demonstrates how to call the sample SQL procedure DSN8.
/********************************************************************* 00010000
* Module name = DSN8ED5 (DB2 sample program) * 00020000
* * 00030000
* DESCRIPTIVE NAME = Client for sample SQL Procedure DSN8.DSN8ES2 * 00040000
* * 00050000
* * 00060000
* LICENSED MATERIALS - PROPERTY OF IBM * 00070000
* 5675-DB2 * 00080000
* (C) COPYRIGHT 1999, 2000 IBM CORP. ALL RIGHTS RESERVED. * 00100000
* * 00130000
* STATUS = VERSION 7 * 00140000
* * 00170000
* Function: Demonstrates how to call the sample SQL procedure * 00230000
* DSN8.DSN8ES2 using static SQL. * 00240000
* * 00250000
* Notes: * 00260000
* Dependencies: Requires IBM C/C++ for OS/390 V1R3 or higher * 00270000
* * 00280000
* Restrictions: * 00290000
* * 00300000
* Module type: C program * 00310000
* Processor: IBM C/C++ for OS/390 V1R3 or higher * 00320000
* Module size: See linkedit output * 00330000
* Attributes: Re-entrant and re-usable * 00340000
* * 00350000
* Entry Point: DSN8ED5 * 00360000
* Purpose: See Function * 00370000
* Linkage: Standard MVS program invocation, one parameter. * 00380000
* * 00390000
* * 00400000
* Parameters: DSN8ED5 uses the C "main" argument convention of * 00410000
* argv (argument vector) and argc (argument count). * 00420000
* * 00430000
* - ARGV[0]: (input) pointer to a char[9], * 00440000
* null-terminated string having the name of * 00450000
* this program (DSN8ED5) * 00460000
* - ARGV[1]: (input) pointer to a char[10], * 00470000
* null-terminated string that contains the * 00480000
* amount of the base bonus for sample * 00490000
* managers. The format is: nnnnnn.nn * 00500000
* - ARGV[2]: (input) pointer to a char[17], * 00510000
* null-terminated string having the name of * 00520000
* the server where DSN8.DSN8ES2 resides. * 00530000
* This is an optional parameter; the local * 00540000
* server is used if no argument is provided. * 00550000
* * 00560000
* Normal Exit: Return Code: 0000 * 00570000
* - Message: none * 00580000
* * 00590000
* Error Exit: Return Code: 0008 * 00600000
* - Message: DSN8ED5 failed: Invalid parameter count * 00610000
* - Message: DSN8ED5 failed: Argument to parameter 1 * 00620000
* exceeds 9 bytes * 00630000
* - Message: DSN8ED5 failed: No result from DSN8.DSN8ES2* 00640000
* - Message: <formatted SQL text from DSNTIAR> * 00650000
* * 00660000
* * 00670000
* External References: * 00680000
* - Routines/Services: DSNTIAR: DB2 msg text formatter * 00690000
* - Data areas : None * 00700000
* - Control blocks : None * 00710000
* * 00720000
* Pseudocode: * 00730000
* DSN8ED5: * 00740000
320 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* - Verify that 2 or 3 input parameters (program name, base bonus * 00750000
* amount and, optionally, remote location name) were passed. * 00760000
* - if not, issue diagnostic message and end with code 0008 * 00770000
* - Connect to the remote location, if one was specified * 00780000
* - Call sample SQL Procedure DSN8.DSN8ES2, passing the base bonus * 00790000
* amount as the argument of the first (input) parameter. * 00800000
* - if unsuccessful, call sql_error to issue a diagnostic mes- * 00810000
* sage, then end with code 0008. * 00820000
* - Report the value returned by DSN8.DSN8ES2 in its second * 00830000
* (output) parameter. * 00840000
* End DSN8ED5 * 00850000
* * 00860000
* sql_error: * 00870000
* - call DSNTIAR to format the unexpected SQLCODE. * 00880000
* End sql_error * 00890000
* * 00900000
*********************************************************************/ 00910000
/********************** C library definitions ***********************/ 00920000
#include <stdio.h> 00930000
#include <stdlib.h> 00940000
#include <string.h> 00950000
#include <decimal.h> 00960000
00970000
/***************************** Equates ******************************/ 00980000
#define NULLCHAR '\0' /* Null character */ 00990000
01000000
#define OUTLEN 80 /* Length of output line */ 01010000
#define DATA_DIM 10 /* Number of message lines */ 01020000
01030000
#define NOT_OK 0 /* Run status indicator: Error*/ 01040000
#define OK 1 /* Run status indicator: Good */ 01050000
01060000
01070000
/******************** DB2 SQL Communication Area ********************/ 01080000
EXEC SQL INCLUDE SQLCA; 01090000
01100000
01110000
/************************ DB2 Host Variables ************************/ 01120000
EXEC SQL BEGIN DECLARE SECTION; 01130000
char locationName[17]; /* Server location name */ 01140000
01150000
decimal(15,2) hvBonusBase = 0; /* base bonus for managers */ 01160000
short int niBonusBase = 0; /* Indic var for hvBonusBase */ 01170000
01180000
decimal(15,2) hvBonuses = 0; /* tot bonuses rtnd by DSN8ES2*/ 01190000
short int niBonuses = 0; /* Indic var for hvBonuses */ 01200000
01210000
long int hvSqlErrCd = 0; /* Err SQLCODE from DSN8ES2 */ 01220000
short int niSqlErrCd = 0; /* Indic var for hvSqlErrCd */ 01230000
01240000
EXEC SQL END DECLARE SECTION; 01250000
01260000
01270000
/********************** DB2 Message Formatter ***********************/ 01280000
struct error_struct /* DSNTIAR message structure */ 01290000
{ 01300000
short int error_len; 01310000
char error_text[DATA_DIM][OUTLEN]; 01320000
} error_message = {DATA_DIM * (OUTLEN)}; 01330000
01340000
#pragma linkage( dsntiar, OS ) 01350000
01360000
extern short int dsntiar( struct sqlca *sqlca, 01370000
struct error_struct *msg, 01380000
int *len ); 01390000
01400000
01410000
/********************* DSN8ED5 Global Variables *********************/ 01420000
short int status = OK; /* DSN8ED5 run status */ 01430000
01440000
long int completion_code = 0; /* DSN8ED5 return code */ 01450000
01460000
01470000
/******************** DSN8ED5 Function Prototypes *******************/ 01480000
int main( int argc, char *argv[] ); 01490000
void sql_error( char locmsg[] ); 01500000
01510000
01520000
int main( int argc, char *argv[] ) 01530000
/********************************************************************* 01540000
* Get input parms, pass them to DSN8ES2, and process the results * 01550000
*********************************************************************/ 01560000
322 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
} 02390000
02400000
if( status != OK ) 02410000
completion_code = 8; 02420000
02430000
return( completion_code ); 02440000
02450000
} /* end main */ 02460000
02470000
02480000
/********************************************************************* 02490000
********************************************************************** 02500000
** SQL error handler ** 02510000
********************************************************************** 02520000
*********************************************************************/ 02530000
void sql_error( char locmsg[] ) /*proc*/ 02540000
{ 02550000
02560000
02570000
short int rc; /* DSNTIAR Return code */ 02580000
int j,k; /* Loop control */ 02590000
static int lrecl = OUTLEN; /* Width of message lines */ 02600000
02610000
/******************************************************************* 02620000
* set status to prevent further processing * 02630000
*******************************************************************/ 02640000
status = NOT_OK; 02650000
02660000
/******************************************************************* 02670000
* print the locator message * 02680000
*******************************************************************/ 02690000
printf( " %.80s\n", locmsg ); 02700000
02710000
/******************************************************************* 02720000
* format and print the SQL message * 02730000
*******************************************************************/ 02740000
rc = dsntiar( &sqlca, &error_message, &lrecl ); 02750000
if( rc == 0 ) 02760000
for( j=0; j<DATA_DIM; j++ ) 02770000
{ 02780000
for( k=0; k<OUTLEN; k++ ) 02790000
putchar(error_message.error_text[j][k] ); 02800000
putchar('\n'); 02810000
} 02820000
else 02830000
{ 02840000
printf( " *** ERROR: DSNTIAR could not format the message\n" ); 02850000
printf( " *** SQLCODE is %d\n",SQLCODE ); 02860000
printf( " *** SQLERRM is \n" ); 02870000
for( j=0; j<sqlca.sqlerrml; j++ ) 02880000
printf( "%c", sqlca.sqlerrmc[j] ); 02890000
printf( "\n" ); 02900000
} 02910000
02920000
} /* end of sql_error */ 02930000
Related reference
“Sample programs to help you prepare and run external SQL procedures” on page 302
Db2 provides sample jobs to help you prepare and run external SQL procedures. All samples are in data
set DSN1210.SDSNSAMP. Before you can run the samples, you must customize them for your installation.
DSNTEJ67
This job demonstrates two important steps to follow when considering the conversion of an external SQL
procedure to a native SQL procedure.
//*********************************************************************
//* Name = DSNTEJ67
//*
//* Descriptive Name =
//* DB2 Sample Application
//* Phase 6
//* REXX and SQL PL
//*
//* Licensed Materials - Property of IBM
//* 5615-DB2
//* (C) COPYRIGHT 2010, 2013 IBM Corp. All Rights Reserved.
//*
//* STATUS = Version 12
324 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
//* (A) '!DSN!' to the subsystem name of your DB2. This is
//* located in Step 0.
//* (B) 'DSN!!0' to the prefix of the target library for the
//* current DB2 release. This is located in the
//* JOBLIB, Step 3 and Step 4.
//* (3) (Optional) Change either of the following to customize the
//* input and output of this job for your particular purposes:
//*
//* (A) Change the name of the external SQL procedure to be
//* processed by this job. This is defined in job Step 1.
//* The name must include the schema qualifier. It must
//* designate an operational external SQL SP which was
//* deployed using the DB2 SQL procedure processor DSNTPSMP.
//*
//* (B) Change the data set where the extracted and modified
//* SQL procdure source will be written. This is defined in
//* job Step 2. The specification can be for an existing
//* data set or data set member, qualified or not qualified.
//* or represented by a DD descriptor (in the form of
//* DD:ddname). Any existing data set or ddname allocation
//* must be for a RECFM=F,FB,V,VB sequential data set or
//* data set member. (If an unallocated ddname is provided
//* a temporary sequential data set will be allocated.)
//*
//* Change Activity = ( V11 base pm76443 )
//* Apr2013 - Add version activation of native SQL PL helper routine
//* Aug2013 - Clarify prolog notes on DSN8ES2 dependency PM92730
//*
//*********************************************************************
//JOBLIB DD DISP=SHR,DSN=DSN!!0.SDSNEXIT
// DD DISP=SHR,DSN=DSN!!0.SDSNLOAD
//*
//*********************************************************************
//* Step 0: Store the default DB2 System SSID in a temporary data set
//* for use by various steps and services that are run.
//*********************************************************************
//PH067S00 EXEC PGM=IEBGENER
//SYSUT1 DD * Enter the desired DB2 SSID or Group attachment name
!DSN!
//SYSUT2 DD DSN=&&PARM0,DISP=(NEW,PASS),SPACE=(TRK,1),
// DCB=(LRECL=80,RECFM=FB,BLKSIZE=160)
//SYSPRINT DD DUMMY
//SYSIN DD DUMMY
//*********************************************************************
//* Step 1: Store the desired external SQL SP name to processs.
//* Specify a fully qualified SP name (2-parts, schema+name).
//*********************************************************************
//PH067S01 EXEC PGM=IEBGENER
//SYSUT1 DD * For a long name, wrap the input at column 72
DSN8.DSN8ES2
//*-+----1----+----2----+----3----+----4----+----5----+----6----+----7--
//SYSUT2 DD DSN=&&PARM1,DISP=(NEW,PASS),SPACE=(TRK,1),
// DCB=(LRECL=72,RECFM=FB,BLKSIZE=576)
//SYSPRINT DD DUMMY
//SYSIN DD *
GENERATE MAXFLDS=1
RECORD FIELD=(72)
//*********************************************************************
//* Step 2: Identify the desired data set name to store the extracted
//* and modified SQL procedure source. Must be Recfm F or V,
//* sequential or member, or a non-existing data set/member.
//* The spcification can be a qualified name, a non-qualified
//* name or a DD descriptor (in the form of DD:ddname).
//*********************************************************************
//PH067S02 EXEC PGM=IEBGENER
//SYSUT1 DD *
DD:TEMPSRC
//SYSUT2 DD DSN=&&PARM2,DISP=(NEW,PASS),SPACE=(TRK,1),
// DCB=(LRECL=72,RECFM=FB,BLKSIZE=576)
//SYSPRINT DD DUMMY
//SYSIN DD *
GENERATE MAXFLDS=1
RECORD FIELD=(72)
//*********************************************************************
//* Step 3: Populate a temporary PDS with REXX services used locally
//*********************************************************************
//PH067S03 EXEC PGM=IEBUPDTE,PARM=NEW
//SYSPRINT DD DUMMY
//SYSUT2 DD DSN=&&REXXPDS,DISP=(NEW,PASS),
// SPACE=(TRK,(5,5,2)),DCB=(LRECL=80,RECFM=FB,DSORG=PO)
//SYSIN DD DSN=DSN!!0.SDSNMACS(DSN8ERL1),
// DISP=SHR
/* From DD:SPNAME read the stored procedure name to extract from DB2.
* The name must be a schema qualified SP name (2-part name).
* The SP must be for an external SQL procedure, with source in DB2.
*/
'EXECIO * DISKR SPNAME (OPEN FINIS STEM TEMP.';
spname='';
do i = 1 to TEMP.0;
spname = spname || TEMP.i;
end;
spname = "STRIP"(spname,'B');
/* Process the passed name to get the name parts,
* plus the string and delimited forms.
*/
parse value "NAMPARTS"( spname ) with p# . namSpec
if p#<>2 then do;
say 'DSNTEJ67 the passed SP name' spname,
'was not schema qualified (2-parts)'
exit 8;
end;
parse var namSpec a b c d e . ':' +1 sNam +(a) sSch +(b) . +(c),
qNam +(d) qSch +(e)
spname = qSch'.'qNam /* 2-part fully qualified form now */
/* From DD:SOURCEDS read the data set specification for where the
* extracted and modified SQL proc source should be written at JOB end.
*/
'EXECIO * DISKR SOURCEDS (OPEN FINIS STEM TEMP.';
sourceFile='';
do i = 1 to TEMP.0;
sourceFile = sourceFile || TEMP.i;
end;
sourceFile = "STRIP"(sourceFile,'B');
/* Find the status of the target data set for the source. It must be a
* Sequential data set, F or V record format (or capable of same).
*/
parse value "CHKANYFV"(sourceFile) with oRecfm oLrecl oEmpty;
if oRecfm='' then do;
say 'DSNTEJ67 Cannot use the designated data set' sourceFile,
'for SQL PL source'
exit 8;
end;
prepConv:
/* From DD:HELPRSP1 deploy the native SQL SP DSN8.DSN8EN1 that will
* provide native options for the external SQL proc to be migrated.
* Use the subroutine form of the CRSQLPL service, asking for return
* of a version activation statement, for processing after deployment.
*/
Say 'Setting up the native SQL PL helper routine...'
call "CRSQLPL" 'DD:HELPRSP1', , , 'RETACTIVATE';
parse var result rc . 1 tok1 VerStmt ;
if "DATATYPE"(rc,'W')=0 then select; /* OK, 1st word not a number */
when tok1='/*CP*/' then rc=0; /* Skip ACTIVATE for CREATE */
when "WORDPOS"(tok1,'/*APR*/ /*APA*/')>0 /* ALTER REP, ALTER ADD */
then rc = ActivateRtnVer( VerStmt );
otherwise rc=8; /* Problem, force an error. */
end /* select */;
if RC>4 then do;
say 'DSNTEJ67 cannot deploy the native SP used for migration.';
exit 8;
end;
extractSQLproc:
/* Extract the SP source to a temporary SQLV file. Also get an S80
* format edition to use with the precompiler for inspection purposes.
*/
'SQLPLSRC' spname 'DD:SQLVE' 'DD:S80E' 'ASIS';
if RC>4 then do;
say 'DSNTEJ67 Cannot extract SQL procedure source';
326 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
exit 8;
end;
allocList='SQLVE,S80E'; /* allocated FOR us */
/* Write extracted source ASIS now to the output data set.
* We will rewrite it again later after reaching the point of editing.
*/
if oRecfm='F' then do;
if oLrecl=80 then seq='SEQ'; else seq='';
"SQLV2F" 'DD:SQLVE' sourceFile seq
end;
else "ANY2SQLV" 'DD:SQLVE' sourceFile 'EXTEND'
if RC<>0 then do;
say 'DSNTEJ67 Cannot write extracted source to data set' sourceFile
exit 8;
end;
else say 'Source for SP' spname 'written to data set' sourceFile
verifyExtSQL:
/* Verify the extracted source is valid external SQL procedure source
* before going to far. Use the HOST(SQL) precompiler.
*/
/* Keep DD:LISTING active till then end. */
'ALLOCATE DDNAME(LISTING) NEW REUSE';
'CHKSQLPL' 'DD:S80E' 'DD:LISTING' '.' 'MAR(1,80) HOST(SQL)'
if RC>4 then do;
msg='DSNTEJ67 Extracted external SQL procedure source has errors';
call endWithListing msg, allocList;
end;
chkoutSQLPL1:
/* Inspect the extracted external SQL procedure source without change
* using the HOST(SQLPL) Checkout precompiler.
* RC=8 errors are anticipated.
*/
allocList = allocList||',UT1';
'ALLOCATE DDNAME(UT1) NEW REUSE';
'CHKSQLPL' 'DD:S80E' 'DD:LISTING' 'DD:UT1' 'MAR(1,80)'
if RC>8 then do;
msg='DSNTEJ67 Fatal error running HOST(SQLPL) precompiler',
'with external SQL procedure source'
call endWithListing msg, allocList;
end;
/* Getting no UT1 content typically represents a native SQL PL syntax
* issue. In this context, that could be caused by some unforeseen
* difference between valid external SQL PL and native SQL PL syntax.
*/
parse value "CHKANYFV"('DD:UT1') with utR . utE;
if utE<>'1' then do;
msg='DSNTEJ67 Syntax error in external SQL proc source',
'when viewed as native SQL PL';
call endWithListing msg, allocList;
end;
editPrep:
/* Obtain an SQLPL TOC description, to use for editing the source. */
'SQLPLTOC' 'DD:S80E' 'DD:UT1' 'DD:TOC'
if RC<>0 then do;
msg='DSNTEJ67 Unable to prepare for source editing (no TOC).'
call endWithListing msg, allocList;
end;
allocList = allocList||',TOC';
/* Read TOC to get the OPTIONS element descriptor */
opts=''
"EXECIO * DISKR TOC (OPEN FINIS STEM TOC."
do i = 1 to TOC.0;
parse var TOC.i elem desc;
if elem='OPTS:' then do;
opts = desc;
leave;
end;
end;
parse var opts o1 o2 o3 .
parse var o1 or1 ':' oc1; parse var o2 or2 ':' oc2;
/* Bring original external source into memory now, spliting into
* three parts, Front (ahead of options), Back (after options)
* and Middle (the options which will be replaced).
*/
"EXECIO 0 DISKR SQLVE (OPEN"
/* Front: all complete lines before options, into stem FR. */
FR.=''; FR.0=0;
if or1>1
then "EXECIO" or1-1 "DISKR SQLVE (STEM FR.";
chkoutSQLPL2:
/* Inspect the modified procedure source one last time
* using the HOST(SQLPL) Checkout precompiler.
*/
'CHKSQLPL' 'DD:S80' 'DD:LISTING' '.' 'MAR(1,80)'
rrc=RC;
say 'Final HOST(SQLPL) Checkout Precompile ended with RC='rrc;
if rrc>0 then say 'Inspect the Listing for',
'additional SQLPL source coding issues';
'EXECIO * DISKR LISTING (OPEN FINIS STEM LISTING.';
call trimListing;
'EXECIO' listing.0 'DISKW LISTOUT (OPEN FINIS STEM LISTING.';
'FREE DDNAME(LISTING,SQLV,S80)';
exit rRC;
328 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
/* ----------------------------------------------------------------- */
activateRtnVer: procedure
/* Process the Activate Version statement passed. Returns 0 or 4. */
parse arg AVstmt ;
rcod=0;
"EXECIO * DISKR DB2SSID (OPEN FINIS STEM TEMP.";
parse var TEMP.1 ssid . ;
say 'Issuing...' AVstmt;
CALL SQLDBS 'ATTACH TO' ssid;
call SQLEXEC "EXECUTE IMMEDIATE :AVSTMT";
if result<0 then do;
say 'Trouble activating the native SQL PL routine version';
say '==>'sqlca.sqlcode'<';
say '==>'sqlca.sqlerrm'<';
call SQLEXEC "ROLLBACK";
rcod=4;
end;
else call SQLEXEC "COMMIT";
call SQLDBS 'DETACH';
return rcod;
endWithListing:
'EXECIO * DISKR LISTING (OPEN FINIS STEM LISTING.';
call trimListing;
'EXECIO' listing.0 'DISKW LISTOUT (OPEN FINIS STEM LISTING.';
'FREE DDNAME(LISTING)';
if arg(2,'E')
then 'FREE DDNAME('arg(2)')'; /* other DDnames to free */
if arg(1,'E')
then say arg(1); /* Message to end with */
exit 8;
Procedure
To create multiple versions of external procedures, including external SQL procedures, use one of the
following techniques:
• Define multiple procedures with the same name in different schemas. You can subsequently use the
SQL path to determine which version of the procedure is to be used by a calling program.
• Define multiple versions of the executable code. You can subsequently use a particular version by
specifying the name of the load module for the version that you want to use on the EXTERNAL clause
of the CREATE PROCEDURE statement or ALTER PROCEDURE statement.
• Define multiple packages for a procedure. You can subsequently use the COLLID option, the CURRENT
PACKAGESET special register, or the CURRENT PACKAGE PATH special register to specify which
version of the procedure is to be used by the calling application.
• Set up multiple WLM environments to use different versions of a procedure.
330 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
You can update existing data and insert new data in a single operation. This operation is useful when you
want to update a table with a set of rows, some of which are changes to existing rows and some of which
are new rows.
Related reference
LOAD (Db2 Utilities)
Procedure
Issue an INSERT statement.
By using INSERT statements, you can do the following actions:
• Specify the column values to insert a single row. You can specify constants, host variables, expressions,
DEFAULT, or NULL by using the VALUES clause.
• In an application program, specify arrays of column values to insert multiple rows into a table. Use
host-variable arrays in the VALUES clause of the INSERT FOR n ROWS statement to add multiple rows of
column values to a table.
• Include a SELECT statement in the INSERT statement to tell Db2 that another table or view contains the
data for the new row or rows.
In each case, for every row that you insert, you must provide a value for any column that does not have
a default value. For a column that meets one of the following conditions, specify DEFAULT to tell Db2 to
insert the default value for that column:
• The column is nullable.
• The column is defined with a default value.
• The column has data type ROWID. ROWID columns always have default values.
• The column is an identity column. Identity columns always have default values.
• The column is a row change timestamp column.
The values that you can insert into a ROWID column, an identity column, or a row change timestamp
column depend on whether the column is defined with GENERATED ALWAYS or GENERATED BY DEFAULT.
You can use the VALUES clause of the INSERT statement to insert a single row of column values into a
table. You can either name all of the columns for which you are providing values, or you can omit the list of
column names. If you omit the column name list, you must specify values for all of the columns.
Recommendation: For static INSERT statements, name all of the columns for which you are providing
values for the following reasons:
• Your INSERT statement is independent of the table format. (For example, you do not need to change the
statement when a column is added to the table.)
• You can verify that you are specifying the values in order.
• Your source statements are more self-descriptive.
If you do not name the columns in a static INSERT statement, and a column is added to the table, an
error can occur if the INSERT statement is rebound. An error will occur after any rebind of the INSERT
statement unless you change the INSERT statement to include a value for the new column. This is true
even if the new column has a default value.
When you list the column names, you must specify their corresponding values in the same order as in the
list of column names.
After inserting a new department row into your YDEPT table, you can use a SELECT statement to
see what you have loaded into the table. The following SQL statement shows you all of the new
department rows that you have inserted:
SELECT *
FROM YDEPT
WHERE DEPTNO LIKE 'E%'
ORDER BY DEPTNO;
Example
The following statement inserts information about a new employee into the YEMP table. Because the
WORKDEPT column is a foreign key, the value that is inserted for that column (E31) must be a value in
the primary key column, which is DEPTNO in the YDEPT table.
Example
The following statement also inserts a row into the YEMP table. Because the unspecified columns
allow null values, Db2 inserts null values into the columns that you do not specify.
Related concepts
Rules for inserting data into an identity column
An identity column contains a unique numeric value for each row in the table. Whether you can insert data
into an identity column and how that data gets inserted depends on how the column is defined.
Rules for inserting data into a ROWID column
A ROWID column contains unique values that identify each row in a table. Whether you can insert data
into a ROWID column and how that data gets inserted depends on how the column is defined.
Related tasks
Inserting multiple rows of data from host-variable arrays
Use host-variable arrays in your INSERT statement when you do not know at least some of the values to
insert until the program runs.
Inserting rows into a table from another table
You can copy one or more rows from one table into another table.
Related reference
INSERT (Db2 SQL)
CREATE TABLE (Db2 SQL)
332 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Inserting rows into a table from another table
You can copy one or more rows from one table into another table.
Procedure
Use a fullselect within an INSERT statement.
Examples
Example
The following SQL statement creates a table named TELE:
The following statement copies data from DSN8C10.EMP into the newly created table:
The two previous statements create and fill a table, TELE, that looks similar to the following table:
The CREATE TABLE statement example creates a table which, at first, is empty. The table has columns
for last names, first names, and phone numbers, but does not have any rows.
The INSERT statement fills the newly created table with data that is selected from the DSN8C10.EMP
table: the names and phone numbers of employees in department D21.
Example
The following CREATE statement creates a table that contains an employee's department name and
phone number. The fullselect within the INSERT statement fills the DLIST table with data from rows
that are selected from two existing tables, DSN8C10.DEPT and DSN8C10.EMP.
If ROWIDCOL2 is defined as GENERATED ALWAYS, you cannot insert the ROWID column data from T1 into
T2, but you can insert the integer column data. To insert only the integer data, use one of the following
methods:
• Specify only the integer column in your INSERT statement, as in the following statement:
• Specify the OVERRIDING USER VALUE clause in your INSERT statement to tell Db2 to ignore any values
that you supply for system-generated columns, as in the following statement:
Related concepts
Direct row access (PRIMARY_ACCESSTYPE='D') (Db2 Performance)
ROWID data type (Introduction to Db2 for z/OS)
Related tasks
Specifying direct row access by using row IDs
For some applications, you can use the value of a ROWID column to navigate directly to a row.
If IDENTCOL2 is defined as GENERATED ALWAYS, you cannot insert the identity column data from T1
into T2, but you can insert the character column data. To insert only the character data, use one of the
following methods:
334 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
• Specify only the character column in your INSERT statement, as in the following statement:
• Specify the OVERRIDING USER VALUE clause in your INSERT statement to tell Db2 to ignore any values
that you supply for system-generated columns, as in the following statement:
You need to insert values from the TOTAL column in JAPAN_SALES into the TOTAL column of
JAPAN_SALES_03. Because INSERT statements follow assignment rules, Db2 does not let you insert
the values directly from one column to the other because the columns are of different distinct types.
Suppose that a user-defined function called US_DOLLAR has been written that accepts values of type
JAPANESE_YEN as input and returns values of type US_DOLLAR. You can then use this function to insert
values into the JAPAN_SALES_03 table:
Related concepts
Promotion of data types (Db2 SQL)
Procedure
Issue a MERGE statement.
To update existing data and inserting new data, specify a MERGE statement with the WHEN MATCHED and
WHEN NOT MATCHED clauses. These clauses specify how Db2 handles matched and unmatched data. If
Db2 finds a matching row, that row is updated. If Db2 does not find a matching row, a new row is inserted.
Example
Suppose that you need to update the inventory at a car dealership. You need to add new car models to the
inventory and update information about car models that are already in the inventory.
You could make these changes with the following series of statements:
UPDATE INVENTORY
SET QUANTITY = QUANTITY + :hv_delta
WHERE MODEL = :hv_model;
336 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
if sqlcode >= 0
then do
GD
if rc = 0 then INSERT..
end
-- end pseudo code
IF rc = 0 THEN
INSERT INTO INVENTORY VALUES (:hv_model, :hv_delta);
END IF;
The MERGE statement simplifies the update and the insert into a single statement:
Related reference
MERGE (Db2 SQL)
Procedure
Specifying the MERGE statement in the FROM clause of the SELECT statement.
When you merge one or more rows into a table, you can retrieve:
• The value of an automatically generated column such as a ROWID or identity column
• Any default values for columns
• All values for a merged row, without specifying individual column names
• Calculated values based on the changes to merged rows
Specify the FINAL TABLE clause with SELECT FROM MERGE statements. The FINAL TABLE consists of the
rows of the table or view after the merge occurs.
Example
Suppose that you need to input data into the STOCK table, which contains company stock symbols and
stock prices from your stock portfolio. Some of your input data refers to companies that are already in the
STOCK table; some of the data refers to companies that you are adding to your stock portfolio. If the stock
symbol exists in the SYMBOL column of the STOCK table, you need to update the PRICE column. If the
company stock symbol is not yet in the STOCK table, you need to insert a new row with the stock symbol
and the stock price. Furthermore, you need to add a new value DELTA to your output to show the change
in stock price.
Suppose that the STOCK table contains the data that is shown in Table 58 on page 337.
Now, suppose that :hv_symbol and :hv_price are host-variable arrays that contain updated data that
corresponds to the data that is shown in Table 58 on page 337. Table 59 on page 338 shows the host
variable data for stock activity.
NEWC is new to the STOCK table, so its symbol and price need to be inserted into the STOCK table.
The rows for XCOM in Table 59 on page 338represent changed stock prices, so these values need to be
updated in the STOCK table. Also, the output needs to show the change in stock prices as a DELTA value.
The following SELECT FROM MERGE statement updates the price of XCOM, inserts the symbol and price
for NEWC, and returns an output that includes a DELTA value for the change in stock price.
The INCLUDE clause specifies that an additional column, DELTA, can be returned in the output without
adding a column to the STOCK table. The UPDATE portion of the MERGE statement sets the DELTA value
to the differential of the previous stock price with the value set for the update operation. The INSERT
portion of the MERGE statement sets the DELTA value to the same value as the PRICE column.
After the SELECT FROM MERGE statement is processed, the STOCK table contains the data that is shown
in Table 60 on page 338.
The following output of the SELECT FROM MERGE statement includes both updates to XCOM and a DELTA
value for each output row.
338 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
• All values that are inserted by a multiple-row INSERT operation
• Values that are changed by a BEFORE INSERT trigger
Procedure
Specify the INSERT statement in the FROM clause of the SELECT statement.
The rows that are inserted into the target table produce a result table whose columns can be referenced
in the SELECT list of the query. The columns of the result table are affected by the columns, constraints,
and triggers that are defined for the target table:
• The result table includes Db2-generated values for identity columns, ROWID columns, or row change
timestamp columns.
• Before Db2 generates the result table, it enforces any constraints that affect the insert operation (that
is, check constraints, unique index constraints, and referential integrity constraints).
• The result table includes any changes that result from a BEFORE trigger that is activated by the insert
operation. An AFTER trigger does not affect the values in the result table.
Examples
In addition to examples that use the Db2 sample tables, the examples in this topic use an EMPSAMP table
that has the following definition:
The SELECT statement returns the Db2-generated identity value for the EMPNO column, the default
value 'New Hire' for the HIRETYPE column, and the value of the CURRENT DATE special register for
the HIREDATE column.
Recommendation: Use the SELECT FROM INSERT statement to insert a row into a parent table and
retrieve the value of a primary key that was generated by Db2 (a ROWID or identity column). In
another INSERT statement, specify this generated value as a value for a foreign key in a dependent
table.
Example 2: Retrieving values updated by triggers
Suppose that a BEFORE INSERT trigger is created on table EMPSAMP to give all new employees at the
Associate level a $5000 increase in salary. The trigger has the following definition:
The SELECT statement returns a salary of 40000.00 for Mary Smith instead of the initial salary of
35000.00 that was explicitly specified in the INSERT statement.
Selecting values when you insert a single row:
When you insert a new row into a table, you can retrieve any column in the result table of the SELECT
FROM INSERT statement. When you embed this statement in an application, you retrieve the row into
host variables by using the SELECT ... INTO form of the statement.
Example 4: Retrieving all values for a row inserted intro a structure.
You can retrieve all the values for a row that is inserted into a structure. For example, in the following
statement :empstruct is a host variable structure that is declared with variables for each of the
columns in the EMPSAMP table.
CREATE VIEW V1 AS
SELECT C1, I1 FROM T1 WHERE I1 > 10
WITH CASCADED CHECK OPTION;
SELECT C1 FROM
FINAL TABLE (INSERT INTO V1 (I1) VALUES(12));
The value 12 satisfies the search condition of the view definition, and the result table consists of the
value for C1 in the inserted row.
If you use a value that does not satisfy the search condition of the view definition, the insert operation
fails, and Db2 returns an error.
Example 5: Selecting ROWID values when inserting multiple rows
In an application program, to retrieve values from the insertion of multiple rows, declare a cursor so
that the INSERT statement is in the FROM clause of the SELECT statement of the cursor.
To see the values of the ROWID columns that are inserted into the employee photo and resume table,
you can declare the following cursor:
340 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Example 7: Using the INPUT SEQUENCE clause
To retrieve rows in the order in which they are inserted, use the INPUT SEQUENCE clause:
The INPUT SEQUENCE clause can be specified only if an INSERT statement is in the FROM clause of
the SELECT statement. In this example, the rows are inserted from an array of employee numbers.
Example 8: Inserting rows with multiple encoding CCSIDs
Suppose that you want to populate an ASCII table with values from an EBCDIC table and then see
selected values from the ASCII table. You can use the following cursor to select the EBCDIC columns,
populate the ASCII table, and then retrieve the ASCII values:
Example 10: Result table of the cursor when you insert multiple rows
In an application program, when you insert multiple rows into a table, you declare a cursor so that the
INSERT statement is in the FROM clause of the SELECT statement of the cursor. The result table of the
cursor is determined during OPEN cursor processing. The result table may or may not be affected by
other processes in your application.
When you declare a scrollable cursor, the cursor must be declared with the INSENSITIVE keyword if
an INSERT statement is in the FROM clause of the cursor specification. The result table is generated
during OPEN cursor processing and does not reflect any future changes. You cannot declare the cursor
with the SENSITIVE DYNAMIC or SENSITIVE STATIC keywords.
When you declare a non-scrollable cursor, any searched updates or deletes do not affect the result
table of the cursor. The rows of the result table are determined during OPEN cursor processing.
For example, assume that your application declares a cursor, opens the cursor, performs a fetch,
updates the table, and then fetches additional rows:
The fetches that occur after the updates return the rows that were generated when the cursor was
opened. If you use a simple SELECT (with no INSERT statement in the FROM clause), the fetches
might return the updated values, depending on the access path that Db2 uses.
Example 11: Effect of WITH HOLD
When you declare a cursor with the WITH HOLD option and open the cursor, all of the rows are
inserted into the target table. The WITH HOLD option has no effect on the SELECT FROM INSERT
statement of the cursor definition. After your application performs a commit, you can continue to
retrieve all of the inserted rows.
Assume that the employee table in the Db2 sample application has five rows. Your application
declares a WITH HOLD cursor, opens the cursor, fetches two rows, performs a commit, and then
fetches the third row successfully:
The addition of 10000.00 causes a decimal overflow to occur, and no rows are inserted into the
EMPSAMP table.
342 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Example 14: Errors during OPEN cursor processing
If the insertion of any row fails during the OPEN cursor processing, all previously successful insertions
are undone. The result table of the insert is empty.
Example 15: Errors during FETCH processing
If the FETCH statement fails while retrieving rows from the result table of the insert operation, a
negative SQLCODE is returned to the application, but the result table still contains the original number
of rows that was determined during the OPEN cursor processing. At this point, you can undo all of the
inserts.
Assume that the result table contains 100 rows and the 90th row that is being fetched from the cursor
returns a negative SQLCODE:
Related concepts
Held and non-held cursors
A held cursor does not close after a commit operation. A cursor that is not held closes after a commit
operation. You specify whether you want a cursor to be held or not held by including or omitting the WITH
HOLD clause when you declare the cursor.
Using host variables in SQL statements
Use scalar host variables in embedded SQL statements to represent a single value. Host variables are
useful for storing retrieved data or for passing values that are to be assigned or used for comparisons.
Identity columns
An identity column contains a unique numeric value for each row in the table. Db2 can automatically
generate sequential numeric values for this column as rows are inserted into the table. Thus, identity
columns are ideal for primary key values, such as employee numbers or product numbers.
Types of cursors
You can declare row-positioned or rowset-positioned cursors in a number of ways. These cursors can be
scrollable or not scrollable, held or not held, or returnable or not returnable.
Related tasks
Inserting multiple rows of data from host-variable arrays
Use host-variable arrays in your INSERT statement when you do not know at least some of the values to
insert until the program runs.
Retrieving a set of rows by using a cursor
In an application program, you can retrieve a set of rows from a table or a result table that is returned by a
stored procedure. You can retrieve one or more rows at a time.
Undoing selected changes within a unit of work by using savepoints
Savepoints enable you to undo selected changes within a unit of work. Your application can set any
number of savepoints and then specify a specific savepoint to indicate which changes to undo within the
unit of work.
Related reference
Command line processor BIND command
Procedure
To preserve the order of the derived table specify the ORDER OF clause with the ORDER BY clause.
These two clauses ensure that the result rows of a fullselect follow the same order as the result table of a
subquery within the fullselect.
You can use the ORDER OF clause in any query that uses an ORDER BY clause, but the ORDER OF clause
is most useful with queries that contain a set operator, such as UNION.
Examples
Example
The following example retrieves the following rows:
• Rows of table T1 in no specified order
• Rows of table T2 in the order of the first column in table T2
The example query then performs a UNION ALL operation on the results of the two subqueries. The
ORDER BY ORDER OF UTABLE clause in the query specifies that the fullselect result rows are to be
returned in the same order as the result rows of the UNION ALL statement.
SELECT * FROM
(SELECT * FROM T1
UNION ALL
(SELECT * FROM T2 ORDER BY 1)
) AS UTABLE
ORDER BY ORDER OF UTABLE;
Example
The following example joins data from table T1 to the result table of a nested table expression. The
nested table expression is ordered by the second column in table T2. The ORDER BY ORDER OF TEMP
clause in the query specifies that the fullselect result rows are to be returned in the same order as the
nested table expression.
Alternatively, you can produce the same result by explicitly stating the ORDER BY column TEMP.Cy in
the fullselect instead of using the ORDER OF syntax.
Related reference
fullselect (Db2 SQL)
order-by-clause (Db2 SQL)
344 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Adding data to the end of a table
In a relational database, the rows of a table are not ordered, and thus, the table has no "end." However,
depending on your goal, you can perform several actions to simulate adding data to the end of a table.
Procedure
To change the data in a table, use the UPDATE statement.
For example, suppose that an employee relocates. To update several items of the employee's data in the
YEMP work table to reflect the move, you can execute the following statement:
UPDATE YEMP
SET JOB = 'MANAGER ',
PHONENO ='5678'
WHERE EMPNO = '000400';
You can also use the UPDATE statement to remove a value from a column (without removing the row) by
changing the column value to null.
You cannot update rows in a created temporary table, but you can update rows in a declared temporary
table.
The SET clause names the columns that you want to update and provides the values that you want to
assign to those columns. You can replace a column value in the SET clause with any of the following
items:
• A null value
The column to which you assign the null value must not be defined as NOT NULL.
• An expression, which can be any of the following items:
Example
The following statement supplies a missing middle initial and changes the job for employee 000200.
UPDATE YEMP
SET MIDINIT = 'H', JOB = 'FIELDREP'
WHERE EMPNO = '000200';
The following statement gives everyone in department D11 a raise of 400.00. The statement can update
several rows.
UPDATE YEMP
SET SALARY = SALARY + 400.00
WHERE WORKDEPT = 'D11';
The following statement sets the salary for employee 000190 to the average salary and sets the bonus to
the minimum bonus for all employees.
UPDATE YEMP
SET (SALARY, BONUS) =
(SELECT AVG(SALARY), MIN(BONUS)
FROM EMP)
WHERE EMPNO = '000190';
Related reference
UPDATE (Db2 SQL)
Procedure
Specify the UPDATE statement in the FROM clause of the SELECT statement.
When you update one or more rows in a table, you can retrieve:
• The value of an automatically generated column such as a ROWID or identity column
346 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
• Any default values for columns
• All values for an updated row, without specifying individual column names
In most cases, you want to use the FINAL TABLE clause with SELECT FROM UPDATE statements. The
FINAL TABLE consists of the rows of the table or view after the update occurs.
Examples
Example: SELECT FROM FINAL TABLE
Suppose that all clerks for a company are receiving 5 percent raises. You can use the following
SELECT FROM UPDATE statement to increase the salary of each designer by 5 percent and to retrieve
the total increase in salary for the company.
Example: INCLUDE a new column in the result table but not the target table
You can use the INCLUDE clause to introduce a new column to the result table but not add the column
to the target table. For example, suppose that sales representatives received a 20 percent increase in
their commission. You need to update the commission (COMM) of sales representatives (SALESREP)
in the EMP table and that you need to retrieve the old commission and the new commission for each
sales representative. You can use the following SELECT FROM UPDATE statement to perform the
update and to retrieve the required data.
Related reference
table-reference (Db2 SQL)
UPDATE (Db2 SQL)
Procedure
To delete one or more rows in a table:
• Use the DELETE statement with a WHERE clause to specify a search condition.
The DELETE statement removes zero or more rows of a table, depending on how many rows satisfy the
search condition that you specify in the WHERE clause.
You can use DELETE with a WHERE clause to remove only selected rows from a declared temporary
table, but not from a created temporary table.
The following DELETE statement deletes each row in the YEMP table that has an employee number
'000060'.
When this statement executes, Db2 deletes any row from the YEMP table that meets the search
condition.
If Db2 finds an error while executing your DELETE statement, it stops deleting data and returns error
codes in the SQLCODE and SQLSTATE variables or related fields in the SQLCA. The data in the table
does not change.
If the DELETE is successful, SQLERRD(3) in the SQLCA contains the number of deleted rows. This
number includes only the number of deleted rows in the table that is specified in the DELETE
statement. Rows that are deleted (in other tables) according to the CASCADE rule are not included
in SQLERRD(3).
To delete every row in a table:
• Use the DELETE statement without specifying a WHERE clause.
With segmented table spaces, deleting all rows of a table is very fast.
The following DELETE statement deletes every row in the YDEPT table:
If the statement executes, the table continues to exist (that is, you can insert rows into it), but it is
empty. All existing views and authorizations on the table remain intact when using DELETE.
• Use the TRUNCATE statement.
The TRUNCATE statement can provide the following advantages over a DELETE statement:
– The TRUNCATE statement can ignore delete triggers
– The TRUNCATE statement can perform an immediate commit
– The TRUNCATE statement can keep storage allocated for the table
The TRUNCATE statement does not, however, reset the count for an automatically generated value for
an identity column on the table. If 14872 was the next identity column value to be generated before a
TRUNCATE statement, 14872 would be the next value generated after the TRUNCATE statement.
Suppose that you need to empty the data from an old inventory table, regardless of any existing delete
triggers, and you need to make the space that is allocated for the table available for other uses. Use
the following TRUNCATE statement.
TRUNCATE INVENTORY_TABLE
IGNORE DELETE TRIGGERS
DROP STORAGE;
348 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Suppose that you need to empty the data from an old inventory table permanently, regardless of any
existing delete triggers, and you need to preserve the space that is allocated for the table. You need
the emptied data to be completely unavailable, so that a ROLLBACK statement cannot return the data.
Use the following TRUNCATE statement.
TRUNCATE INVENTORY_TABLE
REUSE STORAGE
IGNORE DELETE TRIGGERS
IMMEDIATE;
Procedure
Specify the DELETE statement in the FROM clause of the SELECT statement.
When you delete one or more rows in a table, you can retrieve:
• Any default values for columns
• All values for a deleted row, without specifying individual column names
• Calculated values based on deleted rows
Example
Example: FROM OLD TABLE clause
When you use a SELECT FROM DELETE statement, you must use the FROM OLD TABLE clause to
retrieve deleted values. The OLD TABLE consists of the rows of the table or view before the delete
occurs. For example, suppose that a company is eliminating all operator positions and that the
company wants to know how much salary money it will save by eliminating these positions. You can
use the following SELECT FROM DELETE statement to delete operators from the EMP table and to
retrieve the sum of operator salaries.
Related reference
table-reference (Db2 SQL)
DELETE (Db2 SQL)
350 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
The catalog table, SYSIBM.SYSTABAUTH, lists table privileges that are granted to authorization IDs. To
display the tables that you have authority to access (by privileges granted either to your authorization ID
or to PUBLIC), you can execute an SQL statement similar to the one shown in the following example. To do
this, you must have the SELECT privilege on SYSIBM.SYSTABAUTH.
Procedure
Issue a SELECT statement similar to the following example. To do this, you must have the SELECT
privilege on SYSIBM.SYSTABAUTH.
In this query, the predicate GRANTEETYPE = ' ' selects authorization IDs.
Exception: If your Db2 subsystem uses an exit routine for access control authorization, you cannot rely
on catalog queries to tell you the tables that you can access. When such an exit routine is installed, both
RACF and Db2 control table access.
Related reference
SYSTABAUTH catalog table (Db2 SQL)
Explicit table and view privileges (Managing Security)
Procedure
Query the SYSIBM.SYSCOLUMNS catalog table.
Examples
Example
Suppose that you want to display information about table DSN8C10.DEPT. If you have the SELECT
privilege on SYSIBM.SYSCOLUMNS, you can use the following statement:
Example
If you display column information about a table that includes LOB or ROWID columns, the LENGTH
field for those columns contains the number of bytes that those column occupy in the base table. The
LENGTH field does not contain the length of the LOB or ROWID data.
To determine the maximum length of data for a LOB or ROWID column, include the LENGTH2 column
in your query:
Related reference
SYSCOLUMNS catalog table (Db2 SQL)
Procedure
Issue a SELECT statement.
Examples
Example 1: Selecting all columns with SELECT *
You do not need to know the column names to select Db2 data. Use an asterisk (*) in the SELECT
clause to indicate that you want to retrieve all columns of each selected row of the named table.
Implicitly hidden columns, such as ROWID columns and XML document ID columns, are not included
in the result of the SELECT * statement. To view the values of these columns, you must specify the
column name.
The following SQL statement selects all columns from the department table:
SELECT *
FROM DSN8C10.DEPT;
Because the example does not specify a WHERE clause, the statement retrieves data from all rows.
The dashes for MGRNO and LOCATION in the result table indicate null values.
SELECT * is recommended mostly for use with dynamic SQL and view definitions. You can use SELECT
* in static SQL, but doing so is not recommended because of possible host variable compatibility and
performance implications. Suppose that you add a column to the table to which SELECT * refers. If
you have not defined a receiving host variable for that column, an error might occur, or the data from
the added column might not be retrieved.
If you list the column names in a static SELECT statement instead of using an asterisk, you can avoid
problems that might occur with SELECT *. You can also see the relationship between the receiving
host variables and the columns in the result table.
352 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Example 2: selecting specific columns with SELECT column-name
Select the column or columns you want to retrieve by naming each column. With a single SELECT
statement, you can select data from one column or as many as 750 columns. All columns appear in
the order you specify, not in their order in the table.
For example, the following SQL statement retrieves only the MGRNO and DEPTNO columns from the
department table:
MGRNO DEPTNO
====== ======
000010 A00
000020 B01
000030 C01
------ D01
000050 E01
000060 D11
000070 D21
000090 E11
000100 E21
------ F22
------ G22
------ H22
------ I22
------ J22
Db2 generates one additional implicitly hidden XML document ID column. To retrieve data in all
columns, including the generated XML document ID column, first look up the name of the generated
column in SYSIBM.SYSCOLUMNS. Suppose the name is DB2_GENERATED_DOCID_FOR_XML. Then,
specify the following statement:
Related concepts
Host variables
Use host variables to pass a single data item between Db2 and your application.
Remote servers and distributed data
Distributed data is data that resides on a database management system (DBMS) other than your local
system. Your local DBMS is the one on which you bind your application plan. All other DBMSs are remote.
Predicates (Db2 SQL)
Related reference
select-statement (Db2 SQL)
Procedure
Specify a WHERE clause with one or more predicates.
Db2 evaluates a predicate for each row as true, false, or unknown. Results are unknown only if an operand
is null.
If a search condition contains a column of a distinct type, the value to which that column is compared
must be of the same distinct type, or you must cast the value to the distinct type.
The following table lists the type of comparison, the comparison operators, and an example of each type
of comparison that you can use in a predicate in a WHERE clause.
Note: SALARY BETWEEN 20000 AND 40000 is equivalent to SALARY >= 20000 AND SALARY <= 40000.
You can also search for rows that do not satisfy one of the preceding conditions by using the NOT keyword
before the specified condition.
354 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
You can search for rows that do not satisfy the IS DISTINCT FROM predicate by using either of the
following predicates:
• value 1 IS NOT DISTINCT FROM value 2
• NOT(value 1 IS DISTINCT FROM value 2)
Both of these forms of the predicate create an expression for which one value is equal to another value or
both values are equal to null.
Related concepts
Subqueries
When you need to narrow your search condition based on information in an interim table, you can use
a subquery. For example, you might want to find all employee numbers in one table that also exist for a
given project in a second table.
Predicates (Db2 SQL)
Related tasks
Coding SQL statements to avoid unnecessary processing (Db2 Performance)
Related reference
where-clause (Db2 SQL)
Examples
Example 1: Selecting rows that contain null in a column
To select the values for all rows that contain a null value for the manager number, you can issue the
following statement:
C1
2
1
null
C2
2
null
SELECT *
FROM T1, T2
WHERE C1 IS DISTINCT FROM C2
C1 C2
1 2
1 -
2 -
- 2
Related concepts
Nulls (Db2 SQL)
Null values in table columns (Introduction to Db2 for z/OS)
356 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Depending on your application, you might want to include or exclude rows that have a NULL value in a
column. You can use the NULL predicate to do that.
MY_EMP is a table that has a row with the last name and phone number for each of the employees in a
company. In this company, no employees share a phone number, but some employees might not have a
phone number. The LASTNAME column contains the last name of each employee. The PHONENO column
contains the phone number for each employee. If an employee does not have a phone, the PHONENO
column value is NULL. The table might look like this:
LASTNAME PHONENO
HAAS -------
THOMPSON 3476
KWAN 4738
GEYER 6789
STERN 6423
Suppose that you want to know the last name of the employee who has no phone number. Using a query
like this one does not work, because if the PHONENO column value is NULL, the WHERE clause compares
a NULL column value to a null host variable value. The result of that comparison is unknown.
MOVE -1 TO PHONENO-IND.
EXEC SQL
SELECT LASTNAME
INTO :LASTNAME-HV
FROM MY_EMP
WHERE PHONENO = :PHONENO-HV :PHONENO-IND
END-EXEC.
To find the employee with a NULL value for the phone number, you need to use a NULL predicate:
EXEC SQL
SELECT LASTNAME
INTO :LASTNAME-HV
FROM MY_EMP
WHERE PHONENO IS NULL
END-EXEC.
EXEC SQL
SELECT LASTNAME
INTO :LASTNAME-HV
FROM MY_EMP
WHERE (PHONENO IS NOT NULL AND :PHONENO-HV :PHONENO-IND IS NOT NULL
AND PHONENO = :PHONENO-HV ) -- Search condition for non-NULL
-- phone number
OR
(PHONENO IS NULL AND :PHONENO-HV :PHONENO-IND IS NULL)
-- Search condition for NULL
-- phone number
END-EXEC.
If you set :PHONENO-HV to '3476' and :PHONENO-IND to 0, the SELECT statement returns 'THOMPSON'
because the search condition for a non-NULL phone number is used. If you set :PHONENO-HV to any
value, and set :PHONENO-IND to -1, the SELECT statement returns 'HAAS' because the search condition
for a NULL phone number is used.
Derived columns in a result table, such as (SALARY + BONUS + COMM), do not have names. You can use
the AS clause to give a name to an unnamed column of the result table. For information about using the
AS clause, see “Naming result columns” on page 360.
What to do next
To order the rows in a result table by the values in a derived column, specify a name for the column
by using the AS clause, and specify that name in the ORDER BY clause. For information about using the
ORDER BY clause, see “Ordering the result table rows” on page 361.
Procedure
• You can select all XML data that is stored in a particular column by specifying SELECT column name or
SELECT *, just as you would for columns of any other data type.
• Alternatively, you can select only a subset of data from an XML column by using an XPath expression in
a SELECT statement. XPath expressions identify specific nodes in an XML document.
To select a subset of data in an XML column, specify the XMLQUERY function in your SELECT statement
with the following parameters:
– An XPath expression that is embedded in a character string constant. Specify an XPath expression
that identifies which XML data to return.
– Any additional values to pass to the XPath expression, including the XML column name. Specify
these values after the PASSING keyword.
Example
Suppose that you store purchase orders as XML documents in the POrder column in the PurchaseOrders
table. You need to find in each purchase order the items whose product name is equal to a name in the
Product table. You can use the following statement to find these values:
358 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
P.name AS "n")
FROM PurchaseOrders PO, Product P;
This statement returns the item elements in the POrder column that satisfy the criteria in the XPath
expression.
Related concepts
Overview of XQuery (Db2 Programming for XML)
Related reference
XMLQUERY (Db2 SQL)
Result tables
The data that is retrieved by an SQL statement is always in the form of a table, which is called a result
table. Like the tables from which you retrieve the data, a result table has rows and columns. A program
fetches this data one row at a time.
Example result table: Assume that you issue the following SELECT statement, which retrieves the last
name, first name, and phone number of employees in department D11 from the sample employee table:
Procedure
Specify the DISTINCT keyword in the query.
The DISTINCT keyword excludes duplicate rows from your query result table, so that each row contains
unique data.
Restriction: You cannot use the DISTINCT keyword with LOB columns or XML columns.
Example
The following SELECT statement lists unique department numbers for administrative departments:
Related tasks
Coding SQL statements to avoid unnecessary processing (Db2 Performance)
Related reference
select-clause (Db2 SQL)
Procedure
Use the AS clause to name result columns in a SELECT statement.
Examples
The following examples show different ways to use the AS clause.
Example: SELECT with AS CLAUSE
The following example of the SELECT statement gives the expression SALARY+BONUS+COMM the
name TOTAL_SAL.
The column STATUS and the derived column TOTAL_VALUE have the same name in the first and
second result tables. They are combined in the union of the two result tables, which is similar to the
following partial output:
360 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Example: GROUP BY derived column
You can use the AS clause in a FROM clause to assign a name to a derived column that you want to
refer to in a GROUP BY clause. This SQL statement names HIREYEAR in the nested table expression,
which lets you use the name of that result column in the GROUP BY clause:
You cannot use GROUP BY with a name that is defined with an AS clause for the derived column
YEAR(HIREDATE) in the outer SELECT, because that name does not exist when the GROUP BY runs.
However, you can use GROUP BY with a name that is defined with an AS clause in the nested table
expression, because the nested table expression runs before the GROUP BY that references the
name.
Related tasks
Combining result tables from multiple SELECT statements
When you combine the results of multiple SELECT statements, you can choose what to include in the
result table. You can include all rows, only rows that are in the result table of both SELECT statements, or
only rows that are unique to the result table of the first SELECT statement.
Defining a view
A view is a named specification of a result table. Use views to control which users have access to certain
data or to simplify writing SQL statements.
Summarizing group values
You can group rows in the result table by the values of one or more columns or by the results of an
expression. You can then apply aggregate functions to each group.
Related reference
select-clause (Db2 SQL)
Procedure
To retrieve rows in a specific order, use the ORDER BY clause
Examples
Example: Specifying the sort key in the ORDER BY clause
The order of the selected rows depends on the sort keys that you identify in the ORDER BY clause. A
sort key can be a column name, an integer that represents the number of a column in the result table,
or an expression. Db2 orders the rows by the first sort key, followed by the second sort key, and so on.
You can list the rows in ascending or descending order. Null values appear last in an ascending sort
and first in a descending sort.
Db2 sorts strings in the collating sequence associated with the encoding scheme of the table. Db2
sorts numbers algebraically and sorts datetime values chronologically.
Restriction: You cannot use the ORDER BY clause with LOB or XML columns.
Example: ORDER BY clause with a column name as the sort key
Retrieve the employee numbers, last names, and hire dates of employees in department A00 in
ascending order of hire dates:
Related reference
fullselect (Db2 SQL)
Example
Suppose that you want a list of employees and salaries from department D11 in the sample EMP table.
You can return a numbered list that is ordered by last name by submitting the following query:
362 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
This query returns the following result:
---------+---------+---------+---------+---------+---------+-----
NUMBER WORKDEPT LASTNAME SALARY
---------+---------+---------+---------+---------+---------+-----
1 D11 ADAMSON 25280.00
2 D11 BROWN 27740.00
3 D11 JOHN 29840.00
4 D11 JONES 18270.00
5 D11 LUTZ 29840.00
6 D11 PIANKA 22250.00
7 D11 SCOUTTEN 21340.00
8 D11 STERN 32250.00
9 D11 WALKER 20450.00
10 D11 YAMAMOTO 24680.00
11 D11 YOSHIMURA 24680.00
Related reference
OLAP specification (Db2 SQL)
Procedure
To rank rows, use one of the following ranking specifications in an SQL statement:
• Use RANK to return a rank number for each row value.
Use this specification if you want rank numbers to be skipped when duplicate row values exist.
For example, suppose the top five finishers in a marathon have the following times:
– 2:31:57
– 2:34:52
– 2:34:52
– 2:37:26
– 2:38:01
When you use the RANK specification, Db2 returns the following rank numbers:
Examples
Suppose that you had the following values in the DATA column of table T1:
DATA
-------
100
35
23
8
8
6
Example: RANK
Suppose that you use the following RANK specification:
SELECT DATA,
RANK() OVER (ORDER BY DATA DESC) AS RANK_DATA
FROM T1
ORDER BY RANK_DATA;
DATA RANK_DATA
-------------------
100 1
35 2
23 3
8 4
8 4
6 6
SELECT DATA,
DENSE_RANK() OVER (ORDER BY DATA DESC) AS RANK_DATA
FROM T1
ORDER BY RANK_DATA;
DATA RANK_DATA
-------------------
100 1
36 2
23 3
8 4
8 4
6 5
In the example with the RANK specification, two equal values are both ranked as 4. The next rank
number is 6. Number 5 is skipped.
In the example with the DENSE_RANK option, those two equal values are also ranked as 4. However,
the next rank number is 5. With DENSE_RANK, no gaps exist in the sequential rank numbering.
364 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Related reference
OLAP specification (Db2 SQL)
Procedure
• For data dependent pagination: Use row-value expressions with the <, <=, >, or >= comparison
operators in a SELECT statement to retrieve only part of a result set.
When used with a basic predicate, row-value expressions enable an application to access only part of a
Db2 result table based on a logical key value.
The following SELECT statement returns information from the table where the value of the LASTNAME
column is greater than or equal to 'SMITH' and the value of the FIRSTNAME column is greater than
'JOHN':
• For numeric based pagination: Use the OFFSET clause (either by itself, or with the FETCH clause) to
skip a specified number of rows from the result set.
To access part of Db2 result set based on an absolute position, the OFFSET clause can be specified
as part of the SELECT statement. The OFFSET clause specifies the number of rows to skip from the
beginning of a result set, which can be a more efficient way to filter unneeded rows. The OFFSET
clause can be used with the FETCH clause to further limit the number of rows returned from the result
set.
The following SELECT statement skips the first 100 rows from the T1 table before it returns rows for
the query:
SELECT * FROM T1
OFFSET 100 ROWS;
Using the OFFSET clause with the FETCH clause specifies the number of rows to skip from the
beginning of the table before returning the number of rows specified in the FETCH clause:
SELECT * FROM T1
OFFSET 10 ROWS
FETCH FIRST 10 ROWS ONLY;
To return three "pages" of 10 rows each, you might use statements similar to the following SQL
statements:
SELECT * FROM T1
OFFSET 0 ROWS
FETCH FIRST 10 ROWS ONLY;
SELECT * FROM T1
OFFSET 10 ROWS
FETCH NEXT 10 ROWS ONLY;
SELECT * FROM T1
OFFSET 20 ROWS
FETCH NEXT 10 ROWS ONLY;
COL1 COL2
a a
a b
a c
COL1 COL2
a b
a c
a d
You can use the set operators to combine two or more SELECT statements to form a single result table:
UNION
UNION returns all of the values from the result table of each SELECT statement. If you want all
duplicate rows to be repeated in the result table, specify UNION ALL. If you want redundant duplicate
rows to be eliminated from the result table, specify UNION or UNION DISTINCT.
For example, the following example is the result of specifying UNION for R1 and R2.
COL1 COL2
a a
a b
a c
a d
EXCEPT
Returns all rows from the first result table (R1) that are not also in the second result table (R2). If you
want all duplicate rows from R1 to be contained in the result table, specify EXCEPT ALL. If you want
redundant duplicate rows in R1 to be eliminated from the result table, specify EXCEPT or EXCEPT
DISTINCT.
The result of the EXCEPT operation depends on the which SELECT statement is included before the
EXCEPT keyword in the SQL statement. For example, if the SELECT statement that returns the R1
result table is listed first, the result is a single row:
COL1 COL2
a a
366 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
If the SELECT statement that returns the R2 result table is listed first, the final result is a different row:
COL1 COL2
a d
INTERSECT
Returns rows that are in the result table of both SELECT statements. If you want all duplicate rows to
be contained in the result table, specify INTERSECT ALL. If you want redundant duplicate rows to be
eliminated from the result table, specify INTERSECT or INTERSECT DISTINCT.
For example, the following example is the result of specifying UNION for R1 and R2.
COL1 COL2
a b
a c
When you specify one of the set operators, Db2 processes each SELECT statement to form an interim
result table, and then combines the interim result table of each statement. If the nth column of the first
result table (R1) and the nth column of the second result table (R2) have the same result column name,
the nth column of the result table has that same result column name. If the nth column of R1 and the nth
column of R2 do not have the same names, the result column is unnamed.
Procedure
• To combine two or more SELECT statements to form a single result table, use the set operators:
UNION, EXCEPT or INTERSECT.
For example, assume that you have the following tables to manage stock at two book stores.
SELECT TITLE
FROM STOCKA
EXCEPT
SELECT TITLE
FROM STOCKB
ORDER BY TITLE;
SELECT TITLE
FROM STOCKA
INTERSECT
SELECT TITLE
FROM STOCKB
ORDER BY TITLE;
368 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
• To keep all duplicate rows when combining result tables, specify the ALL keyword with the set
operator clause.
The following examples use the STOCKA and STOCK B tables from the previous step.
Example: UNION ALL
The following SQL statement returns a list of books that won Nobel prizes and are in stock at either
store, with duplicates included.
SELECT TITLE
FROM STOCKA
EXCEPT ALL
SELECT TITLE
FROM STOCKB
ORDER BY TITLE;
SELECT TITLE
FROM STOCKA
INTERSECT ALL
SELECT TITLE
FROM STOCKB
ORDER BY TITLE;
Procedure
Use the GROUP BY clause.
When it is used, the GROUP BY clause follows the FROM clause and any WHERE clause, and it precedes
the ORDER BY clause.
Except for the columns that are named in the GROUP BY clause, the SELECT statement must specify any
other selected columns as an operand of one of the aggregate functions.
If a column that you specify in the GROUP BY clause contains null values, Db2 considers those null values
to be equal. Thus, all nulls form a single group.
Examples
Example: GROUP BY clause using one column
The following SQL statement lists, for each department, the lowest and highest education level within
that department:
370 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Example: GROUP BY clause using more than one column
You can group the rows by the values of more than one column. For example, The following statement
finds the average salary for men and women in departments A00 and C01:
Db2 groups the rows first by department number and then (within each department) by sex before it
derives the average SALARY value for each group.
Example: GROUP BY clause using a expression
You can also group the rows by the results of an expression. For example, the following statement
groups departments by their leading characters, and lists the lowest and highest education level for
each group:
Related reference
group-by-clause (Db2 SQL)
Filtering groups
If you group rows in the result table, you can also specify a search condition that each retrieved group
must satisfy. The search condition tests properties of each group rather than properties of individual rows
in the group.
Procedure
Use the HAVING clause to specify a search condition.
The HAVING clause acts like a WHERE clause for groups, and it contains the same kind of search
conditions that you specify in a WHERE clause.
Example
Example: HAVING clause
The following SQL statement includes a HAVING clause that specifies a search condition for groups of
work departments in the employee table:
WORKDEPT AVG_SALARY
======== ==============
A00 40850.00000000
C01 29722.50000000
D11 25147.27272727
D21 25668.57142857
E11 21020.00000000
E21 24086.66666666
When you specify both GROUP BY and HAVING, the HAVING clause must follow the GROUP BY
clause. A function in a HAVING clause can include DISTINCT if you have not used DISTINCT anywhere
else in the same SELECT statement. You can also connect multiple predicates in a HAVING clause
with AND or OR, and you can use NOT for any predicate of a search condition.
Related reference
where-clause (Db2 SQL)
having-clause (Db2 SQL)
Procedure
Specify the ROW CHANGE TIMESTAMP expression in the predicate of your SQL statement.
Recommendation: Ensure that the table has a ROW CHANGE TIMESTAMP column that was defined prior
to the time period that you want to query. This column ensures that Db2 returns only those rows that were
updated in the given time period.
If the table does not have a ROW CHANGE TIMESTAMP column, Db2 returns all rows on each page that
has had any changes within the given time period. In this case, your result set can contain rows that have
not been updated in the give time period, if other rows on that page have been updated or inserted.
Examples
Example
Suppose that the TAB table has a ROW CHANGE TIMESTAMP column and that you want to return all of
the records that have changed in the last 30 days. The following query returns all of those rows.
Example
Suppose that you want to return all of the records that have changed since 9:00 AM January 1, 2004.
The following query returns all of those rows.
372 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
SELECT * FROM TAB
WHERE ROW CHANGE TIMESTAMP FOR TAB >= '2004-01-01-09.00.00';
Related reference
ROW CHANGE expression (Db2 SQL)
CREATE TABLE (Db2 SQL)
where-clause (Db2 SQL)
Examples
Nested table expressions and user-defined table functions in joins
An operand of a join can be more complex than the name of a single table. You can specify one of the
following items as a join operand:
nested table expression
A fullselect that is enclosed in parentheses and followed by a correlation name. The correlation
name lets you refer to the result of that expression.
Using a nested table expression in a join can be helpful when you want to create a temporary table
to use in a join. You can specify the nested table expression as either the right or left operand of a
join, depending on which unmatched rows you want included.
user-defined table function
A user-defined function that returns a table.
Using a nested table expression in a join can be helpful when you want to perform some operation
on the values in a table before you join them to another table.
Example: Using correlated references
In the following SELECT statement, the correlation name that is used for the nested table
expression is CHEAP_PARTS. You can use this correlation name to refer to the columns that are
returned by the expression. In this case, those correlated references are CHEAP_PARTS.PROD# and
CHEAP_PARTS.PRODUCT.
PROD# PRODUCT
===== ===========
505 SCREWDRIVER
30 RELAY
The correlated references are valid because they do not occur in the table expression where
CHEAP_PARTS is defined. The correlated references are from a table specification at a higher level
in the hierarchy of subqueries.
Because PROD# is a character field, Db2 does a character comparison to determine the set of rows in
the result. Therefore, because the characters '30' are greater than '200', the row in which PROD# is
equal to '30' does not appear in the result.
Example: Using a table function as an operand of a join
Suppose that CVTPRICE is a table function that converts the prices in the PRODUCTS table to the
currency that you specify and returns the PRODUCTS table with the prices in those units. You can
obtain a table of parts, suppliers, and product prices with the prices in your choice of currency by
executing a query similar to the following query:
374 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
A table function or a table expression that contains correlated references to other tables in the same
FROM clause cannot participate in a full outer join or a right outer join. The following examples
illustrate valid uses of correlated references in table specifications.
In this example, the correlated reference T.C2 is valid because the table specification, to which it
refers, T, is to its left.
If you specify the join in the opposite order, with T following TABLE(TF3(T.C2), T.C2 is invalid.
In this example, the correlated reference D.DEPTNO is valid because the nested table expression
within which it appears is preceded by TABLE, and the table specification D appears to the left of the
nested table expression in the FROM clause.
Procedure
Specify join conditions that include columns from all of the relevant tables.
Example
Example: Joining three tables
Suppose that you want a result table that shows employees who have projects that they are
responsible for, their projects, and their department names. You need to join three tables to get
all the information. You can use the following SELECT statement:
Db2 determines the intermediate and final results of the previous query by performing the following
logical steps:
1. Join the employee and project tables on the employee number, dropping the rows with no
matching employee number in the project table.
2. Join the intermediate result table with the department table on matching department numbers.
3. Process the select list in the final result table, leaving only four columns.
Example: Joining more than two tables by using more than one join type
When joining more than two tables, you do not have to use the same join type for every join.
To join tables by using more than one join type, specify the join types in the FROM clause.
Suppose that you want a result table that shows the following items:
• Employees whose last name begins with 'S' or a letter that comes after 'S' in the alphabet
• The department names for the these employees
• Any projects that these employees are responsible for
You can use the following SELECT statement:
Db2
determines the intermediate and final results of the previous query by performing the following logical
steps:
1. Join the employee and department tables on matching department numbers, dropping the rows
where the last name begins with a letter before 'S in the alphabet'.
2. Join the intermediate result table with the project table on the employee number, keeping the rows
for which no matching employee number exists in the project table.
3. Process the select list in the final result table, leaving only four columns.
Related reference
from-clause (Db2 SQL)
376 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Inner joins
An inner join is a method of combining two tables that discards rows of either table that do not match any
row of the other table. The matching is based on the join condition.
To request an inner join, execute a SELECT statement in which you specify the tables that you want to join
in the FROM clause, and specify a WHERE clause or an ON clause to indicate the join condition. The join
condition can be any simple or compound search condition that does not contain a subquery reference.
In the simplest type of inner join, the join condition is column1=column2.
Example
You can join the PARTS and PRODUCTS tables in sample data from joins on the PROD# column to get a
table of parts with their suppliers and the products that use the parts.
To do this, you can use either one of the following SELECT statements:
Regardless of whether you omit the WHERE clause or specify a join condition that is always true, the
number of rows in the result table is the product of the number of rows in each table.
You can specify more complicated join conditions to obtain different sets of results. For example, to
eliminate the suppliers that begin with the letter A from the table of parts, suppliers, product numbers,
and products, write a query like the following query:
In this example, the comma in the FROM clause implicitly specifies an inner join, and it acts the same as
if the INNER JOIN keywords had been used. When you use the comma for an inner join, you must specify
the join condition on the WHERE clause. When you use the INNER JOIN keywords, you must specify the
join condition on the ON clause.
Related reference
Sample data for joins
You can use the sample PARTS table and the PRODUCTS table to practice various types of joins.
from-clause (Db2 SQL)
Outer joins
An outer join is a method of combining two or more tables so that the result includes unmatched rows of
one of the tables, or of both tables. The matching is based on the join condition.
Db2 supports three types of outer joins:
full outer join
Includes unmatched rows from both tables. If any column of the result table does not have a value,
that column has the null value in the result table.
left outer join
Includes rows from the table that is specified before LEFT OUTER JOIN that have no matching values
in the table that is specified after LEFT OUTER JOIN.
right outer join
Includes rows from the table that is specified after RIGHT OUTER JOIN that have no matching values
in the table that is specified before RIGHT OUTER JOIN.
The following table illustrates how the PARTS and PRODUCTS tables in “Sample data for joins” on page
382 can be combined using the three outer join functions.
378 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
PARTS PRODUCTS
PART PROD# PROD# PRICE Unmatched
WIRE 10 Matches 505 3.70 row
MAGNETS 10 10 45.75
BLADES 205 205 18.90
Unmatched PLASTIC 30 30 7.55
row OIL 160
Figure 18. Three outer joins from the PARTS and PRODUCTS tables
The result table contains data that is joined from all of the tables, for rows that satisfy the search
conditions.
The result columns of a join have names if the outermost SELECT list refers to base columns. However,
if you use a function (such as COALESCE or VALUE) to build a column of the result, that column does not
have a name unless you use the AS clause in the SELECT list.
The result table from the query looks similar to the following output:
Example of using COALESCE or VALUE: COALESCE is the keyword that is specified by the SQL standard
as a synonym for the VALUE function. This function, by either name, can be particularly useful in full outer
join operations because it returns the first non-null value from the pair of join columns.
The AS clause (AS PRODNUM) provides a name for the result of the COALESCE function.
A row from the PRODUCTS table is in the result table only if its product number matches the product
number of a row in the PARTS table and the price is greater than 10.00 for that row. Rows in which the
PRICE value does not exceed 10.00 are included in the result of the join, but the PRICE value is set to null.
In this result table, the row for PROD# 30 has null values on the right two columns because the price of
PROD# 30 is less than 10.00. PROD# 160 has null values on the right two columns because PROD# 160
does not match another product number.
380 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Right outer join
A right outer join is a method of combining tables. The result includes unmatched rows from only the table
that is specified after the RIGHT OUTER JOIN clause.
If you are joining two tables and want the result set to include unmatched rows from only one table, use a
LEFT OUTER JOIN clause or a RIGHT OUTER JOIN clause. The matching is based on the join condition.
The clause RIGHT OUTER JOIN includes rows from the table that is specified after RIGHT OUTER JOIN
that have no matching values in the table that is specified before RIGHT OUTER JOIN.
As in an inner join, the join condition can be any simple or compound search condition that does not
contain a subquery reference.
Example: The following example uses the tables in “Sample data for joins” on page 382. To include rows
from the PRODUCTS table that have no corresponding rows in the PARTS table, execute this query:
A row from the PARTS table is in the result table only if its product number matches the product number
of a row in the PRODUCTS table and the price is greater than 10.00 for that row.
Because the PRODUCTS table can have rows with nonmatching product numbers in the result table, and
the PRICE column is in the PRODUCTS table, rows in which PRICE is less than or equal to 10.00 are
included in the result. The PARTS columns contain null values for these rows in the result table.
Db2 performs the join operation first. The result of the join operation includes rows from one table that
do not have corresponding rows from the other table. However, the WHERE clause then excludes the rows
from both tables that have null values for the PROD# column.
The following statement is a correct SELECT statement to produce the list:
For this statement, Db2 applies the WHERE clause to each table separately. Db2 then performs the full
outer join operation, which includes rows in one table that do not have a corresponding row in the other
table. The final result includes rows with the null value for the PROD# column and looks similar to the
following output:
382 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Even with the ORDER BY clause, Db2 might fetch all the data first and sort it after the fetch, which could
impact performance. Instead, you can write the query in one of the following ways:
Use OPTIMIZE FOR 1 ROW clause to influence the access path. OPTIMIZE FOR 1 ROW tells Db2 to select
an access path that returns the first qualifying row quickly.
Use FETCH FIRST n ROWS ONLY clause to limit the number of rows in the result table to n rows. FETCH
FIRST n ROWS ONLY has the following benefits:
• When you use FETCH statements to retrieve data from a result table, the fetch clause causes Db2
to retrieve only the number of rows that you need. This can have performance benefits, especially in
distributed applications. If you try to execute a FETCH statement to retrieve the n+1st row, Db2 returns
a +100 SQLCODE.
• When you use fetch clause in a SELECT INTO statement, you never retrieve more than one row. Using
fetch clause in a SELECT INTO statement can prevent SQL errors that are caused by inadvertently
selecting more than one value into a host variable.
When you specify the fetch clause but not the optimize clause, the optimize clause is implicit. When you
specify FETCH FIRST n ROWS ONLY and OPTIMIZE FOR m ROWS, and m is less than n, Db2 optimizes the
query for m rows. If m is greater than n, Db2 optimizes the query for n rows.
Related tasks
Fetching a limited number of rows (Db2 Performance)
Related reference
optimize-clause (Db2 SQL)
fetch-clause (Db2 SQL)
384 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Precision for operations with decimal numbers
Db2 accepts two sets of rules for determining the precision and scale of the result of an operation with
decimal numbers.
• DEC15 rules allow a maximum precision of 15 digits in the result of an operation. DEC15 rules are in
effect when both operands have a precision of 15 or less, or unless the DEC31 rules apply.
• DEC31 rules allow a maximum precision of 31 digits in the result. DEC31 rules are in effect if any of the
following conditions is true:
– Either operand of the operation has a precision greater than 15 digits.
– The operation is in a dynamic SQL statement, and any of the following conditions is true:
- The current value of special register CURRENT PRECISION is DEC31 or D31.s, where s is a number
between 1 and 9 and represents the minimum scale to be used for division operations.
- The installation option for DECIMAL ARITHMETIC on panel DSNTIP4 is DEC31, 31, or D31.s, where
s is a number between 1 and 9; the installation option for USE FOR DYNAMICRULES on panel
DSNTIP4 is YES; and the value of CURRENT PRECISION has not been set by the application.
- The SQL statement has bind, define, or invoke behavior; the statement is in an application that is
precompiled with option DEC(31); the installation option for USE FOR DYNAMICRULES on panel
DSNTIP4 is NO; and the value of CURRENT PRECISION has not been set by the application. See
“Dynamic rules options for dynamic SQL statements” on page 881 for an explanation of bind,
define, and invoke behavior.
– The operation is in an embedded (static) SQL statement that you precompiled with the DEC(31),
DEC31, or D31.s option, or with the default for that option when the installation option DECIMAL
ARITHMETIC is DEC31 or 31. s is a number between 1 and 9 and represents the minimum scale to be
used for division operations. See “Processing SQL statements for program preparation” on page 838
for information about precompiling and for a list of all precompiler options.
Recommendation: To reduce the chance of overflow, or when dealing with a precision greater than 15
digits, choose DEC31 or D31.s , wheres is a number between 1 and 9 and represents the minimum scale
to be used for division operations.
Procedure
Set the CURRENT DECFLOAT ROUNDING MODE special register.
Related reference
CURRENT DECFLOAT ROUNDING MODE (Db2 SQL)
SET CURRENT DECFLOAT ROUNDING MODE (Db2 SQL)
However, you cannot proceed because the DSN8C10.EMP table does not include project number data.
You do not know which employees are working on project MA2111 without issuing another SELECT
statement against the DSN8C10.EMPPROJACT table.
You can use a subquery to solve this problem. A subquery is a subselect or a fullselect in a WHERE clause.
The SELECT statement that surrounds the subquery is called the outer SELECT.
To better understand the results of this SQL statement, imagine that Db2 goes through the following
process:
1. Db2 evaluates the subquery to obtain a list of EMPNO values:
(SELECT EMPNO
FROM DSN8C10.EMPPROJACT
WHERE PROJNO = 'MA2111');
The result is in an interim result table, similar to the one in the following output:
from EMPNO
=====
200
200
220
2. The interim result table then serves as a list in the search condition of the outer SELECT. Effectively,
Db2 executes this statement:
386 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Correlated and uncorrelated subqueries
Subqueries supply information that is needed to qualify a row (in a WHERE clause) or a group of rows (in a
HAVING clause). The subquery produces a result table that is used to qualify the row or group of selected
rows.
A subquery executes only once, if the subquery is the same for every row or group. This kind of subquery
is uncorrelated, which means that it executes only once. For example, in the following statement, the
content of the subquery is the same for every row of the table DSN8C10.EMP:
Subqueries that vary in content from row to row or group to group are correlated subqueries. For
information about correlated subqueries, see “Correlated subqueries” on page 390.
A WHERE or HAVING clause can include predicates that contain subqueries. A predicate that contains
a subquery, like any other search predicate, can be enclosed in parentheses, can be preceded by the
keyword NOT, and can be linked to other predicates through the keywords AND and OR. For example, the
WHERE clause of a query can look something like the following clause:
Subqueries can also appear in the predicates of other subqueries. Such subqueries are nested subqueries
at some level of nesting. For example, a subquery within a subquery within an outer SELECT has a nesting
level of 2. Db2 allows nesting down to a level of 15, but few queries require a nesting level greater than 1.
The relationship of a subquery to its outer SELECT is the same as the relationship of a nested subquery to
a subquery, and the same rules apply, except where otherwise noted.
Except for a subquery of a basic predicate, the result table can contain more than one row. For more
information, see “Places where you can include a subquery” on page 388.
Related concepts
Subquery access (Db2 Performance)
You can use a subquery after a comparison operator, followed by the keyword ALL, ANY, or SOME. The
number of columns and rows that the subquery can return for a quantified predicate depends on the type
of quantified predicate:
• For = SOME, = ANY, or <> ALL, the subquery can return one or many rows and one or many columns.
The number of columns in the result table must match the number of columns on the left side of the
operator.
• For all other quantified predicates, the subquery can return one or many rows, but no more than one
column.
See the information about quantified predicates, including what to do if a subquery that returns one or
more null values gives you unexpected results.
To satisfy this WHERE clause, the column value must be greater than all of the values that the subquery
returns. A subquery that returns an empty result table satisfies the predicate.
Now suppose that you use the <> operator with ALL in a WHERE clause like this:
To satisfy this WHERE clause, each column value must be unequal to all of the values in the corresponding
column of the result table that the subquery returns. A subquery that returns an empty result table
satisfies the predicate.
388 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Example: ANY or SOME predicate
Use ANY or SOME to indicate that the values on the left side of the operator must compare in the
indicated way to at least one of the values that the subquery returns. For example, suppose that you use
the greater-than comparison operator with ANY:
To satisfy this WHERE clause, the value in the expression must be greater than at least one of the values
(that is, greater than the lowest value) that the subquery returns. A subquery that returns an empty result
table does not satisfy the predicate.
Now suppose that you use the = operator with SOME in a WHERE clause like this:
To satisfy this WHERE clause, each column value must be equal to at least one of the values in the
corresponding column of the result table that the subquery returns. A subquery that returns an empty
result table does not satisfy the predicate.
SELECT EMPNO,LASTNAME
FROM DSN8C10.EMP
WHERE EMPNO IN
(SELECT DISTINCT MGRNO
FROM DSN8C10.DEPT);
SELECT EMPNO,LASTNAME
FROM DSN8C10.EMP
WHERE EXISTS
(SELECT *
FROM DSN8C10.PROJ
WHERE PRSTDATE > '2005-01-01');
The result of the subquery is always the same for every row that is examined for the outer SELECT.
Therefore, either every row appears in the result of the outer SELECT or none appears. A correlated
subquery is more powerful than the uncorrelated subquery that is used in this example because the result
of a correlated subquery is evaluated for each row of the outer SELECT.
As shown in the example, you do not need to specify column names in the subquery of an EXISTS clause.
Instead, you can code SELECT *. You can also use the EXISTS keyword with the NOT keyword in order to
select rows when the data or condition that you specify does not exist; that is, you can code the following
clause:
Related tasks
Writing efficient subqueries (Db2 Performance)
Related reference
Quantified predicate (Db2 SQL)
Correlated subqueries
A correlated subquery is a subquery that Db2 reevaluates when it examines a new row (in a WHERE
clause) or a group of rows (in a HAVING clause) as it executes the outer SELECT statement.
In an uncorrelated subquery, Db2 executes the subquery once, substitutes the result of the subquery in
the right side of the search condition, and evaluates the outer SELECT based on the value of the search
condition.
A correlated subquery looks like an uncorrelated one, except for the presence of one or more correlated
references. In the example, the single correlated reference is the occurrence of X.WORKDEPT in the
WHERE clause of the subselect. In this clause, the qualifier X is the correlation name that is defined in the
FROM clause of the outer SELECT statement. X designates rows of the first instance of DSN8C10.EMP. At
any time during the execution of the query, X designates the row of DSN8C10.EMP to which the WHERE
clause is being applied.
Consider what happens when the subquery executes for a given row of DSN8C10.EMP. Before it executes,
X.WORKDEPT receives the value of the WORKDEPT column for that row. Suppose, for example, that the
row is for Christine Haas. Her work department is A00, which is the value of WORKDEPT for that row.
Therefore, the following is the subquery that is executed for that row:
(SELECT AVG(EDLEVEL)
FROM DSN8C10.EMP
WHERE WORKDEPT = 'A00');
The subquery produces the average education level of Christine's department. The outer SELECT then
compares this average to Christine's own education level. For some other row for which WORKDEPT has
a different value, that value appears in the subquery in place of A00. For example, in the row for Michael
390 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
L Thompson, this value is B01, and the subquery for his row delivers the average education level for
department B01.
The result table that is produced by the query is similar to the following output:
Related concepts
Correlated and non-correlated subqueries (Db2 Performance)
Related reference
having-clause (Db2 SQL)
where-clause (Db2 SQL)
The following example demonstrates the use of a correlated reference in the select list of a subquery:
UPDATE BP1TBL T1
SET (KEY1, CHAR1, VCHAR1) =
(SELECT VALUE(T2.KEY1,T1.KEY1), VALUE(T2.CHAR1,T1.CHAR1),
VALUE(T2.VCHAR1,T1.VCHAR1)
FROM BP2TBL T2
WHERE (T2.KEY1 = T1.KEY1))
WHERE KEY1 IN
(SELECT KEY1
FROM BP2TBL T3
WHERE KEY2 > 0);
UPDATE DSN8C10.PROJ X
SET PRIORITY = 1
WHERE DATE('2006-09-01') >
(SELECT MAX(ACENDATE)
FROM DSN8C10.PROJACT
WHERE PROJNO = X.PROJNO);
As Db2 examines each row in the DSN8C10.PROJ table, it determines the maximum activity end date
(the ACENDATE column) for all activities of the project (from the DSN8C10.PROJACT table). If the end
date of each activity that is associated with the project is before September 2006, the current row in the
DSN8C10.PROJ table qualifies, and Db2 updates it.
Using correlated subqueries in a DELETE statement:
Use correlation names in a DELETE statement to refer to the rows that you are deleting. The subquery
for which you specified a correlation name is called a correlated subquery. Db2 evaluates the correlated
subquery once for each row in the table that is named in the DELETE statement to decide whether to
delete the row.
Using tables with no referential constraints:
Suppose that a department considers a project to be complete when the combined amount of time
currently spent on it is less than or equal to half of a person's time. The department then deletes the
rows for that project from the DSN8C10.PROJ table. In the examples in this topic, PROJ and PROJACT are
independent tables; that is, they are separate tables with no referential constraints defined on them.
To process this statement, Db2 determines for each project (represented by a row in the DSN8C10.PROJ
table) whether the combined staffing for that project is less than 0.5. If it is, Db2 deletes that row from
the DSN8C10.PROJ table.
To continue this example, suppose that Db2 deletes a row in the DSN8C10.PROJ table. You must also
delete rows that are related to the deleted project in the DSN8C10.PROJACT table. To do this, use a
statement similar to this statement:
Db2 determines, for each row in the DSN8C10.PROJACT table, whether a row with the same project
number exists in the DSN8C10.PROJ table. If not, Db2 deletes the row from DSN8C10.PROJACT.
Using a single table:
A subquery of a searched DELETE statement (a DELETE statement that does not use a cursor) can
reference the same table from which rows are deleted. In the following statement, which deletes the
employee with the highest salary from each department, the employee table appears in the outer DELETE
and in the subselect:
392 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
This example uses a copy of the employee table for the subquery.
The following statement, without a correlated subquery, yields equivalent results:
With the referential constraints that are defined for the sample tables, this statement causes an error
because the result table for the subquery is not materialized before the deletion occurs. Because
DSN8C10.EMP is a dependent table of DSN8C10.DEPT, the deletion involves the table that is referred
to in the subquery, and the last delete rule in the path to EMP is SET NULL, not RESTRICT or NO ACTION.
If the statement could execute, its results would depend on the order in which Db2 accesses the rows.
Therefore, Db2 prohibits the deletion.
Restrictions when using distinct types with UNION, EXCEPT, and INTERSECT
Db2 enforces strong typing of distinct types with UNION, EXCEPT, and INTERSECT. When you use these
keywords to combine column values from several tables, the combined columns must be of the same
types. If a column is a distinct type, the corresponding column must be the same distinct type.
Example: Suppose that you create a view that combines the values of the US_SALES, EUROPEAN_SALES,
and JAPAN_SALES tables. The TOTAL columns in the three tables are of different distinct types. Before
you combine the table values, you must convert the types of two of the TOTAL columns to the type of
the third TOTAL column. Assume that the US_DOLLAR type has been chosen as the common distinct
type. Because Db2 does not generate cast functions to convert from one distinct type to another, two
user-defined functions must exist:
• A function called EURO_TO_US that converts values of type EURO to type US_DOLLAR
• A function called YEN_TO_US that converts values of type JAPANESE_YEN to type US_DOLLAR
Then you can execute a query like this to display a table of combined sales:
Because the result type of both the YEN_TO_US function and the EURO_TO_US function is US_DOLLAR,
you have satisfied the requirement that the distinct types of the combined columns are the same.
SELECT PRODUCT_ITEM
FROM US_SALES
WHERE TOTAL > US_DOLLAR(100000.00)
AND MONTH = 7
AND YEAR = 2003;
The casting satisfies the requirement that the compared data types are identical.
You cannot use host variables in statements that you prepare for dynamic execution. As explained in
“Dynamically executing an SQL statement by using PREPARE and EXECUTE” on page 517, you can
substitute parameter markers for host variables when you prepare a statement, and then use host
variables when you execute the statement.
If you use a parameter marker in a predicate of a query, and the column to which you compare the value
represented by the parameter marker is of a distinct type, you must cast the parameter marker to the
distinct type, or cast the column to its source type.
For example, suppose that distinct type CNUM is defined like this:
In an application program, you prepare a SELECT statement that compares the CUST_NUM column to a
parameter marker. Because CUST_NUM is of a distinct type, you must cast the distinct type to its source
type:
394 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Alternatively, you can cast the parameter marker to the distinct type:
• Restrictions for SELECT FROM FINAL TABLE statements that specify INSERT, UPDATE, or DELETE
statements to change data:
When you execute this type of statement, an error occurs if both of the following conditions exist:
– The SELECT statement that modifies data (by specifying INSERT, UPDATE, or DELETE) activates an
AFTER TRIGGER.
– The AFTER TRIGGER results in additional nested SQL operations that modify the table that is the
target of the original SELECT statement that modifies data.
• Restrictions for INSERT, UPDATE, MERGE, and DELETE statements:
When you execute an INSERT, UPDATE, MERGE, or DELETE statement on a table, you cannot access
that table from a user-defined function or stored procedure that is at a lower level of nesting.
For example, suppose that you execute this SQL statement at level 1 of nesting:
If the AFTER trigger is not activated by an INSERT, UPDATE, or DELETE data change statement that is
specified in a data-change-table-reference SELECT FROM FINAL TABLE, the preceding list of restrictions
do not apply to SQL statements that are executed at a lower level of nesting as a result of an after trigger.
For example, suppose an UPDATE statement at nesting level 1 activates an after update trigger, which
calls a stored procedure. The stored procedure executes two SQL statements that reference the triggering
table: one SELECT statement and one INSERT statement. In this situation, both the SELECT and the
INSERT statements can be executed even though they are at nesting level 3.
Although trigger activations count in the levels of SQL statement nesting, the previous restrictions on SQL
statements do not apply to SQL statements that are executed in the trigger body.
Example: Suppose that trigger TR1 is defined on table T1:
Now suppose that you execute this SQL statement at level 1 of nesting:
Although the UPDATE statement in the trigger body is at level 2 of nesting and modifies the same table
that the triggering statement updates, Db2 can execute the INSERT statement successfully.
Cursors
A cursor is a mechanism that points to one or more rows in a set of rows. The rows are retrieved from a
table or in a result set that is returned by a stored procedure. Your application program can use a cursor to
retrieve rows from a table.
396 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
values that no longer exists, or to miss a recently inserted row. In many cases, that is acceptable; a case
for which it is not acceptable is said to require data currency.
If your application requires data currency for a cursor, you need to prevent block fetching for the data to
which it points. To prevent block fetching for a distributed cursor, declare the cursor with the FOR UPDATE
clause.
Types of cursors
You can declare row-positioned or rowset-positioned cursors in a number of ways. These cursors can be
scrollable or not scrollable, held or not held, or returnable or not returnable.
In addition, you can declare a returnable cursor in a stored procedure by including the WITH RETURN
clause; the cursor can return result sets to a caller of the stored procedure.
398 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
• Because the FETCH statement executes against the base table, the cursor needs no temporary result
table. When you define a cursor as SENSITIVE DYNAMIC, you cannot specify the INSENSITIVE keyword
in a FETCH statement for that cursor.
Declared cursor type Cursor is updatable or Changes by the cursor Changes by other
read-only? are visible in the result cursors or processes
table?“3” on page 399 are visible to the result
table?
NO SCROLL (result table Read-only“1” on page 399 Not applicable No
is materialized)
NO SCROLL (result table Updatable“2” on page 399 Yes Yes
is not materialized)
INSENSITIVE SCROLL Read-only“4” on page 399 Not applicable No
SENSITIVE STATIC Updatable“2” on page 399, Yes Depends on the
SCROLL “6” on page 399 explicitly or implicitly
specified sensitivity in
the FETCH clause“5” on
page 399
Notes:
1. The content of the SELECT statement of the cursor makes the cursor implicitly read-only.
2. The cursor is updatable only if FOR READ ONLY or FOR FETCH ONLY is not specified as part of the
SELECT statement of the cursor, and there is nothing in the content of the SELECT statement makes
the cursor implicitly read-only.
3. If INSENSITIVE is specified on FETCH, only changes made by the same cursor are visible, assuming
that the rows being fetched have not already been read by a SENSITIVE FETCH on the same cursor.
4. An INSENSITIVE cursor is read-only if an updatability clause is not specified.
5. The sensitivity clause in a FETCH statement affects the visibility of others' changes as follows:
• For FETCH INSENSITIVE: Only positioned updates and deletes that are made by the same cursor
are visible.
• For FETCH SENSITIVE: All updates and deletes are visible.
6. Positioned updates and deletes are disallowed if the values of the selected columns do not match the
current values of the columns in the base table, even if the row satisfies the predicate of the SELECT
statement of the cursor.
7. All updates and deletes that are made by this cursor, and committed changes that are made by
other processes are visible on subsequent FETCH statements. Inserts that are made by this process
are also be visible as the result table is scrolled. Inserts by other processes into the base tables
underlying the result table are visible after they are committed.
Related concepts
FETCH statement interaction between row and rowset positioning
IMS
You cannot use DECLARE CURSOR...WITH HOLD in message processing programs (MPP) and message-
driven batch message processing (BMP). Each message is a new user for Db2; whether or not you declare
them using WITH HOLD, no cursors continue for new users. You can use WITH HOLD in non-message-
driven BMP and DL/I batch programs.
CICS
In CICS applications, you can use DECLARE CURSOR...WITH HOLD to indicate that a cursor should not
close at a commit or sync point. However, SYNCPOINT ROLLBACK closes all cursors, and end-of-task
(EOT) closes all cursors before Db2 reuses or terminates the thread. Because pseudo-conversational
transactions usually have multiple EXEC CICS RETURN statements and thus span multiple EOTs, the
scope of a held cursor is limited. Across EOTs, you must reopen and reposition a cursor declared WITH
HOLD, as if you had not specified WITH HOLD.
You should always close cursors that you no longer need. If you let Db2 close a CICS attachment cursor,
the cursor might not close until the CICS attachment facility reuses or terminates the thread.
If the CICS application is using a protected entry thread, this thread will continue to hold resources,
even when the task that has used these resources ends. These resources will not be released until the
protected thread terminates.
400 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
The following cursor declaration causes the cursor to maintain its position in the DSN8C10.EMP table
after a commit point:
EXEC SQL
DECLARE EMPLUPDT CURSOR WITH HOLD FOR
SELECT EMPNO, LASTNAME, PHONENO, JOB, SALARY, WORKDEPT
FROM DSN8C10.EMP
WHERE WORKDEPT < 'D11'
ORDER BY EMPNO
END-EXEC.
Procedure
To access data by using a row-positioned cursor:
1. Execute a DECLARE CURSOR statement to define the result table on which the cursor operates. See
“Declaring a row cursor” on page 401.
2. Execute an OPEN CURSOR to make the cursor available to the application. See “Opening a row cursor”
on page 403.
3. Specify what the program is to do when all rows have been retrieved. See “Specifying the action that
the row cursor is to take when it reaches the end of the data” on page 403.
4. Execute multiple SQL statements to retrieve data from the table or modify selected rows of the table.
See “Executing SQL statements by using a row cursor” on page 404.
5. Execute a CLOSE CURSOR statement to make the cursor unavailable to the application. See “Closing a
row cursor” on page 405.
Results
Your program can have several cursors, each of which performs the previous steps.
Procedure
To declare a row cursor, issue a DECLARE CURSOR statement.
The DECLARE CURSOR statement names a cursor and specifies a SELECT statement. The SELECT
statement defines the criteria for the rows that are to make up the result table.
The following example shows a simple form of the DECLARE CURSOR statement:
EXEC SQL
DECLARE C1 CURSOR FOR
SELECT EMPNO, FIRSTNME, MIDINIT, LASTNAME, SALARY
FROM DSN8C10.EMP
END-EXEC.
You can use this cursor to list select information about employees.
More complicated cursors might include WHERE clauses or joins of several tables. For example, suppose
that you want to use a cursor to list employees who work on a certain project. Declare a cursor like this to
identify those employees:
EXEC SQL
DECLARE C2 CURSOR FOR
EXEC SQL
DECLARE C1 CURSOR FOR
SELECT EMPNO, FIRSTNME, MIDINIT, LASTNAME, SALARY
FROM DSN8C10.EMP X
WHERE EXISTS
(SELECT *
FROM DSN8C10.PROJ Y
WHERE X.EMPNO=Y.RESPEMP
AND Y.PROJNO=:GOODPROJ)
FOR UPDATE OF SALARY;
If you might use the cursor to update any column of the employee table, define the cursor like this:
EXEC SQL
DECLARE C1 CURSOR FOR
SELECT EMPNO, FIRSTNME, MIDINIT, LASTNAME, SALARY
FROM DSN8C10.EMP X
WHERE EXISTS
(SELECT *
FROM DSN8C10.PROJ Y
WHERE X.EMPNO=Y.RESPEMP
AND Y.PROJNO=:GOODPROJ)
FOR UPDATE;
Db2 must do more processing when you use the FOR UPDATE clause without a column list than when you
use the FOR UPDATE clause with a column list. Therefore, if you intend to update only a few columns of a
table, your program can run more efficiently if you include a column list.
The precompiler options NOFOR and STDSQL affect the use of the FOR UPDATE clause in static SQL
statements. If you do not specify the FOR UPDATE clause in a DECLARE CURSOR statement, and you
do not specify the STDSQL(YES) option or the NOFOR precompiler options, you receive an error if you
execute a positioned UPDATE statement.
You can update a column of the identified table even though it is not part of the result table. In this case,
you do not need to name the column in the SELECT statement. When the cursor retrieves a row (using
FETCH) that contains a column value you want to update, you can use UPDATE … WHERE CURRENT OF to
identify the row that is to be updated.
Read-only result table
Some result tables cannot be updated—for example, the result of joining two or more tables.
Related concepts
Multilevel security (Managing Security)
402 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Related reference
Descriptions of SQL processing options
You can specify any SQL processing options regardless of whether you use the Db2 precompiler or the
Db2 coprocessor. However, the Db2 coprocessor might ignore certain options because host language
compiler options exist that provide the same information.
DECLARE CURSOR (Db2 SQL)
select-statement (Db2 SQL)
EXEC SQL
OPEN C1
END-EXEC.
If you use the CURRENT DATE, CURRENT TIME, or CURRENT TIMESTAMP special registers in a cursor,
Db2 determines the values in those special registers only when it opens the cursor. Db2 uses the values
that it obtained at OPEN time for all subsequent FETCH statements.
Two factors that influence the amount of time that Db2 requires to process the OPEN statement are:
• Whether Db2 must perform any sorts before it can retrieve rows
• Whether Db2 uses parallelism to process the SELECT statement of the cursor
Specifying the action that the row cursor is to take when it reaches the end of the data
Your program must be coded to recognize and handle an end-of-data condition whenever you use a row
cursor to fetch a row.
An alternative to this technique is to code the WHENEVER NOT FOUND statement. The WHENEVER NOT
FOUND statement causes your program to branch to another part that then issues a CLOSE statement. For
example, to branch to label DATA-NOT-FOUND when the FETCH statement does not return a row, use this
statement:
EXEC SQL
WHENEVER NOT FOUND GO TO DATA-NOT-FOUND
END-EXEC.
For more information about the WHENEVER NOT FOUND statement, see “Checking the execution of SQL
statements” on page 523.
EXEC SQL
FETCH C1 INTO
:HV-EMPNO, :HV-FIRSTNME, :HV-MIDINIT, :HV-LASTNAME, :HV-SALARY :IND-SALARY
END-EXEC.
The SELECT statement within DECLARE CURSOR statement identifies the result table from which you
fetch rows, but Db2 does not retrieve any data until your application program executes a FETCH
statement.
When your program executes the FETCH statement, Db2 positions the cursor on a row in the result
table. That row is called the current row. Db2 then copies the current row contents into the program
host variables that you specify on the INTO clause of FETCH. This sequence repeats each time you issue
FETCH, until you process all rows in the result table.
The row that Db2 points to when you execute a FETCH statement depends on whether the cursor is
declared as a scrollable or non-scrollable.
When you query a remote subsystem with FETCH, consider using block fetch for better performance.
Block fetch processes rows ahead of the current row. You cannot use a block fetch when you perform a
positioned update or delete operation.
After your program has executed a FETCH statement to retrieve the current row, you can use a positioned
UPDATE statement to modify the data in that row. An example of a positioned UPDATE statement is:
EXEC SQL
UPDATE DSN8C10.EMP
SET SALARY = 50000
WHERE CURRENT OF C1
END-EXEC.
A positioned UPDATE statement updates the row on which the cursor is positioned.
A positioned UPDATE statement is subject to these restrictions:
• You cannot update a row if your update violates any unique, check, or referential constraints.
• You cannot use an UPDATE statement to modify the rows of a created temporary table. However, you
can use an UPDATE statement to modify the rows of a declared temporary table.
• If the right side of the SET clause in the UPDATE statement contains a fullselect, that fullselect cannot
include a correlated name for a table that is being updated.
• You cannot use an SQL data change statement in the FROM clause of a SELECT statement that defines a
cursor that is used in a positioned UPDATE statement.
• A positioned UPDATE statement will fail if the value of the security label column of the row where the
cursor is positioned is not equivalent to the security label value of your user id. If your user id has write
down privilege, a positioned UPDATE statement will fail if the value of the security label column of the
row where the cursor is positioned does not dominate the security label value of your user id.
After your program has executed a FETCH statement to retrieve the current row, you can use a positioned
DELETE statement to delete that row. A example of a positioned DELETE statement looks like this:
404 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
EXEC SQL
DELETE FROM DSN8C10.EMP
WHERE CURRENT OF C1
END-EXEC.
A positioned DELETE statement deletes the row on which the cursor is positioned.
A positioned DELETE statement is subject to these restrictions:
• You cannot use a DELETE statement with a cursor to delete rows from a created temporary table.
However, you can use a DELETE statement with a cursor to delete rows from a declared temporary
table.
• After you have deleted a row, you cannot update or delete another row using that cursor until you
execute a FETCH statement to position the cursor on another row.
• You cannot delete a row if doing so violates any referential constraints.
• You cannot use an SQL data change statement in the FROM clause of a SELECT statement that defines a
cursor that is used in a positioned DELETE statement.
• A positioned DELETE statement will fail if the value of the security label column of the row where the
cursor is positioned is not equivalent to the security label value of your user id. If your user id has write
down privilege, a positioned DELETE statement will fail if the value of the security label column of the
row where the cursor is positioned does not dominate the security label value of your user id.
Procedure
Issue a CLOSE statement.
An example of a CLOSE statement looks like this:
EXEC SQL
CLOSE C1
END-EXEC.
Procedure
To access data by using a rowset-positioned cursor:
1. Execute a DECLARE CURSOR statement to define the result table on which the cursor operates. See
“Declaring a rowset cursor” on page 406.
2. Execute an OPEN CURSOR to make the cursor available to the application. See “Opening a rowset
cursor” on page 406.
3. Specify what the program is to do when all rows have been retrieved. See “Specifying the action that
the rowset cursor is to take when it reaches the end of the data” on page 406.
Results
Your program can have several cursors, each of which performs the previous steps.
Procedure
Use the WITH ROWSET POSITIONING clause in the DECLARE CURSOR statement.
The following example shows how to declare a rowset cursor:
EXEC SQL
DECLARE C1 CURSOR WITH ROWSET POSITIONING FOR
SELECT EMPNO, LASTNAME, SALARY
FROM DSN8C10.EMP
END-EXEC.
Specifying the action that the rowset cursor is to take when it reaches the end of the
data
Your program must be coded to recognize and handle an end-of-data condition whenever you use a
rowset cursor to fetch rows.
406 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
• The contents of the ROW_COUNT item of GET DIAGNOSTICS
For information about GET DIAGNOSTICS, see “Checking the execution of SQL statements by using the
GET DIAGNOSTICS statement ” on page 530.
If you declare the cursor as dynamic scrollable, and SQLCODE has the value +100, you can continue with
a FETCH statement until no more rows are retrieved. Additional fetches might retrieve more rows because
a dynamic scrollable cursor is sensitive to updates by other application processes. For information about
dynamic cursors, see “Types of cursors” on page 397.
EXEC SQL
FETCH NEXT ROWSET FROM C1
FOR 20 ROWS
INTO :HVA-EMPNO, :HVA-LASTNAME, :HVA-SALARY :INDA-SALARY
END-EXEC.
When your program executes a FETCH statement with the ROWSET keyword, the cursor is positioned
on a rowset in the result table. That rowset is called the current rowset. The dimension of each of the
host-variable arrays must be greater than or equal to the number of rows to be retrieved.
Suppose that you want to dynamically allocate the storage needed for the arrays of column values that
are to be retrieved from the employee table. You must:
1. Declare an SQLDA structure and the variables that reference the SQLDA.
2. Dynamically allocate the SQLDA and the arrays needed for the column values.
3. Set the fields in the SQLDA for the column values to be retrieved.
4. Open the cursor.
5. Fetch the rows.
You must first declare the SQLDA structure. The following SQL INCLUDE statement requests a standard
SQLDA declaration:
Before you can set the fields in the SQLDA for the column values to be retrieved, you must dynamically
allocate storage for the SQLDA structure. For C programs, the code looks like this:
The size of the SQLDA is SQLN * 44 + 16, where the value of the SQLN field is the number of output
columns.
You must set the fields in the SQLDA structure for your FETCH statement. Suppose you want to retrieve
the columns EMPNO, LASTNAME, and SALARY. The C code to set the SQLDA fields for these columns
looks like this:
strcpy(sqldaptr->sqldaid,"SQLDA");
sqldaptr->sqldabc = 148; /* number bytes of storage allocated for the SQLDA */
sqldaptr->sqln = 3; /* number of SQLVAR occurrences */
sqldaptr->sqld = 3;
varptr = (struct sqlvar *) (&(sqldaptr->sqlvar[0])); /* Point to first SQLVAR */
varptr->sqltype = 452; /* data type CHAR(6) */
varptr->sqllen = 6;
varptr->sqldata = (char *) hva1;
varptr->sqlind = (short *) inda1;
varptr->sqlname.length = 8;
memcpy(varptr->sqlname.data, "\x00\x00\x00\x00\x00\x01\x00\x14",varptr->sqlname.length);
varptr = (struct sqlvar *) (&(sqldaptr->sqlvar[0]) + 1); /* Point to next SQLVAR */
varptr->sqltype = 448; /* data type VARCHAR(15) */
varptr->sqllen = 15;
varptr->sqldata = (char *) hva2;
varptr->sqlind = (short *) inda2;
varptr->sqlname.length = 8;
memcpy(varptr->sqlname.data, "\x00\x00\x00\x00\x00\x01\x00\x14",varptr->sqlname.length);
varptr = (struct sqlvar *) (&(sqldaptr->sqlvar[0]) + 2); /* Point to next SQLVAR */
varptr->sqltype = 485; /* data type DECIMAL(9,2) */
((struct DECLEN *) &(varptr->sqllen))->precision = 9;
((struct DECLEN *) &(varptr->sqllen))->scale = 2;
varptr->sqldata = (char *) hva3;
varptr->sqlind = (short *) inda3;
varptr->sqlname.length = 8;
memcpy(varptr->sqlname.data, "\x00\x00\x00\x00\x00\x01\x00\x14",varptr->sqlname.length);
408 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
– SQLIND points to the first element of the array of indicator values for the column. If SQLTYPE is an
odd number, this attribute is required. (If SQLTYPE is an odd number, null values are allowed for the
column.)
– SQLNAME has two parts: the LENGTH and the DATA. The LENGTH is 8. The first two bytes of the DATA
field is X'0000'. Bytes 5 and 6 of the DATA field are a flag indicating whether the variable is an array or
a FOR n ROWS value. Bytes 7 and 8 are a two-byte binary integer representation of the dimension of
the array.
You can open the cursor only after all of the fields have been set in the output SQLDA:
After the OPEN statement, the program fetches the next rowset:
EXEC SQL
FETCH NEXT ROWSET FROM C1
FOR 20 ROWS
USING DESCRIPTOR :*sqldaptr;
The USING clause of the FETCH statement names the SQLDA that describes the columns that are to be
retrieved.
After your program executes a FETCH statement to establish the current rowset, you can use a positioned
UPDATE statement with either of the following clauses:
• Use WHERE CURRENT OF to modify all of the rows in the current rowset
• Use FOR ROW n OF ROWSET to modify row n in the current rowset
An example of a positioned UPDATE statement that uses the WHERE CURRENT OF clause is:
EXEC SQL
UPDATE DSN8C10.EMP
SET SALARY = 50000
WHERE CURRENT OF C1
END-EXEC.
When the UPDATE statement is executed, the cursor must be positioned on a row or rowset of the result
table. If the cursor is positioned on a row, that row is updated. If the cursor is positioned on a rowset, all
of the rows in the rowset are updated.
An example of a positioned UPDATE statement that uses the FOR ROW n OF ROWSET clause is:
EXEC SQL
UPDATE DSN8C10.EMP
SET SALARY = 50000
FOR CURSOR C1 FOR ROW 5 OF ROWSET
END-EXEC.
When the UPDATE statement is executed, the cursor must be positioned on a rowset of the result table.
The specified row (in the example, row 5) of the current rowset is updated.
After your program executes a FETCH statement to establish the current rowset, you can use a positioned
DELETE statement with either of the following clauses:
• Use WHERE CURRENT OF to delete all of the rows in the current rowset
• Use FOR ROW n OF ROWSET to delete row n in the current rowset
An example of a positioned DELETE statement that uses the WHERE CURRENT OF clause is:
EXEC SQL
DELETE FROM DSN8C10.EMP
WHERE CURRENT OF C1
END-EXEC.
When the DELETE statement is executed, the cursor must be positioned on a row or rowset of the result
table. If the cursor is positioned on a row, that row is deleted, and the cursor is positioned before the next
EXEC SQL
DELETE FROM DSN8C10.EMP
FOR CURSOR C1 FOR ROW 5 OF ROWSET
END-EXEC.
When the DELETE statement is executed, the cursor must be positioned on a rowset of the result table.
The specified row of the current rowset is deleted, and the cursor remains positioned on that rowset. The
deleted row (in the example, row 5 of the rowset) cannot be retrieved or updated.
Related tasks
Including dynamic SQL in your program
Dynamic SQL is prepared and executed while the program is running.
Executing SQL statements by using a row cursor
You can use row cursors to execute FETCH statements, positioned UPDATE statements, and positioned
DELETE statements.
Related reference
SQL descriptor area (SQLDA) (Db2 SQL)
Procedure
Issue a CLOSE statement.
410 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Retrieving rows by using a scrollable cursor
A scrollable cursor is cursor that can be moved in both a forward and a backward direction. Scrollable
cursors can be either row-positioned or rowset-positioned.
Procedure
When you open any cursor, the cursor is positioned before the first row of the result table. You move
a scrollable cursor around in the result table by specifying a fetch orientation keyword in a FETCH
statement.
A fetch orientation keyword indicates the absolute or relative position of the cursor when the FETCH
statement is executed. The following table lists the fetch orientation keywords that you can specify and
their meanings. These keywords apply to both row-positioned scrollable cursors and rowset-positioned
scrollable cursors.
Table notes
a. The cursor position applies to both row position and rowset position, for example, before the first
row or before the first rowset.
b. For more information about ABSOLUTE and RELATIVE, see FETCH (Db2 SQL)
Example
To use the cursor that is declared in “Types of cursors” on page 397 to fetch the fifth row of the result
table, use a FETCH statement like this:
To fetch the fifth row from the end of the result table, use this FETCH statement:
Related concepts
Types of cursors
You can declare row-positioned or rowset-positioned cursors in a number of ways. These cursors can be
scrollable or not scrollable, held or not held, or returnable or not returnable.
Related reference
FETCH (Db2 SQL)
Table 73. How sensitivity affects the result table for a scrollable cursor
DECLARE sensitivity FETCH INSENSITIVE FETCH SENSITIVE
INSENSITIVE No changes to the underlying table Not valid.
are visible in the result table.
Positioned UPDATE and DELETE
statements using the cursor are not
allowed.
SENSITIVE STATIC Only positioned updates and deletes All updates and deletes are visible in
that are made by the cursor are the result table. Inserts made by other
visible in the result table. processes are not visible in the result
table.
SENSITIVE DYNAMIC Not valid. All committed changes are visible in the
result table, including updates, deletes,
inserts, and changes in the order of the
rows.
/**************************/
/* Declare host variables */
/**************************/
EXEC SQL BEGIN DECLARE SECTION;
char[37] hv_deptname;
EXEC SQL END DECLARE SECTION;
/**********************************************************/
/* Declare scrollable cursor to retrieve department names */
/**********************************************************/
EXEC SQL DECLARE C1 SCROLL CURSOR FOR
SELECT DEPTNAME FROM DSN8C10.DEPT;
⋮
/**********************************************************/
/* Open the cursor and position it before the start of */
412 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
/* the result table. */
/**********************************************************/
EXEC SQL OPEN C1;
EXEC SQL FETCH BEFORE FROM C1;
/**********************************************************/
/* Fetch first 10 rows */
/**********************************************************/
for(i=0;i<10;i++)
{
EXEC SQL FETCH NEXT FROM C1 INTO :hv_deptname;
}
/**********************************************************/
/* Save the value in the tenth row */
/**********************************************************/
tenth_row=hv_deptname;
/**********************************************************/
/* Fetch backward 5 rows */
/**********************************************************/
for(i=0;i<5;i++)
{
EXEC SQL FETCH PRIOR FROM C1 INTO :hv_deptname;
}
/**********************************************************/
/* Save the value in the fifth row */
/**********************************************************/
fifth_row=hv_deptname;
/**********************************************************/
/* Fetch forward 3 rows */
/**********************************************************/
for(i=0;i<3;i++)
{
EXEC SQL FETCH NEXT FROM C1 INTO :hv_deptname;
}
/**********************************************************/
/* Save the value in the eighth row */
/**********************************************************/
eighth_row=hv_deptname;
/**********************************************************/
/* Close the cursor */
/**********************************************************/
EXEC SQL CLOSE C1;
Determining the number of rows in the result table for a static scrollable cursor
You can determine how many rows are in the result table of an INSENSITIVE or SENSITIVE STATIC
scrollable cursor.
Procedure
To determine the number of rows in the result table for a static scrollable cursor, follow these steps:
1. Execute a FETCH statement, such as FETCH AFTER, that positions the cursor after the last row.
2. Perform one of the following actions:
• Retrieve the values of fields SQLERRD(1) and SQLERRD(2) in the SQLCA (fields sqlerrd[0] and
sqlerrd[1] for C and C++). SQLERRD(1) and SQLERRD(2) together form a double-word value that
contains the number of rows in the result table.
• Issue a GET DIAGNOSTICS statement to retrieve the value of the DB2_NUMBER_ROWS item.
Example
The following C language code demonstrates how to obtain the number of rows in a result table of a
sensitive static cursor.
1
2
3
4
5 Update hole disappears
A hole becomes visible to a cursor when a cursor operation returns a non-zero SQLCODE. The point at
which a hole becomes visible depends on the following factors:
• Whether the scrollable cursor creates the hole
• Whether the FETCH statement is FETCH SENSITIVE or FETCH INSENSITIVE
If the scrollable cursor creates the hole, the hole is visible when you execute a FETCH statement for the
row that contains the hole. The FETCH statement can be FETCH INSENSITIVE or FETCH SENSITIVE.
If an update or delete operation outside the scrollable cursor creates the hole, the hole is visible at the
following times:
• If you execute a FETCH SENSITIVE statement for the row that contains the hole, the hole is visible when
you execute the FETCH statement.
414 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
• If you execute a FETCH INSENSITIVE statement, the hole is not visible when you execute the FETCH
statement. Db2 returns the row as it was before the update or delete operation occurred. However, if
you follow the FETCH INSENSITIVE statement with a positioned UPDATE or DELETE statement, the hole
becomes visible.
1
2
3
4
5
Figure 20. Values for COL1 of table A
Now suppose that you declare the following SENSITIVE STATIC scrollable cursor, which you use to delete
rows from A:
The positioned delete statement creates a delete hole, as shown in the following figure.
After you execute the positioned delete statement, the third row is deleted from the result table, but the
result table does not shrink to fill the space that the deleted row creates.
Creating an update hole with a static scrollable cursor
Suppose that you declare the following SENSITIVE STATIC scrollable cursor, which you use to update
rows in A:
The searched UPDATE statement creates an update hole, as shown in the following figure.
EXEC SQL OPEN C4;
EXEC SQL
UPDATE A
1 1
2 SET COL1=COL1+1 2
3 3
4 4
5 5 Update hole
After you execute the searched UPDATE statement, the last row no longer qualifies for the result table,
but the result table does not shrink to fill the space that the disqualified row creates.
416 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
the row that was truncated. Second, if you do not use FETCH WITH CONTINUE, Db2 does not return the
actual length of the entire value to the application program. Thus, Db2 does not know how large a buffer
to reallocate. If you use FETCH WITH CONTINUE, Db2 preserves the truncated portion of the data for
subsequent retrieval and returns the actual length of the entire data value so that the application can
reallocate a buffer of the appropriate size.
Db2 provides two methods for using FETCH WITH CONTINUE with LOB and XML data:
• “Dynamically allocating buffers when fetching XML and LOB data” on page 417
• “Moving data through fixed-size buffers when fetching XML and LOB data” on page 418
Procedure
To use dynamic buffer allocation for LOB and XML data:
1. Use an initial FETCH WITH CONTINUE to fetch data into a pre-allocated buffer of a moderate size.
2. If the value is too large to fit in the buffer, use the length information that is returned by Db2 to allocate
the appropriate amount of storage.
3. Use a single FETCH CURRENT CONTINUE statement to retrieve the remainder of the data.
Example
Suppose that table T1 was created with the following statement:
A row exists in T1 where C1 contains a valid integer, C2 contains 10MB of data, C3 contains 32KB of data,
and C4 contains 4MB of data.
Now, suppose that you declare CURSOR1, prepare and describe statement DYNSQLSTMT1 with
descriptor sqlda, and open CURSOR1 with the following statements:
Next, suppose that you allocate moderately sized buffers (32 KB for each CLOB or XML column) and set
data pointers and lengths in SQLDA. Then, you use the following FETCH WITH CONTINUE statement:
Because C2 and C4 contain data that do not fit in the buffer, some of the data is truncated. Your
application can use the information that Db2 returns to allocate large enough buffers for the remaining
data and reset the data pointers and length fields in SQLDA. At that point, you can resume the fetch
and complete the process with the following FETCH CURRENT CONTINUE statement and CLOSE CURSOR
statement:
The application needs to concatenate the two returned pieces of the data value. One technique is to move
the first piece of data to the dynamically-allocated larger buffer before the FETCH CONTINUE. Set the
SQLDATA pointer in the SQLDA structure to point immediately after the last byte of this truncated value.
Db2 then writes the remaining data to this location and thus completes the concatenation.
Procedure
To use fixed buffer allocation for LOB and XML data, perform the following steps:
1. Use an initial FETCH WITH CONTINUE to fetch data into a pre-allocated buffer of a moderate size.
2. If the value is too large to fit in the buffer, use as many FETCH CONTINUE statements as necessary to
process all of the data through a fixed buffer.
After each FETCH operation, check whether a column was truncated by first examining the SQLWARN1
field in the returned SQLCA. If that field contains a 'W' value, at least one column in the returned
row has been truncated. To then determine if a particular LOB or XML column was truncated, your
application must compare the value that is returned in the length field with the declared length of the
host variable. If a column is truncated, continue to use FETCH CONTINUE statements until all of the
data has been retrieved.
After you fetch each piece of the data, move it out of the buffer to make way for the next fetch. Your
application can write the pieces to an output file or reconstruct the entire data value in a buffer above
the 2-GB bar.
Example
Suppose that table T1 was created with the following statement:
Next, suppose that you use the following statements to declare and open CURSOR1 and to FETCH WITH
CONTINUE:
As each piece of the data value is fetched, move it from the buffer to the output file.
Because the 10 MB value in C2 does not fit into the 32 KB buffer, some of the data is truncated. Your
application can loop through the following FETCH CURRENT CONTINUE:
After each FETCH operation, you can determine if the data was truncated by first checking if the
SQLWARN1 field in the returned SQLCA contains a 'W' value. If so, then check if the length value,
which is returned in CLOBHV_LENGTH, is greater than the declared length of 32767. (CLOBHV_LENGTH
is declared as part of the precompiler expansion of the CLOBHV declaration.) If the value is greater, that
value has been truncated and more data can be retrieved with the next FETCH CONTINUE operation.
When all of the data has moved to the output file, you can close the cursor:
418 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Determining the attributes of a cursor by using the SQLCA
An SQL communications area (SQLCA) is an area that is set apart for communication with Db2 and
consists of a collection of variables. Using the SQLCA is one way to get information about any open
cursors. Alternatively, you can use the GET DIAGNOSTICS statement.
Procedure
When a program retrieves data from the database, it can scroll backward through the data by using one of
the following techniques:
• Use a scrollable cursor to fetch backward through data by following these steps:
a) Declare the cursor with the SCROLL keyword.
b) Open the cursor.
c) Execute a FETCH statement to position the cursor at the end of the result table.
d) In a loop, execute FETCH statements that move the cursor backward and then retrieve the data.
e) When you have retrieved all the data, close the cursor.
For example, you can use code like the following example to retrieve department names in reverse
order from table DSN8C10.DEPT:
/**************************/
/* Declare host variables */
/**************************/
EXEC SQL BEGIN DECLARE SECTION;
char[37] hv_deptname;
EXEC SQL END DECLARE SECTION;
/**********************************************************/
/* Declare scrollable cursor to retrieve department names */
/**********************************************************/
EXEC SQL DECLARE C1 SCROLL CURSOR FOR
SELECT DEPTNAME FROM DSN8C10.DEPT;
⋮
/**********************************************************/
/* Open the cursor and position it after the end of the */
/* result table. */
/**********************************************************/
EXEC SQL OPEN C1;
EXEC SQL FETCH AFTER FROM C1;
/**********************************************************/
/* Fetch rows backward until all rows are fetched. */
/**********************************************************/
while(SQLCODE==0) {
EXEC SQL FETCH PRIOR FROM C1 INTO :hv_deptname;
⋮
}
EXEC SQL CLOSE C1;
• If the table contains a ROWID or an identity column, retrieve the values from that column into an array.
Then use the ROWID or identity column values to retrieve the rows in reverse order.
You can use the ROWID column or identity column to rapidly retrieve the rows in reverse order. When
you perform the original SELECT, you can store the ROWID or identity column value for each row
you retrieve. Then, to retrieve the values in reverse order, you can execute SELECT statements with a
WHERE clause that compares the ROWID or identity column value to each stored value.
For example, suppose you add ROWID column DEPTROWID to table DSN8C10.DEPT. You can use code
like the following example to select all department names, then retrieve the names in reverse order:
/**************************/
/* Declare host variables */
/**************************/
EXEC SQL BEGIN DECLARE SECTION;
SQL TYPE IS ROWID hv_dept_rowid;
char[37] hv_deptname;
EXEC SQL END DECLARE SECTION;
/***************************/
/* Declare other variables */
/***************************/
struct rowid_struct {
short int length;
char data[40]; /* ROWID variable structure */
420 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
}
struct rowid_struct rowid_array[200];
/* Array to hold retrieved */
/* ROWIDs. Assume no more */
/* than 200 rows will be */
/* retrieved. */
short int i,j,n;
/***********************************************/
/* Declare cursor to retrieve department names */
/***********************************************/
EXEC SQL DECLARE C1 CURSOR FOR
SELECT DEPTNAME, DEPTROWID FROM DSN8C10.DEPT;
⋮
/**********************************************************/
/* Retrieve the department name and ROWID from DEPT table */
/* and store the ROWID in an array. */
/**********************************************************/
EXEC SQL OPEN C1;
i=0;
while(SQLCODE==0) {
EXEC SQL FETCH C1 INTO :hv_deptname, :hv_dept_rowid;
rowid_array[i].length=hv_dept_rowid.length;
for(j=0;j<hv_dept_rowid.length;j++)
rowid_array[i].data[j]=hv_dept_rowid.data[j];
i++;
}
EXEC SQL CLOSE C1;
n=i-1; /* Get the number of array elements */
/**********************************************************/
/* Use the ROWID values to retrieve the department names */
/* in reverse order. */
/**********************************************************/
for(i=n;i>=0;i--) {
hv_dept_rowid.length=rowid_array[i].length;
for(j=0;j<hv_dept_rowid.length;j++)
hv_dept_rowid.data[j]=rowid_array[i].data[j];
EXEC SQL SELECT DEPTNAME INTO :hv_deptname
FROM DSN8C10.DEPT
WHERE DEPTROWID=:hv_dept_rowid;
}
Related concepts
Row ID values (Db2 SQL)
Identity columns
An identity column contains a unique numeric value for each row in the table. Db2 can automatically
generate sequential numeric values for this column as rows are inserted into the table. Thus, identity
columns are ideal for primary key values, such as employee numbers or product numbers.
Related tasks
Retrieving rows by using a scrollable cursor
A scrollable cursor is cursor that can be moved in both a forward and a backward direction. Scrollable
cursors can be either row-positioned or rowset-positioned.
Procedure
To update previously retrieved data, use these steps:
1. Declare the cursor with the SENSITIVE STATIC SCROLL keywords.
2. Open the cursor.
Table 74. Interaction between row and rowset positioning for a scrollable cursor
Keywords in FETCH statement Cursor position when FETCH is executed
FIRST On row 1
FIRST ROWSET On a rowset of size 1, consisting of row 1
FIRST ROWSET FOR 5 ROWS On a rowset of size 5, consisting of rows 1, 2, 3, 4, and 5
CURRENT ROWSET On a rowset of size 5, consisting of rows 1, 2, 3, 4, and 5
CURRENT On row 1
NEXT (default) On row 2
NEXT ROWSET On a rowset of size 1, consisting of row 3
NEXT ROWSET FOR 3 ROWS On a rowset of size 3, consisting of rows 4, 5, and 6
NEXT ROWSET On a rowset of size 3, consisting of rows 7, 8, and 9
LAST On row 15
LAST ROWSET FOR 2 ROWS On a rowset of size 2, consisting of rows 14 and 15
PRIOR ROWSET On a rowset of size 2, consisting of rows 12 and 13
ABSOLUTE 2 On row 2
ROWSET STARTING AT ABSOLUTE 2 FOR 3 On a rowset of size 3, consisting of rows 2, 3, and 4
ROWS
RELATIVE 2 On row 4
ROWSET STARTING AT ABSOLUTE 2 FOR 4 On a rowset of size 4, consisting of rows 2, 3, 4, and 5
ROWS
RELATIVE -1 On row 1
ROWSET STARTING AT ABSOLUTE 3 FOR 2 On a rowset of size 2, consisting of rows 3 and 4
ROWS
422 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 74. Interaction between row and rowset positioning for a scrollable cursor (continued)
Keywords in FETCH statement Cursor position when FETCH is executed
ROWSET STARTING AT RELATIVE 4 On a rowset of size 2, consisting of rows 7 and 8
PRIOR On row 6
ROWSET STARTING AT ABSOLUTE 13 FOR 5 On a rowset of size 3, consisting of rows 13, 14, and 15
ROWS
FIRST ROWSET On a rowset of size 5, consisting of rows 1, 2, 3, 4, and 5
Related reference
FETCH (Db2 SQL)
**************************************************
* Declare a cursor that will be used to update *
* the JOB column of the EMP table. *
**************************************************
EXEC SQL
DECLARE THISEMP CURSOR FOR
SELECT EMPNO, LASTNAME,
WORKDEPT, JOB
FROM DSN8C10.EMP
WHERE WORKDEPT = 'D11'
FOR UPDATE OF JOB
END-EXEC.
**************************************************
* Open the cursor *
**************************************************
EXEC SQL
OPEN THISEMP
END-EXEC.
**************************************************
* Indicate what action to take when all rows *
* in the result table have been fetched. *
**************************************************
EXEC SQL
WHENEVER NOT FOUND
GO TO CLOSE-THISEMP
END-EXEC.
**************************************************
* Fetch a row to position the cursor. *
**************************************************
EXEC SQL
FETCH FROM THISEMP
INTO :EMP-NUM, :NAME2,
:DEPT, :JOB-NAME
END-EXEC.
**************************************************
* Update the row where the cursor is positioned. *
**************************************************
EXEC SQL
UPDATE DSN8C10.EMP
SET JOB = :NEW-JOB
WHERE CURRENT OF THISEMP
END-EXEC.
⋮
**************************************************
* Branch back to fetch and process the next row. *
**************************************************
⋮
**************************************************
* Close the cursor *
**************************************************
CLOSE-THISEMP.
The following example shows how to retrieve data backward with a cursor.
**************************************************
* Declare a cursor to retrieve the data backward *
* from the EMP table. The cursor has access to *
* changes by other processes. *
**************************************************
EXEC SQL
DECLARE THISEMP SENSITIVE STATIC SCROLL CURSOR FOR
SELECT EMPNO, LASTNAME, WORKDEPT, JOB
FROM DSN8C10.EMP
END-EXEC.
**************************************************
* Open the cursor *
**************************************************
EXEC SQL
OPEN THISEMP
END-EXEC.
**************************************************
* Indicate what action to take when all rows *
* in the result table have been fetched. *
**************************************************
EXEC SQL
WHENEVER NOT FOUND GO TO CLOSE-THISEMP
END-EXEC.
**************************************************
* Position the cursor after the last row of the *
* result table. This FETCH statement cannot *
* include the SENSITIVE or INSENSITIVE keyword *
* and cannot contain an INTO clause. *
**************************************************
EXEC SQL
FETCH AFTER FROM THISEMP
END-EXEC.
**************************************************
* Fetch the previous row in the table. *
**************************************************
EXEC SQL
FETCH SENSITIVE PRIOR FROM THISEMP
INTO :EMP-NUM, :NAME2, :DEPT, :JOB-NAME
END-EXEC.
**************************************************
* Check that the fetched row is not a hole *
* (SQLCODE +222). If not, print the contents. *
**************************************************
IF SQLCODE IS GREATER THAN OR EQUAL TO 0 AND
SQLCODE IS NOT EQUAL TO +100 AND
SQLCODE IS NOT EQUAL TO +222 THEN
PERFORM PRINT-RESULTS.
⋮
**************************************************
* Branch back to fetch the previous row. *
**************************************************
⋮
**************************************************
* Close the cursor *
**************************************************
CLOSE-THISEMP.
EXEC SQL
CLOSE THISEMP
END-EXEC.
The following example shows how to update an entire rowset with a cursor.
**************************************************
* Declare a rowset cursor to update the JOB *
* column of the EMP table. *
**************************************************
EXEC SQL
DECLARE EMPSET CURSOR
WITH ROWSET POSITIONING FOR
SELECT EMPNO, LASTNAME, WORKDEPT, JOB
FROM DSN8C10.EMP
424 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
WHERE WORKDEPT = 'D11'
FOR UPDATE OF JOB
END-EXEC.
**************************************************
* Open the cursor. *
**************************************************
EXEC SQL
OPEN EMPSET
END-EXEC.
**************************************************
* Indicate what action to take when end-of-data *
* occurs in the rowset being fetched. *
**************************************************
EXEC SQL
WHENEVER NOT FOUND
GO TO CLOSE-EMPSET
END-EXEC.
**************************************************
* Fetch next rowset to position the cursor. *
**************************************************
EXEC SQL
FETCH NEXT ROWSET FROM EMPSET
FOR :SIZE-ROWSET ROWS
INTO :HVA-EMPNO, :HVA-LASTNAME,
:HVA-WORKDEPT, :HVA-JOB
END-EXEC.
**************************************************
* Update rowset where the cursor is positioned. *
**************************************************
UPDATE-ROWSET.
EXEC SQL
UPDATE DSN8C10.EMP
SET JOB = :NEW-JOB
WHERE CURRENT OF EMPSET
END-EXEC.
END-UPDATE-ROWSET.
⋮
**************************************************
* Branch back to fetch the next rowset. *
**************************************************
⋮
**************************************************
* Update the remaining rows in the current *
* rowset and close the cursor. *
**************************************************
CLOSE-EMPSET.
PERFORM UPDATE-ROWSET.
EXEC SQL
CLOSE EMPSET
END-EXEC.
The following example shows how to update specific rows with a rowset cursor.
*****************************************************
* Declare a static scrollable rowset cursor. *
*****************************************************
EXEC SQL
DECLARE EMPSET SENSITIVE STATIC SCROLL CURSOR
WITH ROWSET POSITIONING FOR
SELECT EMPNO, WORKDEPT, JOB
FROM DSN8C10.EMP
FOR UPDATE OF JOB
END-EXEC.
*****************************************************
* Open the cursor. *
*****************************************************
EXEC SQL
OPEN EMPSET
END-EXEC.
*****************************************************
* Fetch next rowset to position the cursor. *
*****************************************************
EXEC SQL
FETCH SENSITIVE NEXT ROWSET FROM EMPSET
FOR :SIZE-ROWSET ROWS
INTO :HVA-EMPNO,
:HVA-WORKDEPT :INDA-WORKDEPT,
:HVA-JOB :INDA-JOB
⋮
*****************************************************
* Branch back to fetch and process *
* the next rowset. *
*****************************************************
⋮
*****************************************************
* Update row N in current rowset. *
*****************************************************
UPDATE-ROW.
EXEC SQL
UPDATE DSN8C10.EMP
SET JOB = :NEW-JOB
FOR CURSOR EMPSET FOR ROW :N OF ROWSET
END-EXEC.
END-UPDATE-ROW.
*****************************************************
* Delete row N in current rowset. *
*****************************************************
DELETE-ROW.
EXEC SQL
DELETE FROM DSN8C10.EMP
WHERE CURRENT OF EMPSET FOR ROW :N OF ROWSET
END-EXEC.
END-DELETE-ROW.
⋮
*****************************************************
* Close the cursor. *
*****************************************************
CLOSE-EMPSET.
EXEC SQL
CLOSE EMPSET
END-EXEC.
426 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Specifying direct row access by using row IDs
For some applications, you can use the value of a ROWID column to navigate directly to a row.
The following code uses the SELECT from INSERT statement to retrieve the value of the ROWID column
from a new row that is inserted into the EMPLOYEE table. This value is then used to reference that row for
the update of the SALARY column.
For Db2 to be able to use direct row access for the update operation, the SELECT from INSERT statement
and the UPDATE statement must execute within the same unit of work. Alternatively, you can use a
SELECT from MERGE statement. The MERGE statement performs INSERT and UPDATE operations as one
coordinated statement.
Requirement: To use direct row access, you must use a retrieved ROWID value before you commit. When
your application commits, it releases its claim on the table space. After the commit, if a REORG is run on
your table space, the physical location of the rows might change.
Restriction: In general, you cannot use a ROWID column as a key that is to be used as a single column
value across multiple tables. The ROWID value for a particular row in a table might change over time due
to a REORG of the table space. In particular, you cannot use a ROWID column as part of a parent key or
foreign key.
The value that you retrieve from a ROWID column is a varying-length character value that is not
monotonically ascending or descending (the value is not always increasing or not always decreasing).
Therefore, a ROWID column does not provide suitable values for many types of entity keys, such as order
numbers or employee numbers.
Procedure
Call the RID built-in function in the search condition of a SELECT, DELETE, or UPDATE statement.
The RID function returns the RID of a row, which you can use to uniquely identify a row.
Restriction: Because Db2 might reuse RID numbers when the REORG utility is run, the RID function might
return different values when invoked for a row multiple times.
If you specify a RID and Db2 cannot locate the row through direct row access, Db2 does not switch to
another access method. Instead, Db2 returns no rows.
Related concepts
Rules for inserting data into a ROWID column
A ROWID column contains unique values that identify each row in a table. Whether you can insert data
into a ROWID column and how that data gets inserted depends on how the column is defined.
Direct row access (PRIMARY_ACCESSTYPE='D') (Db2 Performance)
Row ID values (Db2 SQL)
Related reference
RID (Db2 SQL)
428 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
SQL TYPE IS CLOB_LOCATOR deptBuffer;
EXEC SQL END DECLARE SECTION;
⋮
EXEC SQL DECLARE C1 CURSOR FOR
SELECT EMPNO, EMP_RESUME FROM EMP;
⋮
EXEC SQL FETCH C1 INTO :employeenum, :resume;
⋮
EXEC SQL SET :deptInfoBeginLoc =
POSSTR(:resume.data, 'Department Information');
These statements use host variables of data type large object locator (LOB locator). LOB locators let you
manipulate LOB data without moving the LOB data into host variables. By using LOB locators, you need
much smaller amounts of memory for your programs.
You can also use LOB file reference variables when you are working with LOB data. You can use LOB file
reference variables to insert LOB data from a file into a Db2 table or to retrieve LOB data from a Db2 table.
Sample LOB applications: The following table lists the sample programs that Db2 provides to assist you in
writing applications to manipulate LOB data. All programs reside in data set DSN1210.SDSNSAMP.
Related concepts
LOB file reference variables
In a host application, you can use a file reference variable to insert a LOB or XML value from a file into a
Db2 table. You can also use a file reference variable to select a LOB or XML value from a Db2 table into a
file.
Phase 7: Accessing LOB data (Db2 Installation and Migration)
Related tasks
Saving storage when manipulating LOBs by using LOB locators
LOB host variable, LOB locator, and LOB file reference variable declarations
When you write applications to manipulate LOB data, you need to declare host variables to hold the LOB
data or LOB locator. Alternatively, you need to declare LOB file reference variables to point to the LOB
data.
You can declare LOB host variables and LOB locators in assembler, C, C++, COBOL, Fortran, and PL/I.
Additionally, you can declare LOB file reference variables in assembler, C, C++, COBOL, and PL/I. For each
host variable, locator, or file reference variable of SQL type BLOB, CLOB, or DBCLOB that you declare,
Db2 generates an equivalent declaration that uses host language data types. When you refer to a LOB
host variable, LOB locator, or LOB file reference variable in an SQL statement, you must use the variable
that you specified in the SQL type declaration. When you refer to the host variable in a host language
statement, you must use the variable that Db2 generates.
Db2 supports host variable declarations for LOBs with lengths of up to 2 GB - 1. However, the size of a
LOB host variable is limited by the restrictions of the host language and the amount of storage available to
the program.
Declare LOB host variables that are referenced by the precompiler in SQL statements by using the SQL
TYPE IS BLOB, SQL TYPE IS CLOB, or SQL TYPE IS DBCLOB keywords.
LOB host variables that are referenced only by an SQL statement that uses a DESCRIPTOR should use the
same form as declared by the precompiler. In this form, the LOB host-variable-array consists of a 31-bit
length, followed by the data, followed by another 31-bit length, followed by the data, and so on. The
31-bit length must be fullword aligned.
Example: Suppose that you want to allocate a LOB array of 10 elements, each with a length of 5 bytes.
You need to allocate the following bytes for each element, for a total of 120 bytes:
• 4 bytes for the 31-bit integer
• 5 bytes for the data
• 3 bytes to force fullword alignment
The following examples show you how to declare LOB host variables in each supported language. In
each table, the left column contains the declaration that you code in your application program. The right
column contains the declaration that Db2 generates.
The following table shows assembler language declarations for some typical LOB types.
430 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 76. Example of assembler LOB variable declarations (continued)
You declare this variable Db2 generates this variable
blob_var SQL TYPE IS BLOB 1M
blob_var DS 0FL4
blob_var_length DS FL4
blob_var_data DS CL655351
ORG blob_var_data+(1048476-65535)
Notes:
1. Because assembler language allows character declarations of no more than 65535 bytes, Db2 separates
the host language declarations for BLOB and CLOB host variables that are longer than 65535 bytes into two
parts.
2. Because assembler language allows graphic declarations of no more than 65534 bytes, Db2 separates the
host language declarations for DBCLOB host variables that are longer than 65534 bytes into two parts.
The following table shows C and C++ language declarations for some typical LOB types.
The declarations that are generated for COBOL depend on whether you use the Db2 precompiler or the
Db2 coprocessor. The following table shows COBOL declarations that the Db2 precompiler generates for
some typical LOB types. The declarations that the Db2 coprocessor generates might be different.
01 BLOB-VAR 01 BLOB-VAR.
SQL TYPE IS BLOB(1M). 49 BLOB-VAR-LENGTH PIC S9(9) COMP-5.
49 BLOB-VAR-DATA PIC X(1048576).
01 CLOB-VAR 01 CLOB-VAR.
SQL TYPE IS CLOB(40000K). 49 CLOB-VAR-LENGTH PIC S9(9) COMP-5.
49 CLOB-VAR-DATA PIC X(40960000).
01 DBCLOB-VAR 01 DBCLOB-VAR.
SQL TYPE IS DBCLOB(4000K). 49 DBCLOB-VAR-LENGTH PIC S9(9) COMP-5
49 DBCLOB-VAR-DATA PIC G(40960000)
DISPLAY-1.
432 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 78. Examples of COBOL variable declarations by the Db2 precompiler (continued)
You declare this variable Db2 precompiler generates this variable
01 BLOB-FILE 01 BLOB-FILE.
SQLTYPE IS BLOB-FILE. 49 BLOB-FILE-NAME-LENGTH PIC S9(9) COMP-5 SYNC.
49 BLOB-FILE-DATA-LENGTH PIC S9(9) COMP-5.
49 BLOB-FILE-FILE-OPTION PIC S9(9) COMP-5.
49 BLOB-FILE-NAME PIC X(255) .
01 CLOB-FILE 01 CLOB-FILE.
SQLTYPE IS CLOB-FILE. 49 CLOB-FILE-NAME-LENGTH PIC S9(9) COMP-5 SYNC.
49 CLOB-FILE-DATA-LENGTH PIC S9(9) COMP-5.
49 CLOB-FILE-FILE-OPTION PIC S9(9) COMP-5.
49 CLOB-FILE-NAME PIC X(255) .
01 DBCLOB-FILE 01 DBCLOB-FILE.
SQLTYPE IS DBCLOB-FILE. 49 DBCLOB-FILE-NAME-LENGTH PIC S9(9) COMP-5 SYNC.
49 DBCLOB-FILE-DATA-LENGTH PIC S9(9) COMP-5.
49 DBCLOB-FILE-FILE-OPTION PIC S9(9) COMP-5.
49 DBCLOB-FILE-NAME PIC X(255) .
The following table shows Fortran declarations for some typical LOB types.
The declarations that are generated for PL/I depend on whether you use the Db2 precompiler or the Db2
coprocessor. The following table shows PL/I declarations that the Db2 precompiler generates for some
typical LOB types. The declarations that the Db2 coprocessor generates might be different.
434 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 80. Examples of PL/I variable declarations by the Db2 precompiler (continued)
You declare this variable Db2 precompiler generates this variable
Notes:
1. For BLOB or CLOB host variables that are greater than 32767 bytes in length, Db2 creates PL/I host
language declarations in the following way:
• If the length of the LOB is greater than 32767 bytes and evenly divisible by 32767, Db2 creates an array of
32767-byte strings. The dimension of the array is length/32767.
• If the length of the LOB is greater than 32767 bytes but not evenly divisible by 32767, Db2 creates
two declarations: The first is an array of 32767 byte strings, where the dimension of the array, n, is
length/32767. The second is a character string of length length-n*32767.
2. For DBCLOB host variables that are greater than 16383 double-byte characters in length, Db2 creates PL/I
host language declarations in the following way:
• If the length of the LOB is greater than 16383 characters and evenly divisible by 16383, Db2 creates an
array of 16383-character strings. The dimension of the array is length/16383.
• If the length of the LOB is greater than 16383 characters but not evenly divisible by 16383, Db2 creates
two declarations: The first is an array of 16383 byte strings, where the dimension of the array, m, is
length/16383. The second is a character string of length length-m*16383.
Related concepts
LOB file reference variables
In a host application, you can use a file reference variable to insert a LOB or XML value from a file into a
Db2 table. You can also use a file reference variable to select a LOB or XML value from a Db2 table into a
file.
Related tasks
Saving storage when manipulating LOBs by using LOB locators
LOB locators let you manipulate LOB data without retrieving the data from the Db2 table. By using
locators, you avoid needing to allocate the large amounts of storage that are needed for host variables to
hold LOB data.
436 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
To free LOB locators after their associated LOB values are retrieved, run the FREE LOCATOR statement:
Related reference
FREE LOCATOR (Db2 SQL)
HOLD LOCATOR (Db2 SQL)
Db2 must materialize the LOB that is specified by :Unicode_lob_locator and convert that entire LOB to
EBCDIC before executing the statement. To avoid materialization and conversion, you can execute the
following statement, which produces the same result but is processed by the Unicode encoding scheme
of the table:
/**************************/
/* Declare host variables */ 1
/**************************/
EXEC SQL BEGIN DECLARE SECTION;
char userid[9];
char passwd[19];
long HV_START_DEPTINFO;
long HV_START_EDUC;
long HV_RETURN_CODE;
SQL TYPE IS CLOB_LOCATOR HV_NEW_SECTION_LOCATOR;
SQL TYPE IS CLOB_LOCATOR HV_DOC_LOCATOR1;
SQL TYPE IS CLOB_LOCATOR HV_DOC_LOCATOR2;
SQL TYPE IS CLOB_LOCATOR HV_DOC_LOCATOR3;
EXEC SQL END DECLARE SECTION;
/*************************************************/
/* Delete any instance of "A00130" from previous */
/* executions of this sample */
/*************************************************/
EXEC SQL DELETE FROM EMP_RESUME WHERE EMPNO = 'A00130';
/*************************************************/
/* Use a single row select to get the document */ 2
/*************************************************/
EXEC SQL SELECT RESUME
INTO :HV_DOC_LOCATOR1
FROM EMP_RESUME
WHERE EMPNO = '000130'
AND RESUME_FORMAT = 'ascii';
/*****************************************************/
/* Use the POSSTR function to locate the start of */
/* sections "Department Information" and "Education" */ 3
/*****************************************************/
EXEC SQL SET :HV_START_DEPTINFO =
POSSTR(:HV_DOC_LOCATOR1, 'Department Information');
438 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
EXEC SQL SET :HV_START_EDUC =
POSSTR(:HV_DOC_LOCATOR1, 'Education');
/*******************************************************/
/* Replace Department Information section with nothing */
/*******************************************************/
EXEC SQL SET :HV_DOC_LOCATOR2 =
SUBSTR(:HV_DOC_LOCATOR1, 1, :HV_START_DEPTINFO -1)
|| SUBSTR (:HV_DOC_LOCATOR1, :HV_START_EDUC);
/*******************************************************/
/* Associate a new locator with the Department */
/* Information section */
/*******************************************************/
EXEC SQL SET :HV_NEW_SECTION_LOCATOR =
SUBSTR(:HV_DOC_LOCATOR1, :HV_START_DEPTINFO,
:HV_START_EDUC -:HV_START_DEPTINFO);
/*******************************************************/
/* Append the Department Information to the end */
/* of the resume */
/*******************************************************/
EXEC SQL SET :HV_DOC_LOCATOR3 =
:HV_DOC_LOCATOR2 || :HV_NEW_SECTION_LOCATOR;
/*******************************************************/
/* Store the modified resume in the table. This is */ 4
/* where the LOB data really moves. */
/*******************************************************/
EXEC SQL INSERT INTO EMP_RESUME VALUES ('A00130', 'ascii',
:HV_DOC_LOCATOR3, DEFAULT);
/*********************/
/* Free the locators */ 5
/*********************/
EXEC SQL FREE LOCATOR :HV_DOC_LOCATOR1, :HV_DOC_LOCATOR2, :HV_DOC_LOCATOR3;
Notes:
1
Declare the LOB locators here.
2
This SELECT statement associates LOB locator HV_DOC_LOCATOR1 with the value of column RESUME
for employee number 000130.
3
The next five SQL statements use LOB locators to manipulate the resume data without moving the
data.
4
Evaluation of the LOB expressions in the previous statements has been deferred until execution of this
INSERT statement.
5
Free all LOB locators to release them from their associated values.
440 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Examples of declaring file reference variables
You can declare a file reference variable in C, COBOL, and PL/I, and declare the file reference variable
construct that Db2 generates.
C Example: Consider the following C declaration:
With the Db2-generated construct, you can use the following code to select from a CLOB column in the
database into a new file that is referenced by :hv_text_file. The file name must be an absolute path.
strcopy(hv_text_file.name, "/u/gainer/papers/sigmod.94");
hv_text_file.name_length = strlen("/u/gainer/papers/sigmod.94");
hv_text_file.file_options = SQL_FILE_CREATE;
Similarly, you can use the following code to insert the data from a file that is referenced
by :hv_text_file into a CLOB column. The file name must be an absolute path.
strcopy(hv_text_file.name, "/u/gainer/patents/chips.13");
hv_text_file.name_length = strlen("/u/gainer/patents/chips.13");
hv_text_file.file_options = SQL_FILE_READ;
strcopy(:hv_patent_title, "A Method for Pipelining Chip Consumption");
01 MY-FILE.
49 MY-FILE-NAME-LENGTH PIC S9(9) COMP-5.
49 MY-FILE-DATA-LENGTH PIC S9(9) COMP-5.
49 MY-FILE-FILE-OPTION PIC S9(9) COMP-5.
49 MY-FILE-NAME PIC(255);
DCL 1 MY_FILE,
3 MY_FILE_NAME_LENGTH BINARY FIXED (31) UNALIGNED,
3 MY_FILE_DATA_LENGTH BINARY FIXED (31) UNALIGNED,
3 MY_FILE_FILE_OPTIONS BINARY FIXED (31) UNALIGNED,
3 MY_FILE_NAME CHAR(255);
Procedure
Issue a SELECT statement with the ROW CHANGE TIMESTAMP column in the column list.
If a qualifying row does not have a value for the ROW CHANGE TIMESTAMP column, Db2 returns the time
that the page in which that row resides was updated.
Example
Suppose that you issue the following statements to create, populate, and alter a table:
442 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
FOR EACH ROW ON UPDATE AS ROW CHANGE TIMESTAMP;
SELECT T1.C2 FROM T1 WHERE T1.C1 = 1;
Because the ROW CHANGE TIMESTAMP column was added after the data was inserted, the following
statement returns the time that the page was last modified:
Assume that this row is added to the same page as the first row. The following statement returns the time
that value "2" was inserted into the table:
Because the row with value "1" still does not have a value for the ROW CHANGE TIMESTAMP column, the
following statement still returns the time that the page was last modified, which in this case is the time
that value "2" was inserted:
Related reference
CREATE TABLE (Db2 SQL)
Procedure
Specify the XMLEXISTS predicate in the WHERE clause of your SQL statement.
Include the following parameters for the XMLEXISTS predicate:
• An XPath expression that is embedded in a character string literal. Specify an XPath expression that
identifies the XML data that you are looking for. If the result of the XPath expression is an empty
sequence, XMLEXISTS returns false. If the result is not empty, XMLEXISTS returns true. If the evaluation
of the XPath expression returns an error, XMLEXISTS returns an error.
• The XML column name. Specify this value after the PASSING keyword.
Example
Suppose that you want to return only purchase orders that have a billing address. Assume that column
XMLPO stores the XML purchase order documents and that the billTo nodes within these documents
contain any billing addresses. You can use the following SELECT statement with the XMLEXISTS
predicate:
Related reference
XMLEXISTS predicate (Db2 SQL)
Procedure
To return the value of an SQL expression that does not include the value of a table column in host variable,
use one of the following approaches:
• Use the SET host-variable assignment statement to set the contents of a host variable to the value of
an expression.
• Use the VALUES INTO statement to return the value of an expression in a host variable.
• Use the following statement to select the expression from the Db2-provided EBCDIC table, named
SYSIBM.SYSDUMMY1, which consists of one row.
Related reference
SET assignment-statement (Db2 SQL)
VALUES INTO (Db2 SQL)
SYSDUMMY1 catalog table (Db2 SQL)
Procedure
To ensure that queries perform sufficiently:
1. Tune each query in your program by following the general tuning guidelines for how to write efficient
queries. For more information, see Writing efficient SQL queries (Db2 Performance).
2. If you suspect that a query is not as efficient as it could be, monitor its performance.
You can use a number of different functions and techniques to monitor SQL performance, including the
EXPLAIN statement.
Related concepts
Investigating SQL performance by using EXPLAIN (Db2 Performance)
Interpreting data access by using EXPLAIN (Db2 Performance)
Related tasks
Investigating access path problems (Db2 Performance)
Related reference
EXPLAIN (Db2 SQL)
444 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Items to include in a batch DL/I program
When you use a batch DL/I program with Db2, you must include certain items in your program.
A batch DL/I program can issue:
• Any IMS batch call, except ROLS, SETS, and SYNC calls. ROLS and SETS calls provide intermediate
backout point processing, which Db2 does not support. The SYNC call provides commit point processing
without identifying the commit point with a value. IMS does not allow a SYNC call in batch, and neither
does the Db2 DL/I batch support.
Issuing a ROLS, SETS, or SYNC call in an application program causes a system abend X'04E' with the
reason code X'00D44057' in register 15.
• GSAM calls.
• IMS system services calls.
• Any SQL statements, except COMMIT and ROLLBACK. IMS and CICS environments do not allow those
SQL statements; however, IMS and CICS do allow ROLLBACK TO SAVEPOINT. You can use the IMS
CHKP call to commit data and the IMS ROLL or ROLB to roll back changes.
Issuing a COMMIT statement causes SQLCODE -925; issuing a ROLLBACK statement causes SQLCODE
-926. Those statements also return SQLSTATE '2D521'.
• Any call to a standard or traditional access method (for example, QSAM, VSAM, and so on).
The restart capabilities for Db2 and IMS databases, as well as for sequential data sets that are accessed
through GSAM, are available through the IMS Checkpoint and Restart facility.
Db2 allows access to both Db2 and DL/I data through the use of the following Db2 and IMS facilities:
• IMS synchronization calls, which commit and abnormally terminate units of recovery
• The Db2 IMS attachment facility, which handles the two-phase commit protocol and enables both
systems to synchronize a unit of recovery during a restart after a failure
• The IMS log, which is used to record the instant of commit
In a data sharing environment, DL/I batch supports group attachment or subgroup attachment. You can
specify a group attachment name instead of a subsystem name in the SSN parameter of the DDITV02
data set for the DL/I batch job.
446 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
To prepare and run applications that contain embedded static SQL statements or dynamic SQL
statements, you must process, compile, link-edit, and bind the SQL statements.
C1 C2
-- --
1 b
2 c
3 a
COUNTER is a user-defined function that increments a variable in the scratchpad each time it is invoked.
Db2 invokes an instance of COUNTER in the predicate 3 times. Assume that COUNTER is invoked for row
1 first, for row 2 second, and for row 3 third. Then COUNTER returns 1 for row 1, 2 for row 2, and 3 for
row 3. Therefore, row 2 satisfies the predicate WHERE COUNTER()=2, so Db2 evaluates the SELECT list
for row 2. Db2 uses a different instance of COUNTER in the select list from the instance in the predicate.
Because the instance of COUNTER in the select list is invoked only once, it returns a value of 1. Therefore,
the result of the query is:
COUNTER() C1 C2
--------- -- --
1 2 c
COUNTER() C1 C2
--------- -- --
1 1 b
Understand the interaction between scrollable cursors and nondeterministic user-defined functions or
user-defined functions with external actions: When you use a scrollable cursor, you might retrieve the
448 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Ensuring that Db2 executes the intended user-defined function
Multiple functions can with the same name can exist in the same schema or in different schemas. You can
take certain actions so that Db2 chooses the correct function to execute.
Procedure
To simplify the resolution of built-in and user-defined functions, use the following techniques:
• When you invoke a function, use the qualified name.
This causes Db2 to search for functions only in the schema you specify. This approach has the
following advantages:
– Db2 is less likely to choose a function that you did not intend to use. Several functions might fit the
invocation equally well. Db2 picks the function whose schema name is listed first in the SQL path,
which might not be the function you want.
– The number of candidate functions is smaller, so Db2 takes less time for function resolution.
• Cast parameters in a user-defined function invocation to the types in the user-defined function
definition. For example, if an input parameter for user-defined function FUNC is defined as
DECIMAL(13,2), and the value you want to pass to the user-defined function is an integer value, cast
the integer value to DECIMAL(13,2):
For example, if an input parameter for user-defined function FUNC is defined as DECIMAL(13,2), and
the value you want to pass to the user-defined function is an integer value, cast the integer value to
DECIMAL(13,2):
• Use the data type BIGINT for numeric parameters in a user-defined function.
When you invoke the function, you can pass in SMALLINT, INTEGER, or BIGINT values. If you use
SMALLINT or REAL as the parameter type, you must pass parameters of the same types. For example,
if user-defined function FUNC is defined with a parameter of type SMALLINT, only an invocation with a
parameter of type SMALLINT resolves correctly. The following call does not resolve to FUNC because
the constant 123 is of type INTEGER, not SMALLINT:
• Avoid defining user-defined function string parameters with fixed-length string types.
If you define a parameter with a fixed-length string type (CHAR, GRAPHIC, or BINARY), you can
invoke the user-defined function only with a fixed-length string parameter. However, if you define
the parameter with a varying-length string type (VARCHAR, VARGRAPHIC, or VARBINARY), you can
invoke the user-defined function with either a fixed-length string parameter or a varying-length string
parameter.
If you must define parameters for a user-defined function as CHAR or BINARY, and you call the user-
defined function from a C program or SQL procedure, you need to cast the corresponding parameter
values in the user-defined function invocation to CHAR or BINARY to ensure that Db2 invokes the
correct function. For example, suppose that a C program calls user-defined function CVRTNUM, which
UPDATE EMP
SET EMPNO=CVRTNUM(CHAR(:empnumbr))
WHERE EMPNO = :empnumbr;
Related concepts
Functions (Db2 SQL)
450 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
If the function name is unqualified in the invocation, the schema of the function instance matches a
schema in the invoker's SQL path.
• The name of the function instance matches the name in the function invocation.
• The number of input parameters in the function instance matches the number of input parameters in
the function invocation.
• The function invoker is authorized to execute the function instance.
• The type of each of the input parameters in the function invocation matches or is promotable to the type
of the corresponding parameter in the function instance.
If an input parameter in the function invocation is an untyped parameter marker, Db2 considers that
parameter to be a match or promotable.
For a function invocation that passes a transition table, the data type, length, precision, and scale of
each column in the transition table must match exactly the data type, length, precision, and scale
of each column of the table that is named in the function instance definition. For information about
transition tables, see “Creating a trigger” on page 149.
• The create timestamp for a user-defined function must be older than the BIND or REBIND timestamp
for the package or plan in which the user-defined function is invoked.
If Db2 authorization checking is in effect, and Db2 performs an automatic rebind on a plan or package
that contains a user-defined function invocation, any user-defined functions that were created after the
original BIND or REBIND of the invoking plan or package are not candidates for execution.
If you use an access control authorization exit routine, some user-defined functions that were not
candidates for execution before the original BIND or REBIND of the invoking plan or package might
become candidates for execution during the automatic rebind of the invoking plan or package.
If a user-defined function is invoked during an automatic rebind, and that user-defined function is
invoked from a trigger body and receives a transition table, then the form of the invoked function that
Db2 uses for function selection includes only the columns of the transition table that existed at the time
of the original BIND or REBIND of the package or plan for the invoking program.
During an automatic rebind, Db2 does not consider built-in functions for function resolution if those
built-in functions were introduced in a later release of Db2 than the release in which the BIND or
REBIND of the invoking plan or package occurred.
When you explicitly bind or rebind a plan or package, the plan or package receives a release
dependency marker. When Db2 performs an automatic rebind of a query that contains a function
invocation, a built-in function is a candidate for function resolution only if the release dependency
marker of the built-in function is the same as or lower than the release dependency marker of the plan
or package that contains the function invocation.
Example: Suppose that in this statement, the data type of A is SMALLINT:
Two instances of USER1.ADDTWO are defined: one with an input parameter of type INTEGER and
one with an input parameter of type DECIMAL. Both function instances are candidates for execution
because the SMALLINT type is promotable to either INTEGER or DECIMAL. However, the instance with
the INTEGER type is a better fit because INTEGER is higher in the list than DECIMAL.
How Db2 chooses the best fit among candidate functions:
More than one function instance might be a candidate for execution. In that case, Db2 determines which
function instances are the best fit for the invocation by comparing parameter data types.
If the data types of all parameters in a function instance are the same as those in the function invocation,
that function instance is a best fit. If no exact match exists, Db2 compares data types in the parameter
lists from left to right, using this method:
1. Db2 compares the data types of the first parameter in the function invocation to the data type of the
first parameter in each function instance.
In user-defined function FUNC, VCHARCOL has data type VARCHAR, SMINTCOL has data type SMALLINT,
and DECCOL has data type DECIMAL. Also suppose that two function instances with the following
definitions meet the appropriate criteria and are therefore candidates for execution.
Candidate 1:
CREATE FUNCTION FUNC(VARCHAR(20),INTEGER,DOUBLE)
RETURNS DECIMAL(9,2)
EXTERNAL NAME 'FUNC1'
PARAMETER STYLE SQL
LANGUAGE COBOL;
Candidate 2:
CREATE FUNCTION FUNC(VARCHAR(20),REAL,DOUBLE)
RETURNS DECIMAL(9,2)
EXTERNAL NAME 'FUNC2'
PARAMETER STYLE SQL
LANGUAGE COBOL;
Db2 compares the data type of the first parameter in the user-defined function invocation to the data
types of the first parameters in the candidate functions. Because the first parameter in the invocation has
data type VARCHAR, and both candidate functions also have data type VARCHAR, Db2 cannot determine
the better candidate based on the first parameter. Therefore, Db2 compares the data types of the second
parameters.
The data type of the second parameter in the invocation is SMALLINT. INTEGER, which is the data type
of candidate 1, is a better fit to SMALLINT than REAL, which is the data type of candidate 2. Therefore,
candidate 1 is the Db2 choice for execution.
Related concepts
Promotion of data types (Db2 SQL)
Related tasks
Creating a trigger
A trigger is a set of SQL statements that execute when a certain event occurs in a table or view. Use
triggers to control changes in Db2 databases. Triggers are more powerful than constraints because they
can monitor a broader range of changes and perform a broader range of actions. This topic describes
support for advanced triggers.
Related information
Exit routines (Db2 Administration Guide)
Procedure
To check how Db2 resolves a function by using DSN_FUNCTION_TABLE:
1. If your_userID.DSN_FUNCTION_TABLE does not already exist, create this table by following the
instructions in DSN_FUNCTION_TABLE (Db2 Performance).
452 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
2. Populate your_userID.DSN_FUNCTION_TABLE with information about which functions are invoked by a
particular SQL statement by performing one of the following actions:
• Execute the EXPLAIN statement on the SQL statement.
• Ensure that the program that contains the SQL statement is bound with EXPLAIN(YES) and run the
program.
Db2 puts a row in your_userID.DSN_FUNCTION_TABLE for each function that is referenced in each SQL
statement.
3. Check the rows that were added to your_userID.DSN_FUNCTION_TABLE to ensure that the appropriate
function was invoked. Use the following columns to help you find applicable rows: QUERYNO,
APPLNAME, PROGNAM, COLLID, and EXPLAIN_TIME.
Related reference
BIND and REBIND options for packages, plans, and services (Db2 Commands)
EXPLAIN (Db2 SQL)
The HOUR function takes only the TIME or TIMESTAMP data type as an argument, so you need a sourced
function that is based on the HOUR function that accepts the FLIGHT_TIME data type. You might declare a
function like this:
Example: Casting function arguments to acceptable types: Another way you can invoke the HOUR
function is to cast the argument of type FLIGHT_TIME to the TIME data type before you invoke the
HOUR function. Suppose table FLIGHT_INFO contains column DEPARTURE_TIME, which has data type
FLIGHT_TIME, and you want to use the HOUR function to extract the hour of departure from the departure
time. You can cast DEPARTURE_TIME to the TIME data type, and then invoke the HOUR function:
Because the US_DOLLAR type is based on the DECIMAL(9,2) type, the source function must be the
version of + with arguments of type DECIMAL(9,2).
Example: Casting constants and host variables to distinct types to invoke a user-defined function:
Suppose function CDN_TO_US is defined like this:
This means that EURO_TO_US accepts only the EURO type as input. Therefore, if you want to call
CDN_TO_US with a constant or host variable argument, you must cast that argument to distinct type
EURO:
Sourced user-defined function TAXFN2, which is sourced on TAXFN1, is defined like this:
UPDATE TB1
SET SALESTAX2 = TAXFN2(PRICE2);
454 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
SALESTAX1 DEC(5,2),
PRICE2 DEC(9,2),
SALESTAX2 DEC(7,2));
Now suppose that PRICE2 has the DECIMAL(9,2) value 0001234.56. Db2 must first assign this value
to the data type of the input parameter in the definition of TAXFN2, which is DECIMAL(8,2). The input
parameter value then becomes 001234.56. Next, Db2 casts the parameter value to a source function
parameter, which is DECIMAL(6,0). The parameter value then becomes 001234. (When you cast a value,
that value is truncated, rather than rounded.)
Now, if TAXFN1 returns the DECIMAL(5,2) value 123.45, Db2 casts the value to DECIMAL(5,0), which is
the result type for TAXFN2, and the value becomes 00123. This is the value that Db2 assigns to column
SALESTAX2 in the UPDATE statement.
Related concepts
Assignment and comparison (Db2 SQL)
Procedure
To include Db2 for z/OS queries in an application program:
1. Choose one of the following methods for communicating with Db2:
Static SQL
The source form of a static SQL statement is embedded within an application program written in a
host language. The statement is prepared before the program is executed and the operational form
of the statement persists beyond the execution of the program.
Embedded dynamic SQL
Dynamic SQL is prepared and executed while the program is running.
Open Database Connectivity (ODBC)
You access data through ODBC function calls in your application. You execute SQL statements by
passing them to Db2 through a ODBC function call. ODBC eliminates the need for precompiling
and binding your application and increases the portability of your application by using the ODBC
interface.
JDBC application support
If you are writing your applications in Java, you can use JDBC application support to access Db2.
JDBC is similar to ODBC but is designed specifically for use with Java.
What to do next
“Writing applications that enable users to create and modify tables” on page 537
“Saving SQL statements that are translated from user requests” on page 538
Related concepts
Example programs that call stored procedures
Examples can be used as models when you write applications that call stored procedures. In
addition, prefix.SDSNSAMP contains sample jobs DSNTEJ6P and DSNTEJ6S and programs DSN8EP1 and
DSN8EP2, which you can run.
XML data in embedded SQL applications (Db2 Programming for XML)
Introduction to Db2 ODBC (Db2 Programming for ODBC)
JDBC application programming (Db2 Application Programming for Java)
SQLJ application programming (Db2 Application Programming for Java)
458 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Related tasks
Including dynamic SQL in your program
Dynamic SQL is prepared and executed while the program is running.
Programming applications for performance (Db2 Performance)
Retrieving a set of rows by using a cursor
In an application program, you can retrieve a set of rows from a table or a result table that is returned by a
stored procedure. You can retrieve one or more rows at a time.
Writing efficient SQL queries (Db2 Performance)
Procedure
To declare table and view definitions, use one of the following methods:
• Include an SQL DECLARE TABLE statement in your program. Specify the name of the table or view and
list each column and its data type.
When you declare a table or view that contains a column with a distinct type, declare that column
with the source type of the distinct type rather than with the distinct type itself. When you declare the
column with the source type, Db2 can check embedded SQL statements that reference that column at
precompile time.
In a COBOL program, code the DECLARE TABLE statement in the WORKING-STORAGE SECTION or
LINKAGE SECTION within the DATA DIVISION.
For example, the following DECLARE TABLE statement in a COBOL program defines the
DSN8C10.DEPT table:
EXEC SQL
DECLARE DSN8C10.DEPT TABLE
(DEPTNO CHAR(3) NOT NULL,
DEPTNAME VARCHAR(36) NOT NULL,
MGRNO CHAR(6) ,
ADMRDEPT CHAR(3) NOT NULL,
LOCATION CHAR(16) )
END-EXEC.
• Use DCLGEN, the declarations generator that is supplied with Db2, to create these declarations for you
and then include them in your program.
Restriction: You can use DCLGEN for only C, COBOL, and PL/I programs.
Related concepts
DCLGEN (declarations generator)
Procedure
To generate table and view declarations by using DCLGEN:
1. Invoke DCLGEN by performing one of the following actions:
• To start DCLGEN from ISPF through DB2I: Select the DCLGEN option on the DB2I Primary Option
Menu panel. Then follow the detailed instructions for generating table and view declarations by using
DCLGEN from DB2I.
• To start DCLGEN directly from TSO: Sign on to TSO, issue the TSO command DSN, and then issue
the subcommand DCLGEN.
• To start DCLGEN directly from a CLIST: From a CLIST, running in TSO foreground or background,
issue DSN and then DCLGEN.
• To start DCLGEN with JCL: Supply the required information in JCL and run DCLGEN in batch. Use the
sample jobs DSNTEJ2C and DSNTEJ2P in the prefix.SDSNSAMP library as models.
460 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Requirement: If you want to start DCLGEN in the foreground and your table names include DBCS
characters, you must provide and display double-byte characters. If you do not have a terminal that
displays DBCS characters, you can enter DBCS characters by using the hex mode of ISPF edit.
DCLGEN creates the declarations in the specified data set.
DCLGEN generates a table or column name in the DECLARE statement as a non-delimited identifier
unless at least one of the following conditions is true:
• The name contains special characters and is not a DBCS string.
• The name is a DBCS string, and you have requested delimited DBCS names.
2. If you use an SQL reserved word as an identifier, edit the DCLGEN output to add the appropriate SQL
delimiters.
3. Make any other necessary edits to the DCLGEN output.
DCLGEN produces output that is intended to meet the needs of most users, but occasionally, you need
to edit the DCLGEN output to work in your specific case. For example, DCLGEN is unable to determine
whether a column that is defined as NOT NULL also contains the DEFAULT clause, so you must edit the
DCLGEN output to add the DEFAULT clause to the appropriate column definitions.
DCLGEN produces declarations based on the encoding scheme of the source table. Therefore, if your
application uses a different encoding scheme, you might need to manually adjust the declarations.
For example, if your source table is in EBCDIC with CHAR columns and your application is in COBOL,
DCLGEN produces declarations of type PIC X. However, suppose your host variables in your COBOL
application are UTF-16. In this case, you will need to manually change the declarations to be type PIC
N USAGE NATIONAL.
Related reference
DCLGEN (DECLARATIONS GENERATOR) (DSN) (Db2 Commands)
DSN (TSO) (Db2 Commands)
Reserved words (Db2 SQL)
Procedure
To generate table and view declarations by using DCLGEN from DB2I:
1. From the DB2I Primary Option Menu panel, select the DCLGEN option.
The following DCLGEN panel is displayed:
'DON''S TABLE'
The underscore is not handled as a special character in DCLGEN. For example, the table name
JUNE_PROFITS does not need to be enclosed in apostrophes. Because COBOL field names cannot
contain underscores, DCLGEN substitutes hyphens (-) for single-byte underscores in COBOL field
names that are built from the table name.
You do not need to enclose DBCS table names in apostrophes.
If you do not enclose the table name in apostrophes, Db2 converts lowercase characters to
uppercase.
2 TABLE OWNER
Is the schema qualifier of the source table. If you do not specify this value and the table is a local
table, Db2 assumes that the table qualifier is your TSO logon ID. If the table is at a remote location,
you must specify this value.
3 AT LOCATION
Is the location of a table or view at another Db2 subsystem. The value of the AT LOCATION field
becomes a prefix for the table name on the SQL DECLARE statement, as follows: location_name,
schema_name, table_name For example, if the location name is PLAINS_GA, the schema name is
CARTER, and the table name is CROP_YIELD_89, the following table name is included in the SQL
DECLARE statement: PLAINS_GA.CARTER.CROP_YIELD_89
The default is the local location name. This field applies to Db2 private protocol access only. The
location must be another Db2 for z/OS subsystem.
462 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
4 DATA SET NAME
Is the name of the data set that you allocated to contain the declarations that DCLGEN produces.
You must supply a name; no default exists.
The data set must already exist and be accessible to DCLGEN. The data set can be either
sequential or partitioned. If you do not enclose the data set name in apostrophes, DCLGEN adds
a standard TSO prefix (user ID) and suffix (language). DCLGEN determines the host language from
the DB2I defaults panel.
For example, for library name LIBNAME(MEMBNAME), the name becomes
userid.libname.language(membname) For library name LIBNAME, the name becomes
userid.libname.language.
If this data set is password protected, you must supply the password in the DATA SET PASSWORD
field.
5 DATA SET PASSWORD
Is the password for the data set that is specified in the DATA SET NAME field, if the data set is
password protected. The password is not displayed on your terminal, and it is not recognized if you
issued it from a previous session.
6 ACTION
Specifies what DCLGEN is to do with the output when it is sent to a partitioned data set. (The
option is ignored if the data set you specify in the DATA SET NAME field is sequential.) You can
specify one of the following values:
ADD
Indicates that an old version of the output does not exist and creates a new member with the
specified data set name. ADD is the default.
REPLACE
Replaces an old version, if it already exists. If the member does not exist, this option creates a
new member.
7 COLUMN LABEL
Specifies whether DCLGEN is to include labels that are declared on any columns of the table or
view as comments in the data declarations. (The SQL LABEL statement creates column labels to
use as supplements to column names.) You can specify one of the following values:
YES
Include column labels.
NO
Ignore column labels. NO is the default.
8 STRUCTURE NAME
Is the name of the generated data structure. The name can be up to 31 characters. If the name
is not a DBCS string, and the first character is not alphabetic, enclose the name in apostrophes. If
you use special characters, be careful to avoid name conflicts.
If you leave this field blank, DCLGEN generates a name that contains the table or view name with
a prefix of DCL. If the language is COBOL or PL/I and the table or view name consists of a DBCS
string, the prefix consists of DBCS characters.
For C, lowercase characters that you enter in this field are not converted to uppercase.
9 FIELD NAME PREFIX
Specifies a prefix that DCLGEN uses to form field names in the output. For example, if you choose
ABCDE, the field names generated are ABCDE1, ABCDE2, and so on.
You can specify a field name prefix of up to 28 bytes that can include special and double-byte
characters. If you specify a single-byte or mixed-string prefix and the first character is not
alphabetic, enclose the prefix in apostrophes. If you use special characters, be careful to avoid
name conflicts.
If you request an array of indicator variables for a COBOL program, DCLGEN might generate the
following host variable declaration:
01 DCLHASNULLS.
10 CHARCOL1 PIC X(1).
10 CHARCOL2 PIC X(1).
01 IHASNULLS PIC S9(4) USAGE COMP-5 OCCURS 2 TIMES.
464 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
NO
Specifies that DCLGEN is not to generate an array of indicator variables. The default is NO.
13 ADDITIONAL OPTIONS
Indicates whether to display the panel for additional DCLGEN options, including the break point
for statement tokens and whether to generate DECLARE VARIABLE statements for FOR BIT DATA
columns. You can specify YES or NO. The default is YES.
If you specified YES in the ADDITIONAL OPTIONS field, the following ADDITIONAL DCLGEN OPTIONS
panel is displayed:
2 FOR BIT DATA .... ===> NO (Enter YES to declare SQL variables for
FOR BIT DATA columns)
466 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 82. Type declarations that DCLGEN generates (continued)
SQL data type1 C COBOL PL/I
DBCLOB(n)3 SQL TYPE IS USAGE SQL TYPE IS SQL TYPE IS
DBCLOB_LOCATOR DBCLOB-LOCATOR DBCLOB_LOCATOR
BINARY(n) SQL TYPE IS USAGE SQL TYPE IS SQL TYPE IS
BINARY(n) BINARY(n) BINARY(n)
VARBINARY(n) SQL TYPE IS USAGE SQL TYPE IS SQL TYPE IS
VARBINARY(n) VARBINARY(n) VARBINARY(n)
BLOB(n)3 SQL TYPE IS USAGE SQL TYPE IS SQL TYPE IS
BLOB_LOCATOR BLOB-LOCATOR BLOB_LOCATOR
DATE char var[11]5 PIC X(10)5 CHAR(10)5
TIME char var[9]6 PIC X(8)6 CHAR(8)6
TIMESTAMP char var[27] PIC X(26) CHAR(26)
TIMESTAMP(0) char var[20] PIC X(19) CHAR(19)
TIMESTAMP(p) p > 0 char var[21+p] PIC X(20+p) CHAR(20+p)
TIMESTAMP(0) WITH DCL var CHAR(147)
struct 01 var.
TIME ZONE {short int var_len; 49 var_LEN VAR;
char var_data[147]; PIC S9(4)
} var; COMP-5.
49 var_TEXT
PIC X(147).
ROWID SQL TYPE IS ROWID USAGE SQL TYPE IS SQL TYPE IS ROWID
ROWID
XML7 SQL TYPE IS XML AS SQL TYPE IS XML AS SQL TYPE IS XML AS
CLOB(1M) CLOB(1M) CLOB(1M)
Notes:
1. For a distinct type, DCLGEN generates the host language equivalent of the source data type.
2. If your C compiler does not support the decimal data type, edit your DCLGEN output and replace the
decimal data declarations with declarations of type double.
3. For a BLOB, CLOB, or DBCLOB data type, DCLGEN generates a LOB locator.
4. DCLGEN chooses the format based on the character that you specify as the DBCS symbol on the COBOL
Defaults panel.
5. This declaration is used unless a date installation exit routine exists for formatting dates, in which case the
length is that specified for the LOCAL DATE LENGTH installation option.
6. This declaration is used unless a time installation exit routine exists for formatting times, in which case the
length is that specified for the LOCAL TIME LENGTH installation option.
7. The default setting for XML is 1M; however, you might need to adjust it.
Procedure
Code the following SQL INCLUDE statement in your program:
EXEC SQL
INCLUDE member-name
END-EXEC.
member-name is the name of the data set member where the DCLGEN output is stored.
Example
Suppose that you used DCLGEN to generate a table declaration and corresponding COBOL record
description for the table DSN8C10.EMP, and those declarations were stored in the data set member
DECEMP. (A COBOL record description is a two-level host structure that corresponds to the columns of
a table's row. ) To include those declarations in your program, include the following statement in your
COBOL program:
EXEC SQL
INCLUDE DECEMP
END-EXEC.
Related reference
INCLUDE (Db2 SQL)
468 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
DSNEOP01 DB2I DEFAULTS PANEL 1
COMMAND ===>_
Figure 27. DCLGEN panel—selecting source table and destination data set
A successful completion message, such as the one in the following figure, is displayed at the top of
your screen.
Db2 again displays the DCLGEN screen, as shown in the following figure.
470 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
For this example, the data set to edit is prefix.TEMP.COBOL(VPHONEC). This data set member contains
the following information.
You can now pull these declarations into your program by using an SQL INCLUDE statement.
Defining the items that your program can use to check whether an
SQL statement executed successfully
If your program contains SQL statements, the program should define some infrastructure so that it can
check whether the statements executed successfully. You can either include an SQL communications
area (SQLCA), which contains SQLCODE and SQLSTATE variables, or declare individual SQLCODE and
SQLSTATE host variables.
Procedure
Take the actions that are appropriate for the programming language that you use:
• “Defining SQL descriptor areas (SQLDA) in assembler” on page 553
• “Defining SQL descriptor areas (SQLDA) in C and C++” on page 580
472 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
• “Defining SQL descriptor areas (SQLDA) in COBOL” on page 647
• “Defining SQL descriptor areas in (SQLDA) Fortran” on page 686
• “Defining SQL descriptor areas (SQLDA) in PL/I” on page 703
• “Defining SQL descriptor areas (SQLDA) in REXX” on page 742
Related reference
SQL descriptor area (SQLDA) (Db2 SQL)
Descriptions of SQL processing options
You can specify any SQL processing options regardless of whether you use the Db2 precompiler or the
Db2 coprocessor. However, the Db2 coprocessor might ignore certain options because host language
compiler options exist that provide the same information.
Description of SQLCA fields (Db2 SQL)
The REXX SQLCA (Db2 SQL)
Procedure
Use the techniques that are appropriate for the programming language that you use.
Related tasks
Accessing data by using a rowset-positioned cursor
A rowset-positioned cursor is a cursor that can return one or more rows for a single fetch operation. The
cursor is positioned on the set of rows that are to be fetched.
Determining whether a retrieved value in a host variable is null or truncated
Before your application manipulates the data that was retrieved from Db2 into a host variable, determine
if the value is null. Also determine if it was truncated when assigned to the variable. You can use indicator
variables to obtain this information.
Related reference
Descriptions of SQL processing options
You can specify any SQL processing options regardless of whether you use the Db2 precompiler or the
Db2 coprocessor. However, the Db2 coprocessor might ignore certain options because host language
compiler options exist that provide the same information.
Host variables
Use host variables to pass a single data item between Db2 and your application.
A host variable is a single data item that is declared in the host language to be used within an SQL
statement. You can use host variables in application programs that are written in the following languages:
assembler, C, C++, COBOL, Fortran, and PL/I to perform the following actions:
• Retrieve data into the host variable for your application program's use
• Place data into the host variable to insert into a table or to change the contents of a row
• Use the data in the host variable when evaluating a WHERE or HAVING clause
• Assign the value that is in the host variable to a special register, such as CURRENT SQLID and CURRENT
DEGREE
• Insert null values into columns by using a host indicator variable that contains a negative value
• Use the data in the host variable in statements that process dynamic SQL, such as EXECUTE, PREPARE,
and OPEN
Host-variable arrays
You can use host-variable arrays to pass a data array between Db2 and your application. A host-variable
array is a data array that is declared in the host language to be used within an SQL statement.
You can use host-variable arrays for the following actions:
• Retrieve data into host-variable arrays for your application use by your application
• Place data into host-variable arrays to insert rows into a table
• Retrieve data for the source of a merge operation.
Host-variable arrays can be referenced only as a simple reference in the following contexts. In syntax
diagrams, host-variable-array designates a reference to a host-variable array.
• In a FETCH statement for a multiple-row fetch. See FETCH (Db2 SQL).
• In an INSERT statement with multiple rows of source data. This is also referred to as multiple-row
insert. See INSERT (Db2 SQL).
• In a MERGE statement with multiple rows of source data. See MERGE (Db2 SQL).
• In an EXECUTE statement to provide a value for a parameter marker in a dynamic multi-row INSERT or
MERGE. See EXECUTE (Db2 SQL).
Host-variable arrays are defined by statements of the host language, as explained in the following topics:
• “Host-variable arrays in C and C++” on page 592
• “Host-variable arrays in COBOL” on page 658
• “Host-variable arrays in PL/I” on page 710
Tip: Host-variable arrays are not supported for assembler, FORTRAN, or REXX programs. However,
you can use SQL descriptor areas (SQLDA) to achieve similar results in any host language. For more
information see “Defining SQL descriptor areas (SQLDA)” on page 472.
474 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Example
GUPI
The following statement uses the main host-variable array, COL1, and the corresponding indicator array,
COL1IND. Assume that COL1 has 10 elements. The first element in the array corresponds to the first
value, and so on. COL1IND must have at least 10 entries.
EXEC SQL
SQL FETCH FIRST ROWSET FROM C1 FOR 5 ROWS
INTO :COL1 :COL1IND
END-EXEC.
GUPI
Related concepts
Host-variable arrays in PL/I, C, C++, and COBOL (Db2 SQL)
Using host-variable arrays in SQL statements
Use host-variable arrays in embedded SQL statements to represent values that the program does not
know until the query is executed. Host-variable arrays are useful for storing a set of retrieved values or for
passing a set of values that are to be inserted into a table.
Related tasks
Inserting multiple rows of data from host-variable arrays
Use host-variable arrays in your INSERT statement when you do not know at least some of the values to
insert until the program runs.
Retrieving multiple rows of data into host-variable arrays
If you know that your query returns multiple rows, you can specify host-variable arrays to store the
retrieved column values.
Related reference
Host-variable arrays in C and C++
In C and C++ programs, you can specify numeric, character, graphic, binary, LOB, XML, and ROWID
host-variable arrays. You can also specify LOB locators and LOB and XML file reference variables.
Host-variable arrays in COBOL
In COBOL programs, you can specify numeric, character, graphic, LOB, XML, and ROWID host-variable
arrays. You can also specify LOB locators and LOB and XML file reference variables.
Host-variable arrays in PL/I
In PL/I programs, you can specify numeric, character, graphic, binary, LOB, XML, and ROWID host-
variable arrays. You can also specify LOB locators and LOB and XML file reference variables.
Host structures
Use host structures to pass a group of host variables between Db2 and your application.
A host structure is a group of host variables that can be referenced with a single name. You can use
host structures in all host languages except REXX. You define host structures with statements in the host
language. You can refer to a host structure in any context where you want to refer to the list of host
variables in the structure. A host structure reference is equivalent to a reference to each of the host
variables within the structure in the order in which they are defined in the structure declaration. You can
also use indicator variables (or indicator structures) with host structures.
Related tasks
Retrieving a single row of data into a host structure
If you know that your query returns multiple column values for only one row, you can specify a host
structure to contain the column values.
Related reference
Host structures in C and C++
A C host structure contains an ordered group of data fields.
Host structures in COBOL
476 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
positive integer
The seconds portion of a time if the time is truncated on assignment to a host variable.
On input to Db2, normal indicator variables or extended indicator variables can contain the following
values:
0, or positive integer
Specifies a non-null value. A 0 (zero), or positive value of the indicator variable specifies that the first
host-identifier provides the value of this host variable reference.
-1, -2, -3, -4, -6
Specifies a null value.
-5
• If extended indicator variables are not enabled, a -5 value specifies the NULL value.
• If extended indicator variables are enabled, a -5 value specifies the DEFAULT value. A -5 value
specifies that the target column for this host variable is to be set to its DEFAULT value.
-7
• If extended indicator variables are not enabled, a -7 value specifies the NULL value.
• If extended indicator variables are enabled, a -7 value specifies the UNASSIGNED value. A -7 value
specifies that the target column for this host variable is to be treated as if it had not been specified
in the statement.
An indicator structure is an array of halfword integer variables that supports a specified host structure.
If the column values that your program retrieves into a host structure can be null, you can attach an
indicator structure name to the host structure name. This name enables Db2 to notify your program about
each null value it returns to a host variable in the host structure.
Related concepts
Holes in the result table of a scrollable cursor
A hole in the result table means that the result table does not shrink to fill the space of deleted rows.
It also does not shrink to fill the space of rows that have been updated and no longer satisfy the
search condition. You cannot access a delete or update hole. However, you can remove holes in specific
situations.
Related tasks
Executing SQL statements by using a rowset cursor
You can use rowset cursors to execute multiple-row FETCH statements, positioned UPDATE statements,
and positioned DELETE statements.
Related reference
Indicator variables in assembler
An indicator variable is a 2-byte integer (DS HL2). You declare indicator variables in the same way as host
variables. You can mix the declarations of the two types of variables.
Indicator variables, indicator arrays, and host structure indicator arrays in C and C++
An indicator variable is a 2-byte integer (short int). An indicator variable array is an array of 2-byte
integers (short int). You declare indicator variables in the same way as host variables. You can mix the
declarations of the two types of variables.
Indicator variables, indicator arrays, and host structure indicator arrays in COBOL
A COBOL indicator variable is a 2-byte binary integer. A COBOL indicator variable array is an array in which
each element is declared as a 2-byte binary integer. You can use indicator variable arrays to support
COBOL host structures.
Indicator variables in Fortran
An indicator variable is a 2-byte integer (INTEGER*2). You declare indicator variables in the same way as
host variables. You can mix the declarations of the two types of variables.
Indicator variables in PL/I
Procedure
Specify the DECLARE VARIABLE statement after the corresponding host variable declaration and before
your first reference to that host variable.
This statement associates an encoding scheme and a CCSID with individual host variables. You can use
this statement in static or dynamic SQL applications.
Restriction: You cannot use the DECLARE VARIABLE statement to control the CCSID and encoding
scheme of data that you retrieve or update by using an SQLDA.
The DECLARE VARIABLE statement has the following effects on a host variable:
• When you use the host variable to update a table, the local subsystem or the remote server assumes
that the data in the host variable is encoded with the CCSID and encoding scheme that the DECLARE
VARIABLE statement assigns.
• When you retrieve data from a local or remote table into the host variable, the retrieved data is
converted to the CCSID and encoding scheme that are assigned by the DECLARE VARIABLE statement.
Example
Suppose that you are writing a C program that runs on a Db2 for z/OS subsystem. The subsystem has an
EBCDIC application encoding scheme. The C program retrieves data from the following columns of a local
table that is defined with the CCSID UNICODE option:
PARTNUM CHAR(10)
JPNNAME GRAPHIC(10)
ENGNAME VARCHAR(30)
Because the application encoding scheme for the subsystem is EBCDIC, the retrieved data is EBCDIC.
To make the retrieved data Unicode, use DECLARE VARIABLE statements to specify that the data that is
retrieved from these columns is encoded in the default Unicode CCSIDs for the subsystem.
Suppose that you want to retrieve the character data in Unicode CCSID 1208 and the graphic data in
Unicode CCSID 1200. Use the following DECLARE VARIABLE statements:
Related reference
DECLARE VARIABLE (Db2 SQL)
478 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Determining what caused an error when retrieving data into a host variable
Errors that occur when Db2 passes data to host variables in an application are usually caused by a
problem in converting from one data type to another. These errors do not affect the position of the cursor.
Procedure
To determine what caused an error when retrieving data into a host variable:
1. When Db2 returns SQLCODE = +354, use the GET DIAGNOSTICS statement with the NUMBER option
to determine the number of errors and warnings.
For example, suppose that no indicator variables are provided for the values that are returned by the
following statement:
For each row with an error, Db2 records a negative SQLCODE and continues processing until the
10 rows are fetched. When SQLCODE = +354 is returned for the statement, you can use the GET
DIAGNOSTICS statement to determine which errors occurred for which rows. The following statement
returns num_rows = 10 and num_cond = 3:
2. To investigate the errors and warnings, use additional GET DIAGNOSTIC statements with the
CONDITION option.
For example, to investigate the three conditions that were reported in the example in the previous
step, use the following statements:
480 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Fortran
A CHAR, VARCHAR, or CLOB column is compatible with Fortran character host variable.
PL/I
A CHAR, VARCHAR, or CLOB column is compatible with a fixed-length or varying-length PL/I
character host variable.
• Character data types are partially compatible with CLOB locators. You can perform the following
assignments:
– Assign a value in a CLOB locator to a CHAR or VARCHAR column
– Use a SELECT INTO statement to assign a CHAR or VARCHAR column to a CLOB locator host variable.
– Assign a CHAR or VARCHAR output parameter from a user-defined function or stored procedure to a
CLOB locator host variable.
– Use a SET assignment statement to assign a CHAR or VARCHAR transition variable to a CLOB locator
host variable.
– Use a VALUES INTO statement to assign a CHAR or VARCHAR function parameter to a CLOB locator
host variable.
However, you cannot use a FETCH statement to assign a value in a CHAR or VARCHAR column to a CLOB
locator host variable.
• Graphic data types are compatible with each other:
Assembler
A GRAPHIC, VARGRAPHIC, or DBCLOB column is compatible with a fixed-length or varying-length
assembler graphic character host variable.
C/C++
A GRAPHIC, VARGRAPHIC, or DBCLOB column is compatible with a single character, NUL-
terminated, or VARGRAPHIC structured form of a C graphic host variable.
COBOL
A GRAPHIC, VARGRAPHIC, or DBCLOB column is compatible with a fixed-length or varying-length
COBOL graphic string host variable.
PL/I
A GRAPHIC, VARGRAPHIC, or DBCLOB column is compatible with a fixed-length or varying-length
PL/I graphic character host variable.
• Graphic data types are partially compatible with DBCLOB locators. You can perform the following
assignments:
– Assign a value in a DBCLOB locator to a GRAPHIC or VARGRAPHIC column
– Use a SELECT INTO statement to assign a GRAPHIC or VARGRAPHIC column to a DBCLOB locator
host variable.
– Assign a GRAPHIC or VARGRAPHIC output parameter from a user-defined function or stored
procedure to a DBCLOB locator host variable.
– Use a SET assignment statement to assign a GRAPHIC or VARGRAPHIC transition variable to a
DBCLOB locator host variable.
– Use a VALUES INTO statement to assign a GRAPHIC or VARGRAPHIC function parameter to a
DBCLOB locator host variable.
However, you cannot use a FETCH statement to assign a value in a GRAPHIC or VARGRAPHIC column to
a DBCLOB locator host variable.
• Binary data types are compatible with each other.
• Binary data types are partially compatible with BLOB locators. You can perform the following
assignments:
– Assign a value in a BLOB locator to a BINARY or VARBINARY column.
– Use a SELECT INTO statement to assign a BINARY or VARBINARY column to a BLOB locator host
variable.
482 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
When you declare host variables in your assembler programs, the precompiler uses equivalent SQL data
types. When you retrieve data of a particular SQL data type into a host variable, ensure that the host
variable is of an equivalent data type.
Equivalent SQL and C data types
When you declare host variables in your C programs, the precompiler uses equivalent SQL data types.
When you retrieve data of a particular SQL data type into a host variable, you need to ensure that the host
variable is of an equivalent data type.
Equivalent SQL and COBOL data types
When you declare host variables in your COBOL programs, the precompiler uses equivalent SQL data
types. When you retrieve data of a particular SQL data type into a host variable, you need to ensure that
the host variable is of an equivalent data type.
Equivalent SQL and Fortran data types
When you declare host variables in your Fortran programs, the precompiler uses equivalent SQL data
types. When you retrieve data of a particular SQL data type into a host variable, ensure that the host
variable is of an equivalent data type.
Equivalent SQL and PL/I data types
When you declare host variables in your PL/I programs, the precompiler uses equivalent SQL data types.
When you retrieve data of a particular SQL data type into a host variable, you need to ensure that the host
variable is of an equivalent data type.
Equivalent SQL and REXX data types
All REXX data is string data. Therefore, when a REXX program assigns input data to a column, Db2
converts the data from a string type to the column type. When a REXX program assigns column data to an
output variable, Db2 converts the data from the column type to a string type.
Procedure
In the SELECT statement specify the INTO clause with the name of one or more host variables to contain
the retrieved values. Specify one variable for each value that is to be retrieved. The retrieved value can
be a column value, a value of a host variable, the result of an expression, or the result of an aggregate
function.
Recommendation: If you want to ensure that only one row is returned, specify the FETCH FIRST 1 ROW
ONLY clause. Consider using the ORDER BY clause to control which row is returned. If you specify both
the ORDER BY clause and the FETCH FIRST clause, ordering is performed on the entire result set before
the first row is returned.
Db2 assigns the first value in the result row to the first variable in the list, the second value to the second
variable, and so on.
If the SELECT statement returns more than one row, Db2 returns an error, and any data that is returned is
undefined and unpredictable.
Examples
Example: Retrieving a single row into a host variable
Suppose that you are retrieving the LASTNAME and WORKDEPT column values from the
DSN8C10.EMP table for a particular employee. You can define a host variable in your program to hold
each column value and then name the host variables in the INTO clause of the SELECT statement, as
shown in the following COBOL example.
In this example, the host variable CBLEMPNO is preceded by a colon (:) in the SQL statement, but it is
not preceded by a colon in the COBOL MOVE statement.
This example also uses a host variable to specify a value in a search condition. The host variable
CBLEMPNO is defined for the employee number, so that you can retrieve the name and the work
department of the employee whose number is the same as the value of the host variable, CBLEMPNO;
in this case, 000110.
In the DATA DIVISION section of a COBOL program, you must declare the host variables CBLEMPNO,
CBLNAME, and CBLDEPT to be compatible with the data types in the columns EMPNO, LASTNAME,
and WORKDEPT of the DSN8C10.EMP table.
484 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Example: Ensuring that a query returns only a single row
You can use the FETCH FIRST 1 ROW ONLY clause in a SELECT statement to ensure that only one
row is returned. This action prevents undefined and unpredictable data from being returned when you
specify the INTO clause of the SELECT statement. The following example SELECT statement ensures
that only one row of the DSN8C10.EMP table is returned.
EXEC SQL
SELECT LASTNAME, WORKDEPT
INTO :CBLNAME, :CBLDEPT
FROM DSN8C10.EMP
FETCH FIRST 1 ROW ONLY
END-EXEC.
You can include an ORDER BY clause in the preceding example to control which row is returned. The
following example SELECT statement ensures that the only row returned is the one with a last name
that is first alphabetically.
EXEC SQL
SELECT LASTNAME, WORKDEPT
INTO :CBLNAME, :CBLDEPT
FROM DSN8810.EMP
ORDER BY LASTNAME
FETCH FIRST 1 ROW ONLY
END-EXEC.
Example: Retrieving the results of host variable values and expressions into host variables
When you specify a list of items in the SELECT clause, that list can include more than the column
names of tables and views. You can request a set of column values mixed with host variable values
and constants. For example, the following query requests the values of several columns (EMPNO,
LASTNAME, and SALARY), the value of a host variable (RAISE), and the value of the sum of a column
and a host variable (SALARY and RAISE). For each of these five items in the SELECT list, a host
variable is listed in the INTO clause.
The preceding SELECT statement returns the following results. The column headings represent the
names of the host variables.
Related tasks
Retrieving a set of rows by using a cursor
Procedure
Determine the value of the indicator variable, array, or structure that is associated with the host variable,
array, or structure.
Those values have the following meanings:
Examples
Example of testing an indicator variable
Assume that you have defined the following indicator variable INDNULL for the host variable
CBLPHONE.
EXEC SQL
SELECT PHONENO
INTO :CBLPHONE:INDNULL
FROM DSN8C10.EMP
WHERE EMPNO = :EMPID
END-EXEC.
You can then test INDNULL for a negative value. If the value is negative, the corresponding value of
PHONENO is null, and you can disregard the contents of CBLPHONE.
486 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Example of testing an indicator variable array
Suppose that you declare the following indicator array INDNULL for the host-variable array
CBLPHONE.
EXEC SQL
FETCH NEXT ROWSET CURS1
FOR 10 ROWS
INTO :CBLPHONE :INDNULL
END-EXEC.
After the multiple-row FETCH statement, you can test each element of the INDNULL array for a
negative value. If an element is negative, you can disregard the contents of the corresponding
element in the CBLPHONE host-variable array.
Example of testing an indicator structure in COBOL
The following example defines the indicator structure EMP-IND as an array that contains six values
and corresponds to the PEMP-ROW host structure.
01 PEMP-ROW.
10 EMPNO PIC X(6).
10 FIRSTNME.
49 FIRSTNME-LEN PIC S9(4) USAGE COMP.
49 FIRSTNME-TEXT PIC X(12).
10 MIDINIT PIC X(1).
10 LASTNAME.
49 LASTNAME-LEN PIC S9(4) USAGE COMP.
49 LASTNAME-TEXT PIC X(15).
10 WORKDEPT PIC X(3).
10 EMP-BIRTHDATE PIC X(10).
01 INDICATOR-TABLE.
02 EMP-IND PIC S9(4) COMP OCCURS 6 TIMES.
⋮
MOVE '000230' TO EMPNO.
⋮
EXEC SQL
SELECT EMPNO, FIRSTNME, MIDINIT, LASTNAME, WORKDEPT, BIRTHDATE
INTO :PEMP-ROW:EMP-IND
FROM DSN8C10.EMP
WHERE EMPNO = :EMPNO
END-EXEC.
You can test the indicator structure EMP-IND for negative values. If, for example, EMP-IND(6)
contains a negative value, the corresponding host variable in the host structure (EMP-BIRTHDATE)
contains a null value.
Related concepts
Arithmetic and conversion errors
You can track arithmetic and conversion errors by using indicator variables. An indicator variable contains
a small integer value that indicates some information about the associated host variable.
Related tasks
Declaring host variables and indicator variables
You can use host variables and indicator variables in SQL statements in your program to pass data
between Db2 and your application.
Procedure
To update data by using host variables:
1. Declare the necessary host variables.
2. Specify an UPDATE statement with the appropriate host variable names in the SET clause.
Related reference
UPDATE (Db2 SQL)
Procedure
Specify an INSERT statement with column values in the VALUES clause. Specify host variables or a
combination of host variables and constants as the column values.
Db2 inserts the first value into the first column in the list, the second value into the second column, and so
on.
Example
The following example uses host variables to insert a single row into the activity table.
EXEC SQL
INSERT INTO DSN8C10.ACT
VALUES (:HV-ACTNO, :HV-ACTKWD, :HV-ACTDESC)
END-EXEC.
Related tasks
Inserting multiple rows of data from host-variable arrays
Use host-variable arrays in your INSERT statement when you do not know at least some of the values to
insert until the program runs.
Related reference
INSERT (Db2 SQL)
488 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Using host-variable arrays in SQL statements
Use host-variable arrays in embedded SQL statements to represent values that the program does not
know until the query is executed. Host-variable arrays are useful for storing a set of retrieved values or for
passing a set of values that are to be inserted into a table.
To use a host-variable array in an SQL statement, specify any valid host-variable array that is declared
according to the host language rules. You can specify host-variable arrays in C or C++, COBOL, and PL/I.
You must declare the array in the host program before you use it.
Host-variable arrays are defined by statements of the host language, as explained in the following topics:
• “Host-variable arrays in C and C++” on page 592
• “Host-variable arrays in COBOL” on page 658
• “Host-variable arrays in PL/I” on page 710
Tip: Host-variable arrays are not supported for assembler, FORTRAN, or REXX programs. However,
you can use SQL descriptor areas (SQLDA) to achieve similar results in any host language. For more
information see “Defining SQL descriptor areas (SQLDA)” on page 472.
Host-variable arrays can be referenced only as a simple reference in the following contexts. In syntax
diagrams, host-variable-array designates a reference to a host-variable array.
• In a FETCH statement for a multiple-row fetch. See FETCH (Db2 SQL).
• In an INSERT statement with multiple rows of source data. This is also referred to as multiple-row
insert. See INSERT (Db2 SQL).
• In a MERGE statement with multiple rows of source data. See MERGE (Db2 SQL).
• In an EXECUTE statement to provide a value for a parameter marker in a dynamic multi-row INSERT or
MERGE. See EXECUTE (Db2 SQL).
Related concepts
Host-variable arrays in PL/I, C, C++, and COBOL (Db2 SQL)
Host-variable arrays
You can use host-variable arrays to pass a data array between Db2 and your application. A host-variable
array is a data array that is declared in the host language to be used within an SQL statement.
Related tasks
Inserting multiple rows of data from host-variable arrays
Use host-variable arrays in your INSERT statement when you do not know at least some of the values to
insert until the program runs.
Retrieving multiple rows of data into host-variable arrays
If you know that your query returns multiple rows, you can specify host-variable arrays to store the
retrieved column values.
Example
You can insert the number of rows that are specified in the host variable NUM-ROWS by using the
following INSERT statement:
EXEC SQL
INSERT INTO DSN8C10.ACT
(ACTNO, ACTKWD, ACTDESC)
VALUES (:HVA1, :HVA2, :HVA3)
FOR :NUM-ROWS ROWS
END-EXEC.
Assume that the host-variable arrays HVA1, HVA2, and HVA3 have been declared and populated with the
values that are to be inserted into the ACTNO, ACTKWD, and ACTDESC columns. The NUM-ROWS host
variable specifies the number of rows that are to be inserted, which must be less than or equal to the
dimension of each host-variable array.
Related concepts
Host-variable arrays in PL/I, C, C++, and COBOL (Db2 SQL)
Related tasks
Retrieving multiple rows of data into host-variable arrays
If you know that your query returns multiple rows, you can specify host-variable arrays to store the
retrieved column values.
Related reference
INSERT (Db2 SQL)
MERGE (Db2 SQL)
490 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Inserting null values into columns by using indicator variables or
arrays
If you need to insert null values into a column, using an indicator variable or array is an easy way to do so.
An indicator variable or array is associated with a particular host variable or host-variable array.
Procedure
To insert null values into columns by using indicator variables or arrays:
1. Define an indicator variable or array for a particular host variable or array.
2. Assign a negative value to the indicator variable or array.
3. Issue the appropriate INSERT, UPDATE, or MERGE statement with the host variable or array and its
indicator variable or array.
When Db2 processes INSERT, UPDATE, and MERGE statements, it checks the indicator variable if one
exists. If the indicator variable is negative, the column value is null. If the indicator variable is greater
than -1, the associated host variable contains a value for the column.
Examples
Example of setting a column value to null by using an indicator variable
Suppose your program reads an employee ID and a new phone number and must update the
employee table with the new number. The new number could be missing if the old number is
incorrect, but a new number is not yet available. If the new value for column PHONENO might be
null, you can use an indicator variable, as shown in the following UPDATE statement.
EXEC SQL
UPDATE DSN8C10.EMP
SET PHONENO = :NEWPHONE:PHONEIND
WHERE EMPNO = :EMPID
END-EXEC.
When NEWPHONE contains a non-null value, set the indicator variable PHONEIND to zero by
preceding the UPDATE statement with the following line:
MOVE 0 TO PHONEIND.
When NEWPHONE contains a null value, set PHONEIND to a negative value by preceding the UPDATE
statement with the following line:
MOVE -1 TO PHONEIND.
EXEC SQL
INSERT INTO DSN8C10.ACT
(ACTNO, ACTKWD, ACTDESC)
VALUES (:hva1:ind1, :hva2:ind2, :hva3:ind3)
FOR 10 ROWS;
Db2 ignores the values in the hva3 array and assigns the values in the ARTDESC column to null for the
10 rows that are inserted.
EXEC SQL
SELECT EMPNO, FIRSTNME, MIDINIT, LASTNAME, WORKDEPT
INTO :EMPNO, :FIRSTNME, :MIDINIT, :LASTNAME, :WORKDEPT
FROM DSN8C10.VEMP
WHERE EMPNO = :EMPID
END-EXEC.
If you want to avoid listing host variables, you can substitute the name of a structure, say :PEMP, that
contains :EMPNO, :FIRSTNME, :MIDINIT, :LASTNAME, and :WORKDEPT. The example then reads:
EXEC SQL
SELECT EMPNO, FIRSTNME, MIDINIT, LASTNAME, WORKDEPT
INTO :PEMP
FROM DSN8C10.VEMP
WHERE EMPNO = :EMPID
END-EXEC.
You can declare a host structure yourself, or you can use DCLGEN to generate a COBOL record
description, PL/I structure declaration, or C structure declaration that corresponds to the columns of
a table.
Related concepts
DCLGEN (declarations generator)
Your program should declare the tables and views that it accesses. The Db2 declarations generator,
DCLGEN, produces these DECLARE statements for C, COBOL, and PL/I programs, so that you do not need
to code the statements yourself. DCLGEN also generates corresponding host variable structures.
Host structures
Use host structures to pass a group of host variables between Db2 and your application.
Example: Adding DCLGEN declarations to a library
You can use DCLGEN to generate table and variable declarations for C, COBOL, and PL/I programs. If you
store these declarations in a library, you can later integrate them into your program with a single SQL
INCLUDE statement.
492 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
About this task
Introductory concepts
Submitting SQL statements to Db2 (Introduction to Db2 for z/OS)
Dynamic SQL applications (Introduction to Db2 for z/OS)
Dynamic SQL prepares and executes the SQL statements within a program, while the program is running.
You can issue dynamic SQL statements in the following contexts:
Interactive SQL
A user enters SQL statements through SPUFI, the command line processor, or an interactive tool, such
as QMF for Workstation.Db2 prepares and executes those statements as dynamic SQL statements.
Embedded dynamic SQL
Your application puts the SQL source in host variables and includes PREPARE and EXECUTE
statements that tell Db2 to prepare and run the contents of those host variables at run time. You
must precompile and bind programs that include embedded dynamic SQL.
Deferred embedded SQL
Deferred embedded SQL statements are neither fully static nor fully dynamic. Like static statements,
deferred embedded SQL statements are embedded within applications; however, like dynamic
statements, they are prepared at run time. Db2 processes the deferred embedded SQL statements
with bind-time rules. For example, Db2 uses the authorization ID and qualifier (that are determined at
bind time) as the plan or package owner.
Dynamic SQL executed through ODBC or JDBC functions
Your application contains ODBC function calls that pass dynamic SQL statements as arguments. You
do not need to precompile and bind programs that use ODBC function calls.
JDBC application support lets you write dynamic SQL applications in Java.
For most Db2 users, static SQL, which is embedded in a host language program and bound before the
program runs, provides a straightforward, efficient path to Db2 data. You can use static SQL when you
know before run time what SQL statements your application needs to execute.
Related tasks
Setting limits for system resource usage by using the resource limit facility (Db2 Performance)
Improving dynamic SQL performance by enabling the dynamic statement cache (Db2 Performance)
Related information
Dynamic Statement Cache (white paper)
01 IOAREA.
02 EMPID PIC X(06).
02 NEW-SALARY PIC S9(7)V9(2) COMP-3.
⋮ (Other declarations)
READ CARDIN RECORD INTO IOAREA
AT END MOVE 'N' TO INPUT-SWITCH.
⋮ (Other COBOL statements)
EXEC SQL
UPDATE DSN8C10.EMP
SET SALARY = :NEW-SALARY
WHERE EMPNO = :EMPID
END-EXEC.
The statement (UPDATE) does not change, nor does its basic structure, but the input can change the
results of the UPDATE statement.
494 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
• When the SQL statement executes
The time at which Db2 determines the access path depends on these factors:
• Whether the statement is executed statically or dynamically
• Whether the statement contains input host variables
• Whether the statement contains a declared global temporary table.
496 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Possible host languages for dynamic SQL applications
Programs that use dynamic SQL are usually written in assembler, C, PL/I, REXX, and COBOL. All SQL
statements in REXX programs are considered dynamic SQL.
You can write non-SELECT and fixed-list SELECT statements in any of the Db2 supported languages. A
program containing a varying-list SELECT statement is more difficult to write in Fortran, because the
program cannot run without the help of a subroutine to manage address variables (pointers) and storage
allocation.
Most of the examples in this topic are in PL/I. Longer examples in the form of complete programs are
available in the sample applications:
DSNTEP2
Processes both SELECT and non-SELECT statements dynamically. (PL/I).
DSNTIAD
Processes only non-SELECT statements dynamically. (Assembler).
DSNTIAUL
Processes SELECT statements dynamically. (Assembler).
Library prefix.SDSNSAMP contains the sample programs. You can view the programs online, or you can
print them using ISPF, IEBPTPCH, or your own printing program.
You can use all forms of dynamic SQL in all supported versions of COBOL.
Related concepts
Sample COBOL dynamic SQL program
You can code dynamic varying-list SELECT statements in a COBOL program. Varying-List SELECT
statements are statements for which you do not know the number or data types of columns that are
to be returned when you write the program.
Procedure
Your program must take the following steps:
1. Include an SQLCA. The requirements for an SQL communications area (SQLCA) are the same as for
static SQL statements. For REXX, Db2 includes the SQLCA automatically.
2. Load the input SQL statement into a data area. The procedure for building or reading the input
SQL statement is not discussed here; the statement depends on your environment and sources of
information. You can read in complete SQL statements, or you can get information to build the
statement from data sets, a user at a terminal, previously set program variables, or tables in the
database.
If you attempt to execute an SQL statement dynamically that Db2 does not allow, you get an SQL error.
3. Execute the statement. You can use either of these methods:
• EXECUTE IMMEDIATE
• PREPARE and EXECUTE
4. Handle any errors that might result. The requirements are the same as those for static SQL
statements. The return code from the most recently executed SQL statement appears in the host
variables SQLCODE and SQLSTATE or corresponding fields of the SQLCA.
Related concepts
Sample dynamic and static SQL in a C program
The program reads the statements from a terminal, and the user determines the WHERE clause.
As with non-SELECT statements, your program puts the statements into a varying-length character
variable; call it DSTRING. Eventually you prepare a statement from DSTRING, but first you must declare a
cursor for the statement and give it a name.
498 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Procedure
To execute a fixed-list SELECT statement dynamically, your program must:
1. Include an SQLCA.
2. Load the input SQL statement into a data area.
The preceding two steps are exactly the same including dynamic SQL for non-SELECT statements in
your program.
3. Declare a cursor for the statement name.
Dynamic SELECT statements cannot use INTO. Therefore, you must use a cursor to put the results into
host variables.
For example, when you declare the cursor, use the statement name (call it STMT), and give the cursor
itself a name (for example, C1):
ATTRVAR contains attributes that you want to add to the SELECT statement, such as FETCH FIRST
10 ROWS ONLY or OPTIMIZE for 1 ROW. In general, if the SELECT statement has attributes that
conflict with the attributes in the PREPARE statement, the attributes on the SELECT statement take
precedence over the attributes on the PREPARE statement. However, in this example, the SELECT
statement in DSTRING has no attributes specified, so Db2 uses the attributes in ATTRVAR for the
SELECT statement.
As with non-SELECT statements, the fixed-list SELECT could contain parameter markers. However, this
example does not need them.
5. Open the cursor.
The OPEN statement evaluates the SELECT statement named STMT.
For example, without parameter markers, use this statement:
If STMT contains parameter markers, you must use the USING clause of OPEN to provide values for
all of the parameter markers in STMT. If four parameter markers are in STMT, you need the following
statement:
The key feature of this statement is the use of a list of host variables to receive the values returned by
FETCH. The list has a known number of items (in this case, two items, :NAME and :PHONE) of known
data types (both are character strings, of lengths 15 and 4, respectively).
You can use this list in the FETCH statement only because you planned the program to use only
fixed-list SELECTs. Every row that cursor C1 points to must contain exactly two character values of
appropriate length. If the program is to handle anything else, it must use the techniques for including
dynamic SQL for varying-list SELECT statements in your program.
7. Close the cursor.
This step is the same as for static SQL.
A WHENEVER NOT FOUND statement in your program can name a routine that contains this
statement:
8. Handle any resulting errors. This step is the same as for static SQL, except for the number and types of
errors that can result.
Related concepts
Sample dynamic and static SQL in a C program
Programs that access Db2 can contain static SQL, dynamic SQL, or both.
Assembler applications that issue SQL statements
You can code SQL statements in assembler programs wherever you can use executable statements.
C and C++ applications that issue SQL statements
You can code SQL statements in a C or C++ program wherever you can use executable statements.
COBOL applications that issue SQL statements
You can code SQL statements in certain COBOL program sections.
Fortran applications that issue SQL statements
You can code SQL statements in a Fortran program wherever you can place executable statements. If
the SQL statement is within an IF statement, the precompiler generates any necessary THEN and END IF
statements.
PL/I applications that issue SQL statements
You can code SQL statements in a PL/I program wherever you can use executable statements.
REXX applications that issue SQL statements
You can code SQL statements in a REXX programs wherever you can use REXX commands.
Related tasks
Including dynamic SQL for non-SELECT statements in your program
The easiest way to use dynamic SQL is to use non-SELECT statements. Because you do not need to
dynamically allocate any main storage, you can write your program in any host language, including
Fortran.
Including dynamic SQL for varying-list SELECT statements in your program
A varying-list SELECT statement returns rows that contain an unknown number of values of unknown
type. When you use this type of statement, you do not know in advance exactly what kinds of host
variables you need to declare for storing the results.
Procedure
To execute a varying-list SELECT statement dynamically, your program must follow these steps:
1. Include an SQLCA.
Db2 performs this step for a REXX program.
2. Load the input SQL statement into a data area.
3. Prepare and execute the statement. This step is more complex than for fixed-list SELECTs.
It involves the following steps:
500 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
a) Include an SQLDA (SQL descriptor area).
Db2 performs this step for a REXX program.
b) Declare a cursor and prepare the variable statement.
c) Obtain information about the data type of each column of the result table.
d) Determine the main storage needed to hold a row of retrieved data.
You do not perform this step for a REXX program.
e) Put storage addresses in the SQLDA to tell where to put each item of retrieved data.
f) Open the cursor.
g) Fetch a row.
h) Eventually close the cursor and free main storage.
Additional complications exist for statements with parameter markers.
4. Handle any errors that might result.
Examples
Preparing a varying-list SELECT statement
Suppose that your program dynamically executes SQL statements, but this time without any limits on
their form. Your program reads the statements from a terminal, and you know nothing about them in
advance. They might not even be SELECT statements.
As with non-SELECT statements, your program puts the statements into a varying-length character
variable; call it DSTRING. Your program goes on to prepare a statement from the variable and then
give the statement a name; call it STMT.
Now, the program must find out whether the statement is a SELECT. If it is, the program must also find
out how many values are in each row, and what their data types are. The information comes from an
SQL descriptor area (SQLDA).
SQL descriptor area (SQLDA)
The SQLDA is a structure that is used to communicate with your program, and storage for it is usually
allocated dynamically at run time.
To include the SQLDA in a PL/I or C program, use:
Table 85. Minimum number of SQLVARs for a result table with n columns
Type of DESCRIBE and contents of result table Not USING BOTH USING BOTH
No distinct types or LOBs n 2*n
Distinct types but no LOBs 2*n 3*n
LOBs but no distinct types 2*n 2*n
LOBs and distinct types 2*n 3*n
An SQLDA with n occurrences of SQLVAR is referred to as a single SQLDA, an SQLDA with 2*n
occurrences of SQLVAR a double SQLDA, an SQLDA with 3*n occurrences of SQLVAR a triple SQLDA.
A program that admits SQL statements of every kind for dynamic execution has two choices:
• Provide the largest SQLDA that it could ever need. The maximum number of columns in a result
table is 750, so an SQLDA for 750 columns occupies 33 016 bytes for a single SQLDA, 66 016 bytes
for a double SQLDA, or 99 016 bytes for a triple SQLDA. Most SELECT statements do not retrieve
750 columns, so the program does not usually use most of that space.
• Provide a smaller SQLDA, with fewer occurrences of SQLVAR. From this the program can find out
whether the statement was a SELECT and, if it was, how many columns are in its result table.
If more columns are in the result than the SQLDA can hold, Db2 returns no descriptions. When
this happens, the program must acquire storage for a second SQLDA that is long enough to hold
the column descriptions, and ask Db2 for the descriptions again. Although this technique is more
complicated to program than the first, it is more general.
How many columns should you allow? You must choose a number that is large enough for most of
your SELECT statements, but not too wasteful of space; 40 is a good compromise. To illustrate what
you must do for statements that return more columns than allowed, the example in this discussion
uses an SQLDA that is allocated for at least 100 columns.
Declaring a cursor for the statement
As before, you need a cursor for the dynamic SELECT. For example, write:
EXEC SQL
DECLARE C1 CURSOR FOR STMT;
Equivalently, you can use the INTO clause in the PREPARE statement:
EXEC SQL
PREPARE STMT INTO :MINSQLDA FROM :DSTRING;
Do not use the USING clause in either of these examples. At the moment, only the minimum SQLDA is
in use. The following figure shows the contents of the minimum SQLDA in use.
502 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
SQLN determines what SQLVAR gets
The SQLN field, which you must set before using DESCRIBE (or PREPARE INTO), tells how many
occurrences of SQLVAR the SQLDA is allocated for. If DESCRIBE needs more than that, the results of
the DESCRIBE depend on the contents of the result table. Let n indicate the number of columns in the
result table. Then:
• If the result table contains at least one distinct type column but no LOB columns, you do not specify
USING BOTH, and n<=SQLN<2*n, then Db2 returns base SQLVAR information in the first n SQLVAR
occurrences, but no distinct type information. Base SQLVAR information includes:
– Data type code
– Length attribute (except for LOBs)
– Column name or label
– Host variable address
– Indicator variable address
• Otherwise, if SQLN is less than the minimum number of SQLVARs specified in the table above, then
Db2 returns no information in the SQLVARs.
Regardless of whether your SQLDA is big enough, whenever you execute DESCRIBE, Db2 returns the
following values, which you can use to build an SQLDA of the correct size:
• SQLD is 0 if the SQL statement is not a SELECT. Otherwise, SQLD is the number of columns in the
result table. The number of SQLVAR occurrences you need for the SELECT depends on the value in
the seventh byte of SQLDAID.
• The seventh byte of SQLDAID is 2 if each column in the result table requires two SQLVAR entries.
The seventh byte of SQLDAID is 3 if each column in the result table requires three SQLVAR entries.
If the statement is not a SELECT
To find out if the statement is a SELECT, your program can query the SQLD field in MINSQLDA. If the
field contains 0, the statement is not a SELECT, the statement is already prepared, and your program
can execute it. If no parameter markers are in the statement, you can use:
(If the statement does contain parameter markers, you must use an SQL descriptor area)
Acquiring storage for a second SQLDA if needed
Now you can allocate storage for a second, full-size SQLDA; call it FULSQLDA. The following figure
shows its structure.
FULSQLDA has a fixed-length header of 16 bytes in length, followed by a varying-length section that
consists of structures with the SQLVAR format. If the result table contains LOB columns or distinct
type columns, a varying-length section that consists of structures with the SQLVAR2 format follows
the structures with SQLVAR format. All SQLVAR structures and SQLVAR2 structures are 44 bytes long.
The number of SQLVAR and SQLVAR2 elements you need is in the SQLD field of MINSQLDA, and the
total length you need for FULSQLDA (16 + SQLD * 44) is in the SQLDABC field of MINSQLDA. Allocate
that amount of storage.
Describing the SELECT statement again
After allocating sufficient space for FULSQLDA, your program must take these steps:
1. Put the total number of SQLVAR and SQLVAR2 occurrences in FULSQLDA into the SQLN field of
FULSQLDA. This number appears in the SQLD field of MINSQLDA.
2. Describe the statement again into the new SQLDA:
After the DESCRIBE statement executes, each occurrence of SQLVAR in the full-size SQLDA
(FULSQLDA in our example) contains a description of one column of the result table in five fields. If
an SQLVAR occurrence describes a LOB column or distinct type column, the corresponding SQLVAR2
occurrence contains additional information specific to the LOB or distinct type.
The following figure shows an SQLDA that describes two columns that are not LOB columns or distinct
type columns.
504 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
2. Derive the address of some storage area of the required size.
3. Put this address in the SQLDATA field.
If the SQLTYPE field indicates that the value can be null, the program must also put the address of
an indicator variable in the SQLIND field. The following figures show the SQL descriptor area after you
take certain actions.
In the previous figure, the DESCRIBE statement inserted all the values except the first occurrence
of the number 200. The program inserted the number 200 before it executed DESCRIBE to tell how
many occurrences of SQLVAR to allow. If the result table of the SELECT has more columns than this,
the SQLVAR fields describe nothing.
The first SQLVAR pertains to the first column of the result table (the WORKDEPT column). SQLVAR
element 1 contains fixed-length character strings and does not allow null values (SQLTYPE=452); the
length attribute is 3.
The following figure shows the SQLDA after your program acquires storage for the column values and
their indicators, and puts the addresses in the SQLDATA fields of the SQLDA.
SQLVAR element 1 (44 bytes) 452 3 Addr FLDA Addr FLDAI 7 WORKDEPT
SQLVAR element 2 (44 bytes) 453 4 Addr FLDB Addr FLDBI 7 PHONENO
Indicator variables
FLDA FLDB (halfword)
CHAR(3) CHAR(4) FLDAI FLDBI
Figure 33. SQL descriptor area after analyzing descriptions and acquiring storage
The following figure shows the SQLDA after your program executes a FETCH statement.
SQLVAR element 1 (44 bytes) 452 3 Addr FLDA Addr FLDAI 8 WORKDEPT
SQLVAR element 2 (44 bytes) 453 4 Addr FLDB Addr FLDBI 7 PHONENO
Indicator variables
FLDA FLDB (halfword)
CHAR(3) CHAR(4) FLDAI FLDBI
E11 4502 0 0
The initial value of this special register is the application encoding scheme that is determined by the
BIND option.
• For static and dynamic SQL statements that use host variables and host-variable arrays, use the
DECLARE VARIABLE statement to associate CCSIDs with the host variables into which you retrieve
the data. See “Setting the CCSID for host variables” on page 478 for information about this
technique.
• For static and dynamic SQL statements that use a descriptor, set the CCSID for the retrieved data in
the SQLDA. The following text describes that technique.
To change the encoding scheme for SQL statements that use a descriptor, set up the SQLDA, and then
make these additional changes to the SQLDA:
506 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
1. Put the character + in the sixth byte of field SQLDAID.
2. For each SQLVAR entry:
a. Set the length field of SQLNAME to 8.
b. Set the first two bytes of the data field of SQLNAME to X'0000'.
c. Set the third and fourth bytes of the data field of SQLNAME to the CCSID, in hexadecimal, in
which you want the results to display, or to X'0000'. X'0000' indicates that Db2 should use the
default CCSID If you specify a nonzero CCSID, it must meet one of the following conditions:
• A row in catalog table SYSSTRINGS has a matching value for OUTCCSID.
• The Unicode conversion services support conversion to that CCSID. See Building and using
Dynamic Link Libraries (DLLs) (XL C/C++ Programming Guide) for information about the
conversions supported.
If you are modifying the CCSID to retrieve the contents of an ASCII, EBCDIC, or Unicode table
on a Db2 for z/OS system, and you previously executed a DESCRIBE statement on the SELECT
statement that you are using to retrieve the data, the SQLDATA fields in the SQLDA that you
used for the DESCRIBE contain the ASCII or Unicode CCSID for that table. To set the data
portion of the SQLNAME fields for the SELECT, move the contents of each SQLDATA field in the
SQLDA from the DESCRIBE to each SQLNAME field in the SQLDA for the SELECT. If you are
using the same SQLDA for the DESCRIBE and the SELECT, be sure to move the contents of the
SQLDATA field to SQLNAME before you modify the SQLDATA field for the SELECT.
For REXX, you set the CCSID in the stem.n.SQLUSECCSID field instead of setting the SQLDAID and
SQLNAME fields.
For example, suppose that the table that contains WORKDEPT and PHONENO is defined with CCSID
ASCII. To retrieve data for columns WORKDEPT and PHONENO in ASCII CCSID 437 (X'01B5'), change
the SQLDA as shown in the following figure.
SQLVAR element 1 (44 bytes) 452 3 Addr FLDA Addr FLDAI 8 X 000001B500000000
SQLVAR element 2 (44 bytes) 453 4 Addr FLDB Addr FLDBI 8 X 000001B500000000
Indicator variables
FLDA FLDB (halfword)
CHAR(3) CHAR(4) FLDAI FLDBI
Figure 35. SQL descriptor area for retrieving data in ASCII CCSID 437
EXEC SQL
DESCRIBE STMT INTO :FULSQLDA USING LABELS;
Some columns, such as those derived from functions or expressions, have neither name nor label;
SQLNAME contains nothing for those columns. For example, if you use a UNION to combine two
columns that do not have the same name and do not use a label, SQLNAME contains a string of length
zero.
Describing tables with LOB and distinct type columns
In general, the steps that you perform when you prepare an SQLDA to select rows from a table with
LOB and distinct type columns are similar to the steps that you perform if the table has no columns of
this type. The only difference is that you need to analyze some additional fields in the SQLDA for LOB
or distinct type columns.
For example, Suppose that you want to execute this SELECT statement:
The USER column cannot contain nulls and is of distinct type ID, defined like this:
Figure 36. SQL descriptor area after describing a CLOB and distinct type
The next steps are the same as for result tables without LOBs or distinct types:
1. Analyze each SQLVAR description to determine the maximum amount of space you need for the
column value.
For a LOB type, retrieve the length from the SQLLONGL field instead of the SQLLEN field.
2. Derive the address of some storage area of the required size.
For a LOB data type, you also need a 4-byte storage area for the length of the LOB data. You can
allocate this 4-byte area at the beginning of the LOB data or in a different location.
3. Put this address in the SQLDATA field.
508 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
For a LOB data type, if you allocated a separate area to hold the length of the LOB data, put the
address of the length field in SQLDATAL. If the length field is at beginning of the LOB data area,
put 0 in SQLDATAL. When you use a file reference variable for a LOB column, the indicator variable
indicates whether the data in the file is null, not whether the data to which SQLDATA points is null.
4. If the SQLTYPE field indicates that the value can be null, the program must also put the address of
an indicator variable in the SQLIND field.
The following figure shows the contents of FULSQLDA after you enter pointers to the storage
locations.
4-byte
length
field
Figure 37. SQL descriptor area after analyzing CLOB and distinct type descriptions and acquiring
storage
The following figure shows the contents of FULSQLDA after you execute a FETCH statement.
4-byte length
field contains
actual length
of data
Figure 38. SQL descriptor area after executing FETCH on a table with CLOB and distinct type columns
sqllen 0
SQLLEN
sqldata 0
SQLDATA
sqlind 0
SQLIND
3. Check the SQLTYPE field of each SQLVAR entry. If the SQLTYPE field is 988 or 989, the column in
the result set is an XML column.
4. For each XML column, make the following changes to the associated SQLVAR entry:
a. Change the SQLTYPE field to indicate the data type of the host variable to receive the XML data.
You can retrieve the XML data into a host variable of type XML AS BLOB, XML AS CLOB, or XML
AS DBCLOB, or a compatible string data type.
If the target host variable type is XML AS BLOB, XML AS CLOB, or XML AS DBCLOB, set the
SQLTYPE field to one of the following values:
404
XML AS BLOB
405
nullable XML AS BLOB
408
XML AS CLOB
409
nullable XML AS CLOB
412
XML AS DBCLOB
413
nullable XML AS DBCLOB
If the target host variable type is a string data type, set the SQLTYPE field to a valid string value.
Restriction: You cannot use the XML type (988/989) as a target host variable type.
b. If the target host variable type is XML AS BLOB, XML AS CLOB, or XML AS DBCLOB, change the
first two bytes in the SQLNAME field to X'0000' and the fifth and sixth bytes to X'0100'. These
bytes indicate that the value to be received is an XML value.
5. Populate the extended SQLVAR fields for each XML column as you would for a LOB column, as
indicated in the following table.
510 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 88. Fields for an extended SQLVAR entry for an XML host variable
SQLVAR field Value for an XML host variable
* Reserved
You can now use the SQLDA to retrieve the XML data into a host variable of type XML AS BLOB, XML
AS CLOB, or XML AS DBCLOB, or a compatible string data type.
Executing a varying-list SELECT statement dynamically
You can easily retrieve rows of the result table using a varying-list SELECT statement. The statements
differ only a little from those for the fixed-list example.
1. Open the cursor. If the SELECT statement contains no parameter marker, this step is simple
enough. For example:
2. Fetch rows from the result table. This statement differs from the corresponding one for the case of
a fixed-list select. Write:
EXEC SQL
FETCH C1 USING DESCRIPTOR :FULSQLDA;
The key feature of this statement is the clause USING DESCRIPTOR :FULSQLDA. That clause
names an SQL descriptor area in which the occurrences of SQLVAR point to other areas. Those
other areas receive the values that FETCH returns. It is possible to use that clause only because
you previously set up FULSQLDA to look like Figure 32 on page 504.
Figure 34 on page 505 shows the result of the FETCH. The data areas identified in the SQLVAR
fields receive the values from a single row of the result table.
Successive executions of the same FETCH statement put values from successive rows of the result
table into these same areas.
3. Close the cursor. This step is the same as for the fixed-list case. When no more rows need to be
processed, execute the following statement:
When COMMIT ends the unit of work containing OPEN, the statement in STMT reverts to the
unprepared state. Unless you defined the cursor using the WITH HOLD option, you must prepare
the statement again before you can reopen the cursor.
Executing arbitrary statements with parameter markers
Consider, as an example, a program that executes dynamic SQL statements of several kinds, including
varying-list SELECT statements, any of which might contain a variable number of parameter markers.
This program might present your users with lists of choices: choices of operation (update, select,
delete); choices of table names; choices of columns to select or update. The program also enables the
• If the SQL statement is SELECT, name a list of host variables in the OPEN statement:
In both cases, the number and types of host variables named must agree with the number of
parameter markers in STMT and the types of parameter they represent. The first variable (VAR1 in
the examples) must have the type expected for the first parameter marker in the statement, the
second variable must have the type expected for the second marker, and so on. There must be at
least as many variables as parameter markers.
When the number and types of parameters are not known
When you do not know the number and types of parameters, you can adapt the SQL descriptor
area. Your program can include an unlimited number of SQLDAs, and you can use them for
different purposes. Suppose that an SQLDA, arbitrarily named DPARM, describes a set of
parameters.
The structure of DPARM is the same as that of any other SQLDA. The number of occurrences of
SQLVAR can vary, as in previous examples. In this case, every parameter marker must have one
SQLVAR. Each occurrence of SQLVAR describes one host variable that replaces one parameter
marker at run time. Db2 replaces the parameter markers when a non-SELECT statement executes
or when a cursor is opened for a SELECT statement.
You must enter certain fields in DPARM before using EXECUTE or OPEN; you can ignore the other
fields.
Field
Use when describing host variables for parameter markers
SQLDAID
The seventh byte indicates whether more than one SQLVAR entry is used for each parameter
marker. If this byte is not blank, at least one parameter marker represents a distinct type or
LOB value, so the SQLDA has more than one set of SQLVAR entries.
You do not set this field for a REXX SQLDA.
SQLDABC
The length of the SQLDA, which is equal to SQLN * 44 + 16. You do not set this field for a REXX
SQLDA.
SQLN
The number of occurrences of SQLVAR allocated for DPARM. You do not set this field for a
REXX SQLDA.
512 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
SQLD
The number of occurrences of SQLVAR actually used. This number must not be less than the
number of parameter markers. In each occurrence of SQLVAR, put information in the following
fields: SQLTYPE, SQLLEN, SQLDATA, SQLIND.
SQLTYPE
The code for the type of variable, and whether it allows nulls.
SQLLEN
The length of the host variable.
SQLDATA
The address of the host variable.
For REXX, this field contains the value of the host variable.
SQLIND
The address of an indicator variable, if needed.
For REXX, this field contains a negative number if the value in SQLDATA is null.
SQLNAME
Ignore.
Using the SQLDA with EXECUTE or OPEN
To indicate that the SQLDA called DPARM describes the host variables substituted for the parameter
markers at run time, use a USING DESCRIPTOR clause with EXECUTE or OPEN.
• For a non-SELECT statement, write:
How bind options REOPT(ALWAYS), REOPT(AUTO) and REOPT(ONCE) affect dynamic SQL
When you specify the bind option REOPT(ALWAYS), Db2 reoptimizes the access path at run time
for SQL statements that contain host variables, parameter markers, or special registers. The option
REOPT(ALWAYS) has the following effects on dynamic SQL statements:
• When you specify the option REOPT(ALWAYS), Db2 automatically uses DEFER(PREPARE), which
means that Db2 waits to prepare a statement until it encounters an OPEN or EXECUTE statement.
• When you execute a DESCRIBE statement and then an EXECUTE statement on a non-SELECT
statement, Db2 prepares the statement twice: Once for the DESCRIBE statement and once for
the EXECUTE statement. Db2 uses the values in the input variables only during the second
PREPARE. These multiple PREPAREs can cause performance to degrade if your program contains
many dynamic non-SELECT statements. To improve performance, consider putting the code that
contains those statements in a separate package and then binding that package with the option
REOPT(NONE).
• If you execute a DESCRIBE statement before you open a cursor for that statement, Db2 prepares
the statement twice. If, however, you execute a DESCRIBE statement after you open the cursor,
Db2 prepares the statement only once. To improve the performance of a program bound with the
option REOPT(ALWAYS), execute the DESCRIBE statement after you open the cursor. To prevent an
automatic DESCRIBE before a cursor is opened, do not use a PREPARE statement with the INTO
clause.
• If you use predictive governing for applications bound with REOPT(ALWAYS), Db2 does not return
a warning SQLCODE when dynamic SQL statements exceed the predictive governing warning
threshold. Db2 does return an error SQLCODE when dynamic SQL statements exceed the predictive
governing error threshold. Db2 returns the error SQLCODE for an EXECUTE or OPEN statement.
When you specify the bind option REOPT(AUTO), Db2 optimizes the access path for SQL statements
at the first EXECUTE or OPEN. Each time a statement is executed, Db2 determines if a new access
514 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
– If you execute DESCRIBE on a statement before you open a cursor for that statement, Db2
always prepares the statement on DESCRIBE. However, Db2 will not prepare the statement again
on OPEN if the statement has already been saved in the cache. If you execute DESCRIBE on a
statement after you open a cursor for that statement, Db2 prepared the statement only once if it
is not already saved in the cache. If the statement is already saved in the cache and you execute
DESCRIBE after you open a cursor for that statement, Db2 does not prepare the statement, it
used the statement that is saved in the cache.
To improve the performance of a program that is bound with REOPT(ONCE), execute the DESCRIBE
statement after you open a cursor. To prevent an automatic DESCRIBE before a cursor is opened, do
not use a PREPARE statement with the INTO clause.
• If you use predictive governing for applications that are bound with REOPT(ONCE), Db2 does not
return a warning SQLCODE when dynamic SQL statements exceed the predictive governing warning
threshold. Db2 does return an error SQLCODE when dynamic SQL statements exceed the predictive
governing error threshold. Db2 returns the error SQLCODE for an EXECUTE or OPEN statement.
Related concepts
Assembler applications that issue SQL statements
You can code SQL statements in assembler programs wherever you can use executable statements.
C and C++ applications that issue SQL statements
You can code SQL statements in a C or C++ program wherever you can use executable statements.
COBOL applications that issue SQL statements
You can code SQL statements in certain COBOL program sections.
Fortran applications that issue SQL statements
You can code SQL statements in a Fortran program wherever you can place executable statements. If
the SQL statement is within an IF statement, the precompiler generates any necessary THEN and END IF
statements.
PL/I applications that issue SQL statements
You can code SQL statements in a PL/I program wherever you can use executable statements.
REXX applications that issue SQL statements
You can code SQL statements in a REXX programs wherever you can use REXX commands.
Related reference
DESCRIBE OUTPUT (Db2 SQL)
SQL descriptor area (SQLDA) (Db2 SQL)
SQLTYPE and SQLLEN (Db2 SQL)
The SQLDA Header (Db2 SQL)
Examples
Example: Using a varying-length character host variable
This excerpt is from a C program that reads a DELETE statement into the host variable dstring and
executes the statement:
EXECUTE IMMEDIATE causes the DELETE statement to be prepared and executed immediately.
Declaring a CLOB or DBCLOB host variable
You declare CLOB and DBCLOB host variables according to certain rules.
The precompiler generates a structure that contains two elements, a 4-byte length field and a data
field of the specified length. The names of these fields vary depending on the host language:
• In PL/I, assembler, and Fortran, the names are variable_LENGTH and variable_DATA.
• In COBOL, the names are variable–LENGTH and variable–DATA.
• In C, the names are variable.LENGTH and variable.DATA.
Example: Using a CLOB host variable
This excerpt is from a C program that copies an UPDATE statement into the host variable string1 and
executes the statement:
EXECUTE IMMEDIATE causes the UPDATE statement to be prepared and executed immediately.
Related concepts
LOB host variable, LOB locator, and LOB file reference variable declarations
When you write applications to manipulate LOB data, you need to declare host variables to hold the LOB
data or LOB locator. Alternatively, you need to declare LOB file reference variables to point to the LOB
data.
Assembler applications that issue SQL statements
You can code SQL statements in assembler programs wherever you can use executable statements.
C and C++ applications that issue SQL statements
516 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
You can code SQL statements in a C or C++ program wherever you can use executable statements.
COBOL applications that issue SQL statements
You can code SQL statements in certain COBOL program sections.
Fortran applications that issue SQL statements
You can code SQL statements in a Fortran program wherever you can place executable statements. If
the SQL statement is within an IF statement, the precompiler generates any necessary THEN and END IF
statements.
PL/I applications that issue SQL statements
You can code SQL statements in a PL/I program wherever you can use executable statements.
REXX applications that issue SQL statements
You can code SQL statements in a REXX programs wherever you can use REXX commands.
Procedure
To construct and execute statements dynamically your program must now do these things differently:
• Use parameter markers instead of host variables.
Dynamic SQL statements cannot use host variables. Therefore, you cannot dynamically execute an
SQL statement that contains host variables. Instead, substitute a parameter marker, indicated by a
question mark (?), for each host variable in the statement.
You can indicate to Db2 that a parameter marker represents a host variable of a certain data type
by specifying the parameter marker as the argument of a CAST specification. When the statement
executes, Db2 converts the host variable to the data type in the CAST specification. A parameter
marker that you include in a CAST specification is called a typed parameter marker. A parameter
marker without a CAST specification is called an untyped parameter marker.
Recommendation: Because Db2 can evaluate an SQL statement with typed parameter markers more
efficiently than a statement with untyped parameter markers, use typed parameter markers whenever
possible. Under certain circumstances you must use typed parameter markers.
For example, suppose that you want to prepare this statement:
You associate host variable :EMP with the parameter marker when you execute the prepared
statement. Suppose that S1 is the prepared statement. Then the EXECUTE statement looks like this:
The prepared statement still contains a parameter marker, for which you must supply a value when
the statement executes. After the statement is prepared, the table name is fixed, but the parameter
marker enables you to execute the same statement many times with different values of the employee
number.
• Use EXECUTE instead of EXECUTE IMMEDIATE.
The EXECUTE statement executes a prepared SQL statement by naming a list of one or more host
variables, one or more host-variable arrays, or a host structure. This list supplies values for all of the
parameter markers.
After you prepare a statement, you can execute it many times within the same unit of work. In
most cases, COMMIT or ROLLBACK destroys statements prepared in a unit of work. Then, you must
prepare them again before you can execute them again. However, if you declare a cursor for a
dynamic statement and use the option WITH HOLD, a commit operation does not destroy the prepared
statement if the cursor is still open. You can execute the statement in the next unit of work without
preparing it again.
For example, to execute the prepared statement S1 just once, using a parameter value contained in
the host variable :EMP, write:
Examples
Preparing and executing the example DELETE statement
You can now write an equivalent example for a dynamic SQL statement:
518 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
The PREPARE statement prepares the SQL statement and calls it S1. The EXECUTE statement
executes S1 repeatedly, using different values for EMP.
Using more than one parameter marker
The prepared statement (S1 in the example) can contain more than one parameter marker. If it does,
the USING clause of EXECUTE specifies a list of variables or a host structure. The variables must
contain values that match the number and data types of parameters in S1 in the proper order. You
must know the number and types of parameters in advance and declare the variables in your program,
or you can use an SQLDA (SQL descriptor area).
Related concepts
Assembler applications that issue SQL statements
You can code SQL statements in assembler programs wherever you can use executable statements.
C and C++ applications that issue SQL statements
You can code SQL statements in a C or C++ program wherever you can use executable statements.
COBOL applications that issue SQL statements
You can code SQL statements in certain COBOL program sections.
Fortran applications that issue SQL statements
You can code SQL statements in a Fortran program wherever you can place executable statements. If
the SQL statement is within an IF statement, the precompiler generates any necessary THEN and END IF
statements.
PL/I applications that issue SQL statements
You can code SQL statements in a PL/I program wherever you can use executable statements.
REXX applications that issue SQL statements
You can code SQL statements in a REXX programs wherever you can use REXX commands.
Related tasks
Dynamically executing an SQL statement by using EXECUTE IMMEDIATE
In certain situations, you might want your program to prepare and dynamically execute a statement
immediately after reading it.
Related reference
PREPARE (Db2 SQL)
EXEC SQL
INSERT INTO DSN8C10.ACT
VALUES (:hva_actno, :hva_actkwd, :hva_actdesc)
FOR :num_rows ROWS;
However, if you want to enter the rows of data into different tables or enter different numbers of rows, you
can construct the INSERT statement dynamically.
Procedure
To execute a data change statement dynamically, use one of the following methods:
• Use descriptor to describe the host-variable arrays that contain the data, by completing the following
actions in your program:
a) Set the following fields in the SQLDA structure to specify data types and other information about
the host-variable arrays that contain the values to insert in your INSERT statement.
– SQLN
– SQLABC
– SQLD
– SQLVAR
– SQLNAME
Assume that your program includes the standard SQLDA structure declaration and declarations for
the program variables that point to the SQLDA structure. For C application programs, the following
example code sets the SQLDA fields:
strcpy(sqldaptr->sqldaid,"SQLDA");
sqldaptr->sqldabc = 192; /* number of bytes of storage allocated
for the SQLDA */
sqldaptr->sqln = 4; /* number of SQLVAR
occurrences */
sqldaptr->sqld = 4;
varptr = (struct sqlvar *) (&(sqldaptr->sqlvar[0])); /* Point
to first SQLVAR */
varptr->sqltype = 500; /* data
type SMALLINT */
varptr->sqllen = 2;
varptr->sqldata = (char *) hva1;
varptr->sqlname.length = 8;
memcpy(varptr->sqlname.data, "\x00\x00\x00\x00\x00\x01\x00\x14",varptr->sqlname.length);
varptr = (struct sqlvar *) (&(sqldaptr->sqlvar[0]) + 1); /* Point
to next SQLVAR */
varptr->sqltype = 452; /* data
type CHAR(6) */
varptr->sqllen = 6;
varptr->sqldata = (char *) hva2;
varptr->sqlname.length = 8;
memcpy(varptr->sqlname.data, "\x00\x00\x00\x00\x00\x01\x00\x14",varptr->sqlname.length);
varptr = (struct sqlvar *) (&(sqldaptr->sqlvar[0]) + 2); /* Point
to next SQLVAR */
520 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
varptr->sqltype = 448; /* data type
VARCHAR(20) */
varptr->sqllen = 20;
varptr->sqldata = (char *) hva3;
varptr->sqlname.length = 8;
memcpy(varptr->sqlname.data, "\x00\x00\x00\x00\x00\x01\x00\x14",varptr->sqlname.length);
Related concepts
Assembler applications that issue SQL statements
You can code SQL statements in assembler programs wherever you can use executable statements.
C and C++ applications that issue SQL statements
You can code SQL statements in a C or C++ program wherever you can use executable statements.
COBOL applications that issue SQL statements
You can code SQL statements in certain COBOL program sections.
Fortran applications that issue SQL statements
Procedure
To dynamically execute a statement with parameter markers by using the SQLDA:
1. Include in your program a DESCRIBE INPUT statement that specifies the prepared SQL statement and
the name of an appropriate SQLDA.
Db2 puts the requested parameter marker information in the SQLDA.
2. Code the application in the same way as any other application in which you execute a prepared
statement by using an SQLDA. First, obtain the addresses of the input host variables and their indicator
variables and insert those addresses into the SQLDATA and SQLIND fields. Then, execute the prepared
SQL statement.
Example
Suppose that you want to execute the following statement dynamically:
You can use the following code to set up an SQLDA, obtain parameter information by using the DESCRIBE
INPUT statement, and execute the statement:
522 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Related concepts
Assembler applications that issue SQL statements
You can code SQL statements in assembler programs wherever you can use executable statements.
C and C++ applications that issue SQL statements
You can code SQL statements in a C or C++ program wherever you can use executable statements.
COBOL applications that issue SQL statements
You can code SQL statements in certain COBOL program sections.
Fortran applications that issue SQL statements
You can code SQL statements in a Fortran program wherever you can place executable statements. If
the SQL statement is within an IF statement, the precompiler generates any necessary THEN and END IF
statements.
PL/I applications that issue SQL statements
You can code SQL statements in a PL/I program wherever you can use executable statements.
REXX applications that issue SQL statements
You can code SQL statements in a REXX programs wherever you can use REXX commands.
Related tasks
Defining SQL descriptor areas (SQLDA)
If your program includes certain SQL statements, you must define at least one SQL descriptor area
(SQLDA). Depending on the context in which it is used, the SQLDA stores information about prepared SQL
statements or host variables. This information can then be read by either the application program or Db2.
Related reference
DESCRIBE INPUT (Db2 SQL)
524 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
– SQLWARN5 contains a character value of 1 (read only), 2 (read and delete), or 4 (read, delete, and
update) to indicate the operation that is allowed on the result table of the cursor.
Related tasks
Accessing data by using a rowset-positioned cursor
A rowset-positioned cursor is a cursor that can return one or more rows for a single fetch operation. The
cursor is positioned on the set of rows that are to be fetched.
Checking the execution of SQL statements by using SQLCODE and SQLSTATE
Whenever an SQL statement executes, the SQLCODE and SQLSTATE fields of the SQLCA receive a return
code.
Defining the SQL communications area, SQLSTATE, and SQLCODE in assembler
Assembler programs that contain SQL statements can include an SQL communications area (SQLCA)
to check whether an SQL statement executed successfully. Alternatively, these programs can declare
individual SQLCODE and SQLSTATE host variables.
Defining the SQL communications area, SQLSTATE, and SQLCODE in C and C++
C and C++ programs that contain SQL statements can include an SQL communications area (SQLCA)
to check whether an SQL statement executed successfully. Alternatively, these programs can declare
individual SQLCODE and SQLSTATE host variables.
Defining the SQL communications area, SQLSTATE, and SQLCODE in COBOL
COBOL programs that contain SQL statements can include an SQL communications area (SQLCA) to check
whether an SQL statement executed successfully. Alternatively, these programs can declare individual
SQLCODE and SQLSTATE host variables.
Defining the SQL communications area, SQLSTATE, and SQLCODE in Fortran
Fortran programs that contain SQL statements can include an SQL communications area (SQLCA) to check
whether an SQL statement executed successfully. Alternatively, these programs can declare individual
SQLCODE and SQLSTATE host variables.
Defining the SQL communications area, SQLSTATE, and SQLCODE in PL/I
PL/I programs that contain SQL statements can include an SQL communications area (SQLCA) to check
whether an SQL statement executed successfully. Alternatively, these programs can declare individual
SQLCODE and SQLSTATE host variables.
Defining the SQL communications area, SQLSTATE, and SQLCODE in REXX
When Db2 prepares a REXX program that contains SQL statements, Db2 automatically includes an SQLCA
in the program.
Related reference
Description of SQLCA fields (Db2 SQL)
DSNTIAR
The assembler subroutine DSNTIAR helps you to obtain a formatted form of the SQLCA and a text
message that is based on the SQLCODE field of the SQLCA.
DSNTIAR can run either above or below the 16-MB line of virtual storage. The DSNTIAR object module
that comes with Db2 has the attributes AMODE(31) and RMODE(ANY). At installation time, DSNTIAR links
as AMODE(31) and RMODE(ANY). DSNTIAR runs in 31-bit mode if any of the following conditions is true:
• DSNTIAR is linked with other modules that also have the attributes AMODE(31) and RMODE(ANY).
• DSNTIAR is linked into an application that specifies the attributes AMODE(31) and RMODE(ANY) in its
link-edit JCL.
• An application loads DSNTIAR.
When loading DSNTIAR from another program, be careful how you branch to DSNTIAR. For example, if the
calling program is in 24-bit addressing mode and DSNTIAR is loaded above the 16-MB line, you cannot
use the assembler BALR instruction or CALL macro to call DSNTIAR, because they assume that DSNTIAR
is in 24-bit mode. Instead, you must use an instruction that is capable of branching into 31-bit mode,
such as BASSM.
You can dynamically link (load) and call DSNTIAR directly from a language that does not handle 31-bit
addressing. To do this, link a second version of DSNTIAR with the attributes AMODE(24) and RMODE(24)
into another load module library. Alternatively, you can write an intermediate assembler language
program that calls DSNTIAR in 31-bit mode and then call that intermediate program in 24-bit mode
from your application.
For more information on the allowed and default AMODE and RMODE settings for a particular language,
see the application programming guide for that language. For details on how the attributes AMODE and
RMODE of an application are determined, see the linkage editor and loader user's guide for the language
in which you have written the application.
526 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Line:
1
2
.
.
.
n-1
When you call DSNTIAR, you must name an SQLCA and an output message area in the DSNTIAR
parameters. You must also provide the logical record length (lrecl) as a value between 72 and 240 bytes.
DSNTIAR assumes the message area contains fixed-length records of length lrecl.
DSNTIAR places up to 10 lines in the message area. If the text of a message is longer than the record
length you specify on DSNTIAR, the output message splits into several records, on word boundaries if
possible. The split records are indented. All records begin with a blank character for carriage control. If
you have more lines than the message output area can contain, DSNTIAR issues a return code of 4. A
completely blank record marks the end of the message output area.
An SQLCODE of 0 or -501 resulting from that statement indicates that the close was successful.
To use DSNTIAR to generate the error message text, first follow these steps:
1. Choose a logical record length (lrecl) of the output lines. For this example, assume lrecl is 72 (to fit on a
terminal screen) and is stored in the variable named ERROR-TEXT-LEN.
2. Define a message area in your COBOL application. Assuming you want an area for up to 10 lines of
length 72, you should define an area of 720 bytes, plus a 2-byte area that specifies the total length of
the message output area.
01 ERROR-MESSAGE.
02 ERROR-LEN PIC S9(4) COMP VALUE +720.
02 ERROR-TEXT PIC X(72) OCCURS 10 TIMES
INDEXED BY ERROR-INDEX.
77 ERROR-TEXT-LEN PIC S9(9) COMP VALUE +72.
You can then print the message output area just as you would any other variable. Your message might
look like this:
Procedure
You can declare SQLCODE and SQLSTATE (SQLCOD and SQLSTA in Fortran) as stand-alone host variables.
If you specify the STDSQL(YES) precompiler option, these host variables receive the return codes, and
you should not include an SQLCA in your program.
Portable applications should use SQLSTATE instead of SQLCODE, although SQLCODE values can provide
additional Db2-specific information about an SQL error or warning.
An advantage to using the SQLCODE field is that it can provide more specific information than the
SQLSTATE. Many of the SQLCODEs have associated tokens in the SQLCA that indicate, for example, which
object incurred an SQL error. However, an SQL standard application uses only SQLSTATE.
SQLCODE
Db2 returns the following codes in SQLCODE:
• If SQLCODE = 0, execution was successful.
• If SQLCODE > 0, execution was successful with a warning.
528 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
• If SQLCODE < 0, execution was not successful.
SQLCODE 100 indicates that no data was found.
The meaning of SQLCODEs other than 0 and 100 varies with the particular product implementing SQL.
SQLSTATE
SQLSTATE enables an application program to check for errors in the same way for different IBM
database management systems.
Related tasks
Defining the SQL communications area, SQLSTATE, and SQLCODE in assembler
Assembler programs that contain SQL statements can include an SQL communications area (SQLCA)
to check whether an SQL statement executed successfully. Alternatively, these programs can declare
individual SQLCODE and SQLSTATE host variables.
Defining the SQL communications area, SQLSTATE, and SQLCODE in C and C++
C and C++ programs that contain SQL statements can include an SQL communications area (SQLCA)
to check whether an SQL statement executed successfully. Alternatively, these programs can declare
individual SQLCODE and SQLSTATE host variables.
Defining the SQL communications area, SQLSTATE, and SQLCODE in COBOL
COBOL programs that contain SQL statements can include an SQL communications area (SQLCA) to check
whether an SQL statement executed successfully. Alternatively, these programs can declare individual
SQLCODE and SQLSTATE host variables.
Defining the SQL communications area, SQLSTATE, and SQLCODE in Fortran
Fortran programs that contain SQL statements can include an SQL communications area (SQLCA) to check
whether an SQL statement executed successfully. Alternatively, these programs can declare individual
SQLCODE and SQLSTATE host variables.
Defining the SQL communications area, SQLSTATE, and SQLCODE in PL/I
PL/I programs that contain SQL statements can include an SQL communications area (SQLCA) to check
whether an SQL statement executed successfully. Alternatively, these programs can declare individual
SQLCODE and SQLSTATE host variables.
Defining the SQL communications area, SQLSTATE, and SQLCODE in REXX
When Db2 prepares a REXX program that contains SQL statements, Db2 automatically includes an SQLCA
in the program.
Related reference
SQLSTATE values and common error codes (Db2 Codes)
EXEC SQL
WHENEVER condition action
END-EXEC
Procedure
You can use the GET DIAGNOSTICS statement to return diagnostic information about the last SQL
statement that was executed.
You can request individual items of diagnostic information from the following groups of items:
• Statement items, which contain information about the SQL statement as a whole
• Condition items, which contain information about each error or warning that occurred during the
execution of the SQL statement
• Connection items, which contain information about the SQL statement if it was a CONNECT statement
In addition to requesting individual items, you can request that GET DIAGNOSTICS return all diagnostic
items that are set during the execution of the last SQL statement as a single string.
In SQL procedures, you can also retrieve diagnostic information by using handlers. Handlers tell the
procedure what to do if a particular error occurs.
Use the GET DIAGNOSTICS statement to handle multiple SQL errors that might result from the execution
of a single SQL statement. First, check SQLSTATE (or SQLCODE) to determine whether diagnostic
information should be retrieved by using GET DIAGNOSTICS. This method is especially useful for
diagnosing problems that result from a multiple-row INSERT that is specified as NOT ATOMIC CONTINUE
ON SQLEXCEPTIONand multiple row MERGE statements.
530 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Even if you use only the GET DIAGNOSTICS statement in your application program to check for
conditions, you must either include the instructions required to use the SQLCA or you must declare
SQLSTATE (or SQLCODE) separately in your program.
When you use the GET DIAGNOSTICS statement, you assign the requested diagnostic information to host
variables. Declare each target host variable with a data type that is compatible with the data type of the
requested item.
To retrieve condition information, you must first retrieve the number of condition items (that is, the
number of errors and warnings that Db2 detected during the execution of the last SQL statement). The
number of condition items is at least one. If the last SQL statement returned SQLSTATE '00000' (or
SQLCODE 0), the number of condition items is one.
In the activity table, the ACTNO column is defined as SMALLINT. Suppose that you declare the host-
variable array hva1 as an array with data type long, and you populate the array so that the value for the
fourth element is 32768.
If you check the SQLCA values after the INSERT statement, the value of SQLCODE is equal to 0, the value
of SQLSTATE is '00000', and the value of SQLERRD(3) is 9 for the number of rows that were inserted.
However, the INSERT statement specified that 10 rows were to be inserted.
The GET DIAGNOSTICS statement provides you with the information that you need to correct the data for
the row that was not inserted. The printed output from your program looks like this:
The value 32768 for the input variable is too large for the target column ACTNO. You can print the
MESSAGE_TEXT condition item.
Table 89. Data types for GET DIAGNOSTICS items that return statement information
Item Description Data type
DB2_GET_DIAGNOSTICS_DIAGNOSTICS After a GET DIAGNOSTICS VARCHAR(32672)
statement, if any error or warning
occurred, this item contains all of the
diagnostics as a single string.
DB2_LAST_ROW After a multiple-row FETCH INTEGER
statement, this item contains a value
of +100 if the last row in the table is
in the rowset that was returned.
DB2_NUMBER_PARAMETER_MARKERS After a PREPARE statement, this item INTEGER
contains the number of parameter
markers in the prepared statement.
DB2_NUMBER_RESULT_SETS After a CALL statement that invokes INTEGER
a stored procedure, this item
contains the number of result sets
that are returned by the procedure.
532 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 89. Data types for GET DIAGNOSTICS items that return statement information (continued)
Item Description Data type
DB2_NUMBER_ROWS After an OPEN or FETCH statement DECIMAL(31,0)
for which the size of the result table
is known, this item contains the
number of rows in the result table.
After a PREPARE statement, this
item contains the estimated number
of rows in the result table for the
prepared statement. For SENSITIVE
DYNAMIC cursors, this item contains
the approximate number of rows.
Otherwise, or if the server only
returns an SQLCA, the value zero is
returned.
DB2_RETURN_STATUS After a CALL statement that invokes INTEGER
an SQL procedure, this item contains
the return status if the procedure
contains a RETURN statement.
DB2_SQL_ATTR_CURSOR_HOLD After an ALLOCATE or OPEN CHAR(1)
statement, this item indicates
whether the cursor can be held open
across multiple units of work (Y or
N).
DB2_SQL_ATTR_CURSOR_ROWSET After an ALLOCATE or OPEN CHAR(1)
statement, this item indicates
whether the cursor can use rowset
positioning (Y or N).
DB2_SQL_ATTR_CURSOR_SCROLLABLE After an ALLOCATE or OPEN CHAR(1)
statement, this item indicates
whether the cursor is scrollable (Y or
N).
DB2_SQL_ATTR_CURSOR_SENSITIVITY After an ALLOCATE or OPEN CHAR(1)
statement, this item indicates
whether the cursor shows updates
made by other processes (sensitivity
I or S).
DB2_SQL_ATTR_CURSOR_TYPE After an ALLOCATE or OPEN CHAR(1)
statement, this item indicates
whether the cursor is forward (F),
declared static (S for INSENSITIVE
or SENSITIVE STATIC, or dynamic (D
for SENSITIVE DYNAMIC).
Table 90. Data types for GET DIAGNOSTICS items that return condition information
Item Description Data type
CATALOG_NAME This item contains the server name of the VARCHAR(128)
table that owns a constraint that caused
an error, or that caused an access rule or
check violation.
CONDITION_NUMBER This item contains the number of the INTEGER
condition.
CURSOR_NAME This item contains the name of a cursor in VARCHAR(128)
an invalid cursor state.
DB2_ERROR_CODE1 This item contains an internal error code. INTEGER
DB2_ERROR_CODE2 This item contains an internal error code. INTEGER
DB2_ERROR_CODE3 This item contains an internal error code. INTEGER
DB2_ERROR_CODE4 This item contains an internal error code. INTEGER
534 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 90. Data types for GET DIAGNOSTICS items that return condition information (continued)
Item Description Data type
DB2_INTERNAL_ERROR_POINTER For some errors, this item contains a INTEGER
negative value that is an internal error
pointer.
DB2_MESSAGE_ID This item contains the message ID CHAR(10)
that corresponds to the message that
is contained in the MESSAGE_TEXT
diagnostic item.
DB2_MODULE_DETECTING_ERROR After any SQL statement, this item CHAR(8)
indicates which module detected the
error.
DB2_ORDINAL_TOKEN_n After any SQL statement, this item VARCHAR(515)
contains the nth token, where n is a value
from 1 to 100.
DB2_REASON_CODE After any SQL statement, this item INTEGER
contains the reason code for errors that
have a reason code token in the message
text.
DB2_RETURNED_SQLCODE After any SQL statement, this item INTEGER
contains the SQLCODE for the condition.
DB2_ROW_NUMBER After any SQL statement that involves DECIMAL(31,0)
multiple rows, this item contains the
row number on which Db2 detected the
condition.
DB2_TOKEN_COUNT After any SQL statement, this item INTEGER
contains the number of tokens available
for the condition.
MESSAGE_TEXT After any SQL statement, this item VARCHAR(32672)
contains the message text associated with
the SQLCODE.
RETURNED_SQLSTATE After any SQL statement, this item CHAR(5)
contains the SQLSTATE for the condition.
SERVER_NAME After a CONNECT, DISCONNECT, or VARCHAR(128)
SET CONNECTION statement, this item
contains the name of the server specified
in the statement.
Table 91. Data types for GET DIAGNOSTICS items that return connection information
Item Description Data type
DB2_AUTHENTICATION_TYPE This item contains the authentication type CHAR(1)
(S, C, D, E, or blank).
DB2_AUTHORIZATION_ID This item contains the authorization ID VARCHAR(128)
that is used by the connected server.
DB2_CONNECTION_STATE This item indicates whether the INTEGER
connection is unconnected (-1), local (0),
or remote (1).
Related reference
GET DIAGNOSTICS (Db2 SQL)
Procedure
Take action based on the programming language that you use.
• “Handling SQL error codes in assembler applications” on page 567
• “Handling SQL error codes in C and C++ applications” on page 615
• “Handling SQL error codes in Cobol applications” on page 681
• “Handling SQL error codes in Fortran applications” on page 690
• “Handling SQL error codes in PL/I applications” on page 700
• “Handling SQL error codes in REXX applications” on page 749
Related tasks
Displaying SQLCA fields by calling DSNTIAR
If you use the SQLCA to check whether an SQL statement executed successfully, your program needs to
read the data in the appropriate SQLCA fields. One easy way to read these fields is to use the assembler
subroutine DSNTIAR.
Checking the execution of SQL statements by using the GET DIAGNOSTICS statement
One way to check whether an SQL statement executed successfully is to ask Db2 to return the diagnostic
information about the last executed SQL statement.
Related reference
GET DIAGNOSTICS (Db2 SQL)
536 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Arithmetic and conversion errors
You can track arithmetic and conversion errors by using indicator variables. An indicator variable contains
a small integer value that indicates some information about the associated host variable.
Numeric or character conversion errors or arithmetic expression errors can set an indicator variable to
-2. For example, division by zero and arithmetic overflow do not necessarily halt the execution of a
SELECT statement. If you use indicator variables and an error occurs in the SELECT list, the statement can
continue to execute and return good data for rows in which the error does not occur.
For rows in which a conversion or arithmetic expression error does occur, the indicator variable indicates
that one or more selected items have no meaningful value. The indicator variable flags this error with a -2
for the affected host variable and an SQLCODE of +802 (SQLSTATE '01519') in the SQLCA.
Procedure
To create new tables:
• Use the CREATE TABLE statement.
To add columns or increase the length of columns:
• Use the ALTER TABLE statement with the ADD COLUMN clause or the ALTER COLUMN clause.
Added columns initially contain either the null value or a default value. Both CREATE TABLE and ALTER
TABLE, like any data definition statement, are relatively expensive to execute. Also consider the effects
of locks.
To drop columns:
• Use the ALTER TABLE statement with the DROP COLUMN clause.
Dropping a column from a table is a pending-definition change unless the table space is defined with
the DEFINE NO option. The column is not removed from the table until the REORG utility is run on
the table space. If you are planning on dropping a column from a table in addition to making other
changes to the table, make all changes that take effect immediately, prior to issuing the ALTER TABLE
statement with the DROP COLUMN clause.
To rearrange columns:
• Drop the table and create the table again, with the columns you want, in the order you want.
Consider creating a view on the table, which includes only the columns that you want, in the order that
you want, as an alternative to redefining the table.
Related tasks
Including dynamic SQL in your program
Dynamic SQL is prepared and executed while the program is running.
Related reference
ALTER TABLE (Db2 SQL)
CREATE TABLE (Db2 SQL)
CREATE VIEW (Db2 SQL)
Procedure
Save the corresponding SQL statements in a table with a column having a data type of VARCHAR(n),
where n is the maximum length of any SQL statement.
You must save the source SQL statements, not the prepared versions. That means that you must retrieve
and then prepare each statement before executing the version stored in the table. In essence, your
program prepares an SQL statement from a character string and executes it dynamically.
Related tasks
Including dynamic SQL in your program
Dynamic SQL is prepared and executed while the program is running.
Host variable data types for XML data in embedded SQL applications
Db2 provides XML host variable types for assembler, C, C++, COBOL, and PL/I.
Those types are:
• XML AS BLOB
• XML AS CLOB
• XML AS DBCLOB
• XML AS BLOB_FILE (C, C++, or PL/I) or XML AS BLOB-FILE (COBOL)
• XML AS CLOB_FILE (C, C++, or PL/I) or XML AS CLOB-FILE (COBOL)
538 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
• XML AS DBCLOB_FILE (C, C++, or PL/I) or XML AS DBCLOB-FILE (COBOL)
The XML host variable types are compatible only with the XML column data type.
You can use BLOB, CLOB, DBCLOB, CHAR, VARCHAR, GRAPHIC, VARGRAPHIC, BINARY, or VARBINARY
host variables to update XML columns. You can convert the host variable data types to the XML type using
the XMLPARSE function, or you can let the Db2 database server perform the conversion implicitly.
You can use BLOB, CLOB, DBCLOB, CHAR, VARCHAR, GRAPHIC, VARGRAPHIC, BINARY, or VARBINARY
host variables to retrieve data from XML columns. You can convert the XML data to the host variable
type using the XMLSERIALIZE function, or you can let the Db2 database server perform the conversion
implicitly.
The following examples show you how to declare XML host variables in each supported language. In
each table, the left column contains the declaration that you code in your application program. The right
column contains the declaration that Db2 generates.
Notes:
1. Because assembler language allows character declarations of no more than 65535 bytes, Db2 separates
the host language declarations for XML AS BLOB and XML AS CLOB host variables that are longer than
65535 bytes into two parts.
2. Because assembler language allows graphic declarations of no more than 65534 bytes, Db2 separates the
host language declarations for XML AS DBCLOB host variables that are longer than 65534 bytes into two
parts.
540 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Declarations of XML host variables in COBOL
The declarations that are generated for COBOL differ, depending on whether you use the Db2 precompiler
or the Db2 coprocessor.
The following table shows COBOL declarations that the Db2 precompiler generates for some typical XML
types.
Notes:
1. For XML AS BLOB or XML AS CLOB host variables that are greater than 32767 bytes in length, Db2 creates
multiple host language declarations of 32767 or fewer bytes.
2. For XML AS DBCLOB host variables that are greater than 32767 double-byte characters in length, Db2
creates multiple host language declarations of 32767 or fewer double-byte characters.
542 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 95. Examples of PL/I variable declarations (continued)
You declare this variable Db2 precompiler generates this variable
Notes:
1. For XML AS BLOB or XML AS CLOB host variables that are greater than 32767 bytes in length, Db2 creates
host language declarations in the following way:
• If the length of the XML is greater than 32767 bytes and evenly divisible by 32767, Db2 creates an array
of 32767-byte strings. The dimension of the array is length/32767.
• If the length of the XML is greater than 32767 bytes but not evenly divisible by 32767, Db2 creates
two declarations: The first is an array of 32767 byte strings, where the dimension of the array, n, is
length/32767. The second is a character string of length length-n*32767.
2. For XML AS DBCLOB host variables that are greater than 16383 double-byte characters in length, Db2
creates host language declarations in the following way:
• If the length of the XML is greater than 16383 characters and evenly divisible by 16383, Db2 creates an
array of 16383-character strings. The dimension of the array is length/16383.
• If the length of the XML is greater than 16383 characters but not evenly divisible by 16383, Db2 creates
two declarations: The first is an array of 16383 byte strings, where the dimension of the array, m, is
length/16383. The second is a character string of length length-m*16383.
Related concepts
Insertion of rows with XML column values (Db2 Programming for XML)
Retrieving XML data (Db2 Programming for XML)
**********************************************************************
* UPDATE AN XML COLUMN WITH DATA IN AN XML AS CLOB HOST VARIABLE *
**********************************************************************
EXEC SQL +
UPDATE MYCUSTOMER +
SET INFO = :XMLBUF +
WHERE CID = 1000
**********************************************************************
* UPDATE AN XML COLUMN WITH DATA IN AN XML AS BLOB HOST VARIABLE *
**********************************************************************
EXEC SQL +
UPDATE MYCUSTOMER +
SET INFO = :XMLBLOB +
WHERE CID = 1000
**********************************************************************
* UPDATE AN XML COLUMN WITH DATA IN A CLOB HOST VARIABLE. USE *
* THE XMLPARSE FUNCTION TO CONVERT THE DATA TO THE XML TYPE. *
**********************************************************************
EXEC SQL +
UPDATE MYCUSTOMER +
SET INFO = XMLPARSE(DOCUMENT :CLOBBUF) +
WHERE CID = 1000
…
LTORG
******************************
* HOST VARIABLE DECLARATIONS *
******************************
XMLBUF SQL TYPE IS XML AS CLOB 10K
XMLBLOB SQL TYPE IS XML AS BLOB 10K
CLOBBUF SQL TYPE IS CLOB 10K
Example
The following example shows a C language program that inserts data from XML AS BLOB, XML AS
CLOB, and CLOB host variables into an XML column. The XML AS BLOB data is inserted as binary data,
so the database server honors the internal encoding. The XML AS CLOB and CLOB data is inserted as
character data, so the database server honors the external encoding.
544 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
/******************************/
/* Host variable declarations */
/******************************/
EXEC SQL BEGIN DECLARE SECTION;
SQL TYPE IS XML AS CLOB( 10K ) xmlBuf;
SQL TYPE IS XML AS BLOB( 10K ) xmlblob;
SQL TYPE IS CLOB( 10K ) clobBuf;
EXEC SQL END DECLARE SECTION;
/******************************************************************/
/* Update an XML column with data in an XML AS CLOB host variable */
/******************************************************************/
EXEC SQL UPDATE MYCUSTOMER SET INFO = :xmlBuf where CID = 1000;
/******************************************************************/
/* Update an XML column with data in an XML AS BLOB host variable */
/******************************************************************/
EXEC SQL UPDATE MYCUSTOMER SET INFO = :xmlblob where CID = 1000;
/******************************************************************/
/* Update an XML column with data in a CLOB host variable. Use */
/* the XMLPARSE function to convert the data to the XML type. */
/******************************************************************/
EXEC SQL UPDATE MYCUSTOMER SET INFO = XMLPARSE(DOCUMENT :clobBuf) where CID = 1000;
Example
The following example shows a COBOL program that inserts data from XML AS BLOB, XML AS CLOB,
and CLOB host variables into an XML column. The XML AS BLOB data is inserted as binary data, so
the database server honors the internal encoding. The XML AS CLOB and CLOB data is inserted as
character data, so the database server honors the external encoding.
******************************
* Host variable declarations *
******************************
01 XMLBUF USAGE IS SQL TYPE IS XML as CLOB(10K).
01 XMLBLOB USAGE IS SQL TYPE IS XML AS BLOB(10K).
01 CLOBBUF USAGE IS SQL TYPE IS CLOB(10K).
*******************************************************************
* Update an XML column with data in an XML AS CLOB host variable *
*******************************************************************
EXEC SQL UPDATE MYCUSTOMER SET INFO = :XMLBUF where CID = 1000.
*******************************************************************
* Update an XML column with data in an XML AS BLOB host variable *
*******************************************************************
EXEC SQL UPDATE MYCUSTOMER SET INFO = :XMLBLOB where CID = 1000.
*******************************************************************
* Update an XML column with data in a CLOB host variable. Use *
* the XMLPARSE function to convert the data to the XML type. *
*******************************************************************
EXEC SQL UPDATE MYCUSTOMER SET INFO = XMLPARSE(DOCUMENT :CLOBBUF) where CID = 1000.
Example
The following example shows a PL/I program that inserts data from XML AS BLOB, XML AS CLOB,
and CLOB host variables into an XML column. The XML AS BLOB data is inserted as binary data, so
the database server honors the internal encoding. The XML AS CLOB and CLOB data is inserted as
character data, so the database server honors the external encoding.
/******************************/
/* Host variable declarations */
/******************************/
DCL
XMLBUF SQL TYPE IS XML AS CLOB(10K),
XMLBLOB SQL TYPE IS XML AS BLOB(10K),
CLOBBUF SQL TYPE IS CLOB(10K);
/*******************************************************************/
/* Update an XML column with data in an XML AS CLOB host variable */
/*******************************************************************/
EXEC SQL UPDATE MYCUSTOMER SET INFO = :XMLBUF where CID = 1000;
/*******************************************************************/
/* Update an XML column with data in an XML AS BLOB host variable */
/*******************************************************************/
EXEC SQL UPDATE MYCUSTOMER SET INFO = :XMLBLOB where CID = 1000;
/*******************************************************************/
/* Update an XML column with data in a CLOB host variable. Use */
/* the XMLPARSE function to convert the data to the XML type. */
/*******************************************************************/
EXEC SQL UPDATE MYCUSTOMER SET INFO = XMLPARSE(DOCUMENT :CLOBBUF) where CID = 1000;
**********************************************************************
* RETRIEVE XML COLUMN DATA INTO AN XML AS CLOB HOST VARIABLE *
**********************************************************************
EXEC SQL +
SELECT INFO +
INTO :XMLBUF +
FROM MYCUSTOMER +
WHERE CID = 1000
**********************************************************************
* RETRIEVE XML COLUMN DATA INTO AN XML AS BLOB HOST VARIABLE *
**********************************************************************
EXEC SQL +
SELECT INFO +
INTO :XMLBLOB +
FROM MYCUSTOMER +
WHERE CID = 1000
**********************************************************************
* RETRIEVE DATA FROM AN XML COLUMN INTO A CLOB HOST VARIABLE. *
* BEFORE SENDING THE DATA TO THE APPLICATION, INVOKE THE *
* XMLSERIALIZE FUNCTION TO CONVERT THE DATA FROM THE XML *
* TYPE TO THE CLOB TYPE. *
**********************************************************************
EXEC SQL +
SELECT XMLSERIALIZE(INFO AS CLOB(10K)) +
INTO :CLOBBUF +
FROM MYCUSTOMER +
WHERE CID = 1000
…
LTORG
******************************
* HOST VARIABLE DECLARATIONS *
******************************
XMLBUF SQL TYPE IS XML AS CLOB 10K
XMLBLOB SQL TYPE IS XML AS BLOB 10K
CLOBBUF SQL TYPE IS CLOB 10K
Example: The following example shows a C language program that retrieves data from an XML column
into XML AS BLOB, XML AS CLOB, and CLOB host variables. The data that is retrieved into an XML AS BLOB
546 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
host variable is retrieved as binary data, so the database server generates an XML declaration with UTF-8
encoding. The data that is retrieved into an XML AS CLOB host variable is retrieved as character data, so
the database server generates an XML declaration with an internal encoding declaration that is consistent
with the external encoding. The data that is retrieved into a CLOB host variable is retrieved as character
data, so the database server generates an XML declaration with an internal encoding declaration. That
declaration might not be consistent with the external encoding.
/******************************/
/* Host variable declarations */
/******************************/
EXEC SQL BEGIN DECLARE SECTION;
SQL TYPE IS XML AS CLOB( 10K ) xmlBuf;
SQL TYPE IS XML AS BLOB( 10K ) xmlBlob;
SQL TYPE IS CLOB( 10K ) clobBuf;
EXEC SQL END DECLARE SECTION;
/**********************************************************************/
/* Retrieve data from an XML column into an XML AS CLOB host variable */
/**********************************************************************/
EXEC SQL SELECT INFO INTO :xmlBuf from myTable where CID = 1000;
/**********************************************************************/
/* Retrieve data from an XML column into an XML AS BLOB host variable */
/**********************************************************************/
EXEC SQL SELECT INFO INTO :xmlBlob from myTable where CID = 1000;
/**********************************************************************/
/* RETRIEVE DATA FROM AN XML COLUMN INTO A CLOB HOST VARIABLE. */
/* BEFORE SENDING THE DATA TO THE APPLICATION, INVOKE THE */
/* XMLSERIALIZE FUNCTION TO CONVERT THE DATA FROM THE XML */
/* TYPE TO THE CLOB TYPE. */
/**********************************************************************/
EXEC SQL SELECT XMLSERIALIZE(INFO AS CLOB(10K))
INTO :clobBuf from myTable where CID = 1000;
Example: The following example shows a COBOL program that retrieves data from an XML column into
XML AS BLOB, XML AS CLOB, and CLOB host variables. The data that is retrieved into an XML AS BLOB
host variable is retrieved as binary data, so the database server generates an XML declaration with UTF-8
encoding. The data that is retrieved into an XML AS CLOB host variable is retrieved as character data, so
the database server generates an XML declaration with an internal encoding declaration that is consistent
with the external encoding. The data that is retrieved into a CLOB host variable is retrieved as character
data, so the database server generates an XML declaration with an internal encoding declaration. That
declaration might not be consistent with the external encoding.
******************************
* Host variable declarations *
******************************
01 XMLBUF USAGE IS SQL TYPE IS XML AS CLOB(10K).
01 XMLBLOB USAGE IS SQL TYPE IS XML AS BLOB(10K).
01 CLOBBUF USAGE IS SQL TYPE IS CLOB(10K).
**********************************************************************
* Retrieve data from an XML column into an XML AS CLOB host variable *
**********************************************************************
EXEC SQL SELECT INFO
INTO :XMLBUF
FROM MYTABLE
WHERE CID = 1000
END-EXEC.
**********************************************************************
* Retrieve data from an XML column into an XML AS BLOB host variable *
**********************************************************************
EXEC SQL SELECT INFO
INTO :XMLBLOB
FROM MYTABLE
WHERE CID = 1000
END-EXEC.
**********************************************************************
* RETRIEVE DATA FROM AN XML COLUMN INTO A CLOB HOST VARIABLE. *
* BEFORE SENDING THE DATA TO THE APPLICATION, INVOKE THE *
* XMLSERIALIZE FUNCTION TO CONVERT THE DATA FROM THE XML *
* TYPE TO THE CLOB TYPE. *
**********************************************************************
EXEC SQL SELECT XMLSERIALIZE(INFO AS CLOB(10K))
INTO :CLOBBUF
FROM MYTABLE
WHERE CID = 1000
END-EXEC.
/******************************/
/* Host variable declarations */
/******************************/
DCL
XMLBUF SQL TYPE IS XML AS CLOB(10K),
XMLBLOB SQL TYPE IS XML AS BLOB(10K),
CLOBBUF SQL TYPE IS CLOB(10K);
/**********************************************************************/
/* Retrieve data from an XML column into an XML AS CLOB host variable */
/**********************************************************************/
EXEC SQL SELECT INFO INTO :XMLBUF FROM MYTABLE WHERE CID = 1000;
/**********************************************************************/
/* Retrieve data from an XML column into an XML AS BLOB host variable */
/**********************************************************************/
EXEC SQL SELECT INFO INTO :XMLBLOB FROM MYTABLE WHERE CID = 1000;
/**********************************************************************/
/* RETRIEVE DATA FROM AN XML COLUMN INTO A CLOB HOST VARIABLE. */
/* BEFORE SENDING THE DATA TO THE APPLICATION, INVOKE THE */
/* XMLSERIALIZE FUNCTION TO CONVERT THE DATA FROM THE XML */
/* TYPE TO THE CLOB TYPE. */
/**********************************************************************/
EXEC SQL SELECT XMLSERIALIZE(INFO AS CLOB(10K))
INTO :CLOBBUF FROM MYTABLE WHERE CID = 1000;
Comments
You cannot include assembler comments in SQL statements. However, you can include SQL
comments in any embedded SQL statement. For more information, see SQL comments (Db2 SQL).
Continuation for SQL statements
The line continuation rules for SQL statements are the same as those for assembler statements,
except that you must specify EXEC SQL within one line. Any part of the statement that does not fit
on one line can appear on subsequent lines, beginning at the continuation margin (column 16, the
548 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
default). Every line of the statement, except the last, must have a continuation character (a non-blank
character) immediately after the right margin in column 72.
Delimiters for SQL statements
Delimit an SQL statement in your assembler program with the beginning keyword EXEC SQL and an
end of line or end of last continued line.
Declaring tables and views
Your assembler program should include a DECLARE statement to describe each table and view the
program accesses.
Including code
To include SQL statements or assembler host variable declaration statements from a member of a
partitioned data set, place the following SQL statement in the source code where you want to include
the statements:
DFHEISTG DSECT
DFHEISTG
EXEC SQL INCLUDE SQLCA
*
DS 0F
SQDWSREG EQU R7
SQDWSTOR DS (SQLDLEN)C RESERVE STORAGE TO BE USED FOR SQLDSECT
In this example, the actual storage allocation is done by the DFHEIENT macro.
TSO: The sample program in prefix.SDSNSAMP(DSNTIAD) contains an example of how to acquire
storage for the SQLDSECT in a program that runs in a TSO environment. The following example code
contains pieces from prefix.SDSNSAMP(DSNTIAD) with explanations in the comments.
550 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
• Generated code uses registers 0, 1, 14, and 15. Register 13 points to a save area that the called
program uses. Register 15 does not contain a return code after a call that is generated by an SQL
statement.
CICS: A CICS application program uses the DFHEIENT macro to generate the entry point code.
When using this macro, consider the following:
– If you use the default DATAREG in the DFHEIENT macro, register 13 points to the save area.
– If you use any other DATAREG in the DFHEIENT macro, you must provide addressability to a save
area.
For example, to use SAVED, you can code instructions to save, load, and restore register 13
around each SQL statement as in the following example.
• If you have an addressability error in precompiler-generated code because of input or output host
variables in an SQL statement, check to make sure that you have enough base registers.
• Do not put CICS translator options in the assembly source code. Instead, pass the options to the
translator by using the PARM field.
Handling SQL error codes
Assembler applications can request more information about SQL errors from Db2. For more
information, see “Handling SQL error codes in assembler applications” on page 567.
Related tasks
Overview of programming applications that access Db2 for z/OS data
Applications that interact with Db2 must first connect to Db2. They can then read, add, or modify data or
manipulate Db2 objects.
Including dynamic SQL in your program
Dynamic SQL is prepared and executed while the program is running.
Setting limits for system resource usage by using the resource limit facility (Db2 Performance)
Procedure
Choose one of the following actions:
Option Description
To define the SQL a. Code the SQLCA directly in the program or use the following SQL INCLUDE
communications statement to request a standard SQLCA declaration:
area:
EXEC SQL INCLUDE SQLCA
If your program is reentrant, you must include the SQLCA within a unique
data area that is acquired for your task (a DSECT). For example, at the
beginning of your program, specify the following code:
PROGAREA DSECT
EXEC SQL INCLUDE SQLCA
As an alternative, you can create a separate storage area for the SQLCA and
provide addressability to that area.
Db2 sets the SQLCODE and SQLSTATE values in the SQLCA after each SQL
statement executes. Your application should check these values to determine
whether the last SQL statement was successful.
To declare SQLCODE a. Declare the SQLCODE variable within a BEGIN DECLARE SECTION statement
and SQLSTATE host and an END DECLARE SECTION statement in your program declarations as a
variables: fullword integer.
b. Declare the SQLSTATE variable within a BEGIN DECLARE SECTION statement
and an END DECLARE SECTION statement in your program declarations as a
character string of length 5 (CL5).
Restriction: Do not declare an SQLSTATE variable as an element of a structure.
Requirement: After you declare the SQLCODE and SQLSTATE variables, ensure
that all SQL statements in the program are within the scope of the declaration of
these variables.
Related tasks
Checking the execution of SQL statements
After executing an SQL statement, your program should check for any errors before you commit the data
and handle the errors that they represent.
Checking the execution of SQL statements by using the SQLCA
One way to check whether an SQL statement executed successfully is to use the SQL communication area
(SQLCA). This area is set apart for communication with Db2.
Checking the execution of SQL statements by using SQLCODE and SQLSTATE
Whenever an SQL statement executes, the SQLCODE and SQLSTATE fields of the SQLCA receive a return
code.
Defining the items that your program can use to check whether an SQL statement executed successfully
If your program contains SQL statements, the program should define some infrastructure so that it can
check whether the statements executed successfully. You can either include an SQL communications
552 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
area (SQLCA), which contains SQLCODE and SQLSTATE variables, or declare individual SQLCODE and
SQLSTATE host variables.
Procedure
Code the SQLDA directly in the program, or use the following SQL INCLUDE statement to request a
standard SQLDA declaration:
Restriction: You must place SQLDA declarations before the first SQL statement that references the data
descriptor, unless you use the TWOPASS SQL processing option.
Example
You can use host-variable arrays for certain multi-row operations in other host languages, such C, C++,
COBOL, and PL/I. but the Db2 precompiler does not recognize declarations of host-variable arrays for
assembler. However, you can SQLDA declarations to achieve similar results in assembler programs, as
shown in the following examples:
• Assembler support for multiple-row FETCH is limited to the FETCH statement with the INTO
DESCRIPTOR clause. For example:
– Dynamic multiple-row INSERT executed with the USING DESCRIPTOR clause on the EXECUTE
statement. For example:
– Assembler does not support multiple-row MERGE. You cannot specify MERGE statements that
reference host-variable arrays.
Related tasks
Defining SQL descriptor areas (SQLDA)
If your program includes certain SQL statements, you must define at least one SQL descriptor area
(SQLDA). Depending on the context in which it is used, the SQLDA stores information about prepared SQL
statements or host variables. This information can then be read by either the application program or Db2.
Related reference
SQL descriptor area (SQLDA) (Db2 SQL)
Procedure
To declare host variables, host-variable arrays, and host structures:
1. Declare the variables according to the following rules and guidelines:
• You can declare host variables in normal assembler style (DC or DS), depending on the data type and
the limitations on that data type. You can specify a value on DC or DS declarations (for example, DC
H'5'). The Db2 precompiler examines only packed decimal declarations.
• If you specify the ONEPASS SQL processing option, you must explicitly declare each host variable
and each host-variable array before using them in an SQL statement. If you specify the TWOPASS
precompiler option, you must declare each host variable before using it in the DECLARE CURSOR
statement.
• If you specify the STDSQL(YES) SQL processing option, you must precede the host language
statements that define the host variables and host-variable arrays with the BEGIN DECLARE
SECTION statement and follow the host language statements with the END DECLARE SECTION
statement. Otherwise, these statements are optional.
• Ensure that any SQL statement that uses a host variable or host-variable array is within the scope of
the statement that declares that variable or array.
• If you are using the Db2 precompiler, ensure that the names of host variables and host-variable
arrays are unique within the program, even if the variables and variable arrays are in different blocks,
classes, procedures, functions, or subroutines. You can qualify the names with a structure name to
make them unique.
2. Optional: Define any associated indicator variables, arrays, and structures.
Related tasks
Declaring host variables and indicator variables
You can use host variables and indicator variables in SQL statements in your program to pass data
between Db2 and your application.
554 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Numeric host variables
The following diagram shows the syntax for declaring numeric host variables.
variable-name DC H
DS 1 L2
F
L4
FD
L8
1
P 'value '
Ln
E
L4
EH
L4
EB
L4
ED
L4
D
L8
DH
L8
DB
L8
DD
L8
LD
L16
Notes:
1 value is a numeric value that specifies the scale of the packed decimal variable. If value does not include
a decimal point, the scale is 0.
For floating-point data types (E, EH, EB, D, DH, and DB), use the FLOAT SQL processing option to specify
whether the host variable is in IEEE binary floating-point or z/Architecture® hexadecimal floating-point
format. If you specify FLOAT(S390), you need to define your floating-point host variables as E, EH, D,
or DH. If you specify FLOAT(IEEE), you need to define your floating-point host variables as EB or DB.
Db2 does not check if the host variable declarations or format of the host variable contents match the
format that you specified with the FLOAT SQL processing option. Therefore, you need to ensure that your
floating-point host variable types and contents match the format that you specified with the FLOAT SQL
processing option. Db2 converts all floating-point input data to z/Architecture hexadecimal floating-point
format before storing it.
Restriction: The FLOAT SQL processing options do not apply to the decimal floating-point host variable
types ED, DD, or LD.
For the decimal floating-point host variable types ED, DD, and LD, you can specify the following special
values: MIN, MAX, NAN, SNAN, and INFINITY.
variable-name DC C
DS 1 1
Ln
Notes:
1 If you declare a character string host variable without a length (for example, DC C 'ABCD') Db2
interprets the length as 1. To get the correct length, specify a length attribute (for example, DC CL 4
'ABCD').
The following diagram shows the syntax for declaring varying-length character strings.
variable-name DC H , CL n
DS 1 L2 1
variable-name DC G
DS Ln
'<value >'
Ln'<value >'
The following diagram shows the syntax for declaring varying-length graphic strings.
variable-name DS H , GL n
556 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
1
variable-name DS X Ln
Notes:
1 1 ≤ n ≤ 255
1
variable-name DS H L2 , X Ln
Notes:
1 1 ≤ n ≤ 32704
1
variable-name SQL TYPE IS RESULT_SET_LOCATOR VARYING
Notes:
1 To be compatible with previous releases, result set locator host variables may be declared as fullword
integers (FL4), but the method shown is the preferred syntax.
Table Locators
The following diagram shows the syntax for declaring of table locators.
BLOB K
CLOB
DBCLOB
BLOB_LOCATOR
CLOB_LOCATOR
DBCLOB_LOCATOR
BLOB_FILE
CLOB_FILE
DBCLOB_FILE
1
BINARY LARGE OBJECT length
BLOB K
CLOB
DBCLOB
BLOB_FILE
CLOB_FILE
DBCLOB_FILE
Notes:
1If you specify the length of the LOB in terms of KB, MB, or GB, do not leave spaces between the length
and K, M, or G.
ROWIDs
The following diagram shows the syntax for declaring ROWID host variables.
Related concepts
Host variables
558 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Use host variables to pass a single data item between Db2 and your application.
Using host variables in SQL statements
Use scalar host variables in embedded SQL statements to represent a single value. Host variables are
useful for storing retrieved data or for passing values that are to be assigned or used for comparisons.
Related tasks
Determining whether a retrieved value in a host variable is null or truncated
Before your application manipulates the data that was retrieved from Db2 into a host variable, determine
if the value is null. Also determine if it was truncated when assigned to the variable. You can use indicator
variables to obtain this information.
Inserting a single row by using a host variable
Use host variables in your INSERT statement when you don't know at least some of the values to insert
until the program runs.
Inserting null values into columns by using indicator variables or arrays
If you need to insert null values into a column, using an indicator variable or array is an easy way to do so.
An indicator variable or array is associated with a particular host variable or host-variable array.
Storing LOB data in a table
Db2 handles LOB data differently than it handles other kinds of data. As a result, in some cases, you need
to take additional actions when you define LOB columns and insert the LOB data.
Retrieving a single row of data into host variables
If you know that your query returns only one row, you can specify one or more host variables to contain
the column values of the retrieved row.
Updating data by using host variables
When you want to update a value in a Db2 table, but you do not know the exact value until the program
runs, use host variables. Db2 can change a table value to match the current value of the host variable.
Related reference
Descriptions of SQL processing options
You can specify any SQL processing options regardless of whether you use the Db2 precompiler or the
Db2 coprocessor. However, the Db2 coprocessor might ignore certain options because host language
compiler options exist that provide the same information.
High Level Assembler (HLASM) and Toolkit Feature Library
variable-name DC H
DS 1 L2
Example
The following example shows a FETCH statement with the declarations of the host variables that are
needed for the FETCH statement and their associated indicator variables.
CLSCD DS CL7
DAY DS HL2
Related concepts
Indicator variables, arrays, and structures
An indicator variable is associated with a particular host variable. Each indicator variable contains a small
integer value that indicates some information about the associated host variable. Indicator arrays and
structures serve the same purpose for host-variable arrays and structures.
Related tasks
Inserting null values into columns by using indicator variables or arrays
If you need to insert null values into a column, using an indicator variable or array is an easy way to do so.
An indicator variable or array is associated with a particular host variable or host-variable array.
Table 96. SQL data types, SQLLEN values, and SQLTYPE values that the precompiler uses for host variables in
assembler programs
Assembler host variable data type SQLTYPE of host SQLLEN of SQL data type
variable1 host variable
500 2
DS HL2 SMALLINT
496 4
DS FL4 INTEGER
484 p in byte 1, s
DS P'value' DECIMAL(p,s)
DS PLn'value' or in byte 2
DS PLn
1<=n<=16
480 4
DS EL4 REAL or FLOAT (n)
DS EHL4 1<=n<=21
DS EBL4
560 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 96. SQL data types, SQLLEN values, and SQLTYPE values that the precompiler uses for host variables in
assembler programs (continued)
Assembler host variable data type SQLTYPE of host SQLLEN of SQL data type
variable1 host variable
480 8
DS DL8 DOUBLE PRECISION,
DS DHL8 or FLOAT (n)
DS DBL8 22<=n<=53
492 8
DS FDL8 BIGINT
DS FD
912 n
SQL TYPE IS BINARY(n) BINARY(n)
1<=n<=255
908 n
SQL TYPE IS VARBINARY(n) or VARBINARY(n)
SQL TYPE IS BINARY(n) VARYING
1<=n<=32704
452 n
DS CLn CHAR(n)
1<=n<=255
448 n
DS HL2,CLn VARCHAR(n)
1<=n<=255
456 n
DS HL2,CLn VARCHAR(n)
n>255
468 n
DS GLm GRAPHIC(n)
2<=m<=254
3
2
464 n
DS HL2,GLm VARGRAPHIC(n)
2<=m<=254
3
2
472 n
DS HL2,GLm VARGRAPHIC(n)
m>254
3
2
972 4
SQL TYPE IS RESULT_SET_LOCATOR Result set locator4,5
976 4
SQL TYPE IS Table locator4
TABLE LIKE
table-name
AS LOCATOR
960 4
SQL TYPE IS BLOB locator4
BLOB_LOCATOR
964 4
SQL TYPE IS CLOB locator4
CLOB_LOCATOR
404 n
SQL TYPE IS BLOB(n)
BLOB(n)
1≤n≤2147483647
408 n
SQL TYPE IS CLOB(n)
CLOB(n)
1≤n≤2147483647
412 n
SQL TYPE IS DBCLOB(n)
DBCLOB(n)
1≤n≤1073741823 3
404 0
SQL TYPE IS XML AS BLOB(n) XML
408 0
SQL TYPE IS XML AS CLOB(n) XML
412 0
SQL TYPE IS XML AS DBCLOB(n) XML
916/917 267 4
SQL TYPE IS BLOB_FILE BLOB file reference
920/921 267 4
SQL TYPE IS CLOB_FILE CLOB file reference
924/925 267 4
SQL TYPE IS DBCLOB_FILE DBCLOB file reference
916/917 267 4
SQL TYPE IS XML AS BLOB_FILE XML BLOB file reference
920/921 267 4
SQL TYPE IS XML AS CLOB_FILE XML CLOB file reference
924/925 267 4
SQL TYPE IS XML AS DBCLOB_FILE XML DBCLOB file reference
904 40
SQL TYPE IS ROWID ROWIDnote 5
Notes:
1. If a host variable includes an indicator variable, the SQLTYPE value is the base SQLTYPE value plus 1.
2. m is the number of bytes.
3. n is the number of double-byte characters.
4. This data type cannot be used as a column type.
5. To be compatible with previous releases, result set locator host variables may be declared as fullword
integers (FL4), but the method shown is the preferred syntax.
562 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
The following table shows equivalent assembler host variables for each SQL data type. Use this table to
determine the assembler data type for host variables that you define to receive output from the database.
For example, if you retrieve TIMESTAMP data, you can define variable DS CLn.
This table shows direct conversions between SQL data types and assembler data types. However, a
number of SQL data types are compatible. When you do assignments or comparisons of data that have
compatible data types, Db2 converts those compatible data types.
Table 97. Assembler host variable equivalents that you can use when retrieving data of a particular SQL
data type
SQL data type Assembler host variable Notes
equivalent
SMALLINT DS HL2
INTEGER DS F
BIGINT DS FD OR DS FDL8 DS FDL8 requires High Level Assembler
(HLASM), Release 4 or later.
DECIMAL(p,s) or DS P'value' DS PLn'value' DS p is precision; s is scale. 1<=p<=31 and
NUMERIC(p,s) PLn 0<=s<=p. 1<=n<=16. value is a literal value that
includes a decimal point. You must use Ln, value,
or both. Using only value is recommended.
Precision: If you use Ln, it is 2n-1; otherwise, it
is the number of digits in value. Scale: If you use
value, it is the number of digits to the right of the
decimal point; otherwise, it is 0.
For efficient use of indexes: Use value. If p is
even, do not use Ln and be sure the precision
of value is p and the scale of value is s. If p is
odd, you can use Ln (although it is not advised),
but you must choose n so that 2n-1=p, and value
so that the scale is s. Include a decimal point in
value, even when the scale of value is 0.
564 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 97. Assembler host variable equivalents that you can use when retrieving data of a particular SQL
data type (continued)
SQL data type Assembler host variable Notes
equivalent
BLOB(n) SQL TYPE IS BLOB(n) 1≤n≤2147483647
CLOB(n) SQL TYPE IS CLOB(n) 1≤n≤2147483647
DBCLOB(n) SQL TYPE IS DBCLOB(n) n is the number of double-byte characters.
1≤n≤1073741823
XML SQL TYPE IS XML AS 1≤n≤2147483647
BLOB(n)
XML SQL TYPE IS XML AS 1≤n≤2147483647
CLOB(n)
XML SQL TYPE IS XML AS n is the number of double-byte characters.
DBCLOB(n) 1≤n≤1073741823
BLOB file reference SQL TYPE IS BLOB_FILE Use this data type only to manipulate data in
BLOB columns. Do not use this data type as a
column type.
CLOB file reference SQL TYPE IS CLOB_FILE Use this data type only to manipulate data in
CLOB columns. Do not use this data type as a
column type.
DBCLOB file reference SQL TYPE IS DBCLOB_FILE Use this data type only to manipulate data in
DBCLOB columns. Do not use this data type as a
column type.
XML BLOB file SQL TYPE IS XML AS Use this data type only to manipulate XML data
reference BLOB_FILE as BLOB files. Do not use this data type as a
column type.
XML CLOB file SQL TYPE IS XML AS Use this data type only to manipulate XML data
reference CLOB_FILE as CLOB files. Do not use this data type as a
column type.
XML DBCLOB file SQL TYPE IS XML AS Use this data type only to manipulate XML data
reference DBCLOB_FILE as DBCLOB files. Do not use this data type as a
column type.
ROWID SQL TYPE IS ROWID
Notes:
1. Although stored procedures and user-defined functions can use IEEE floating-point host variables,
you cannot declare a user-defined function or stored procedure parameter as IEEE.
The following table shows the assembler language definitions to use in assembler stored procedures and
user-defined functions, when the parameter data types in the routine definitions are LOBs, ROWIDs, or
locators. For other parameter data types, the assembler language definitions are the same as those in
Table 97 on page 563 above.
var DS 0FL4
var_length DS FL4
var_data DS CLn
If n > 65535:
var DS 0FL4
var_length DS FL4
var_data DS CL65535
ORG var_data+(n-65535)
var DS 0FL4
var_length DS FL4
var_data DS CLn
If n > 65535:
var DS 0FL4
var_length DS FL4
var_data DS CL65535
ORG var_data+(n-65535)
var DS 0FL4
var_length DS FL4
var_data DS CLm
If n > 65534:
var DS 0FL4
var_length DS FL4
var_data DS CL65534
ORG var_data+(m-65534)
ROWID DS HL2,CL40
Related concepts
Compatibility of SQL and language data types
The host variable data types that are used in SQL statements must be compatible with the data types of
the columns with which you intend to use them.
LOB host variable, LOB locator, and LOB file reference variable declarations
When you write applications to manipulate LOB data, you need to declare host variables to hold the LOB
data or LOB locator. Alternatively, you need to declare LOB file reference variables to point to the LOB
data.
Host variable data types for XML data in embedded SQL applications (Db2 Programming for XML)
566 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Macros for assembler applications
Data set DSN1210.SDSNMACS contains all Db2 macros that are available for use.
Procedure
To request information about SQL errors in assembler programs, use the following approaches:
• You can use the subroutine DSNTIAR to convert an SQL return code into a text message.
DSNTIAR takes data from the SQLCA, formats it into a message, and places the result in a message
output area that you provide in your application program. For concepts and more information about the
behavior of DSNTIAR, see “Displaying SQLCA fields by calling DSNTIAR” on page 525.
DSNTIAR syntax
DSNTIAR has the following syntax:
DSNTIAR parameters
The DSNTIAR parameters have the following meanings:
sqlca
An SQL communication area.
message
An output area, defined as a varying-length string, in which DSNTIAR places the message text.
The first halfword contains the length of the remaining area; its minimum value is 240.
The output lines of text, each line being the length specified in lrecl, are put into this area. For
example, you could specify the format of the output area as:
LINES EQU 10
LRECL EQU 132
⋮
MSGLRECL DC AL4(LRECL)
MESSAGE DS H,CL(LINES*LRECL)
ORG MESSAGE
MESSAGEL DC AL2(LINES*LRECL)
MESSAGE1 DS CL(LRECL) text line 1
MESSAGE2 DS CL(LRECL) text line 2
⋮
MESSAGEn DS CL(LRECL) text line n
⋮
CALL DSNTIAR,(SQLCA,MESSAGE,MSGLRECL),MF=(E,PARM)
where MESSAGE is the name of the message output area, LINES is the number of lines in the
message output area, and LRECL is the length of each line.
lrecl
A fullword containing the logical record length of output messages, between 72 and 240.
The expression MF=(E,PARM) is an z/OS macro parameter that indicates dynamic execution. PARM is
the name of a data area that contains a list of pointers to the call parameters of DSNTIAR.
See “Sample applications supplied with Db2 for z/OS” on page 1022 for instructions on how to access
and print the source code for the sample program.
• If your CICS application requires CICS storage handling, you must use the subroutine DSNTIAC instead
of DSNTIAR.
DSNTIAC syntax
DSNTIAC has the following syntax:
DSNTIAC parameters
DSNTIAC has extra parameters, which you must use for calls to routines that use CICS commands.
eib
EXEC interface block
commarea
communication area
For more information on these parameters, see the appropriate application programming guide for
CICS. The remaining parameter descriptions are the same as those for DSNTIAR. Both DSNTIAC
and DSNTIAR format the SQLCA in the same way.
You must define DSNTIA1 in the CSD. If you load DSNTIAR or DSNTIAC, you must also define them
in the CSD. For an example of CSD entry generation statements for use with DSNTIAC, see member
DSN8FRDO in the data set prefix.SDSNSAMP.
The assembler source code for DSNTIAC and job DSNTEJ5A, which assembles and link-edits
DSNTIAC, are also in the data set prefix.SDSNSAMP.
• You can also use the MESSAGE_TEXT condition item field of the GET DIAGNOSTICS statement to
convert an SQL return code into a text message.
Programs that require long token message support should code the GET DIAGNOSTICS statement
instead of DSNTIAR. For more information about GET DIAGNOSTICS, see “Checking the execution of
SQL statements by using the GET DIAGNOSTICS statement ” on page 530.
Related tasks
Handling SQL error codes
Application programs can request more information about SQL error codes from Db2.
Related reference
GET DIAGNOSTICS (Db2 SQL)
EXEC SQL
UPDATE DSN8C10.DEPT
SET MGRNO = :mgr_num
WHERE DEPTNO = :int_dept;
Comments
You can include C comments (/* ... */) within SQL statements wherever you can use a blank, except
between the keywords EXEC and SQL. You can use single-line comments (starting with //) in C
language statements, but not in embedded SQL. You can use SQL comments within embedded SQL
statements. For more information, see SQL comments (Db2 SQL).
You can nest comments.
568 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
To include EBCDIC DBCS characters in comments, you must delimit the characters by a shift-out and
shift-in control character; the first shift-in character in the DBCS string signals the end of the DBCS
string.
Continuation for SQL statements
You can use a backslash to continue a character-string constant or delimited identifier on the
following line. However, EBCDIC DBCS string constants cannot be continued on a second line.
Delimiters
Delimit an SQL statement in your C program with the beginning keyword EXEC SQL and a Semicolon
(;).
Declaring tables and views
Your C program should use the DECLARE TABLE statement to describe each table and view the
program accesses. You can use the Db2 declarations generator (DCLGEN) to generate the DECLARE
TABLE statements. For more information, see “DCLGEN (declarations generator)” on page 460.
Including SQL statements and variable declarations in source code that is to be processed by the Db2
precompiler
To include SQL statements or C host variable declarations from a member of a partitioned data set,
add the following SQL statement to the source code where you want to include the statements:
You cannot nest SQL INCLUDE statements. Do not use C #include statements to include SQL
statements or C host variable declarations.
Margins
Code SQL statements in columns 1 through 72, unless you specify other margins to the Db2
precompiler. If EXEC SQL is not within the specified margins, the Db2 precompiler does not recognize
the SQL statement. The margin rules do not apply to the Db2 coprocessor. The Db2 coprocessor
allows variable length source input.
Names
You can use any valid C name for a host variable, subject to the following restrictions:
• Do not use DBCS characters.
• Do not use external entry names or access plan names that begin with 'DSN', and do not use host
variable names or macro names that begin with 'SQL' (in any combination of uppercase or lowercase
letters). These names are reserved for Db2.
An SQL identifier that starts with the pound character ('#') can be interpreted as a C macro statement.
Nulls and NULs
C and SQL differ in the way they use the word null. The C language has a null character (NUL), a null
pointer (NULL), and a null statement (just a semicolon). The C NUL is a single character that compares
equal to 0. The C NULL is a special reserved pointer value that does not point to any valid data object.
The SQL null value is a special value that is distinct from all non-null values and denotes the absence
of a (nonnull) value. NUL (or NUL-terminator) is the null character in C and C++, and NULL is the SQL
null value.
Sequence numbers
The Db2 precompiler generates statements without sequence numbers. (The Db2 coprocessor does
not perform this action, because the source is read and modified by the compiler. )
Statement labels
You can precede SQL statements with a label.
Trigraph characters
Some characters from the C character set are not available on all keyboards. You can enter these
characters into a C source program using a sequence of three characters called a trigraph. The
trigraph characters that Db2 supports are the same as those that the C compiler supports.
570 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Related reference
Assembler, C, C++, COBOL, PL/I, and REXX programming examples (Db2 Programming samples)
/*********************************************************************/
/* Descriptive name = Dynamic SQL sample using C language */
/* */
/* Function = To show examples of the use of dynamic and static */
/* SQL. */
/* */
/* Notes = This example assumes that the EMP and DEPT tables are */
/* defined. They need not be the same as the DB2 Sample */
/* tables. */
/* */
/* Module type = C program */
/* Processor = DB2 precompiler, C compiler */
/* Module size = see link edit */
/* Attributes = not reentrant or reusable */
/* */
/* Input = */
/* */
/* symbolic label/name = DEPT */
/* description = arbitrary table */
/* symbolic label/name = EMP */
/* description = arbitrary table */
/* */
/* Output = */
/* */
/* symbolic label/name = SYSPRINT */
/* description = print results via printf */
/* */
/* Exit-normal = return code 0 normal completion */
/* */
/* Exit-error = */
/* */
/* Return code = SQLCA */
/* */
/* Abend codes = none */
/* */
/* External references = none */
/* */
/* Control-blocks = */
/* SQLCA - sql communication area */
/* */
/* Logic specification: */
/* */
/* There are four SQL sections. */
/* */
/* 1) STATIC SQL 1: using static cursor with a SELECT statement. */
/* Two output host variables. */
/* 2) Dynamic SQL 2: Fixed-list SELECT, using same SELECT statement */
/* used in SQL 1 to show the difference. The prepared string */
/* :iptstr can be assigned with other dynamic-able SQL statements.*/
/* 3) Dynamic SQL 3: Insert with parameter markers. */
/* Using four parameter markers which represent four input host */
/* variables within a host structure. */
/* 4) Dynamic SQL 4: EXECUTE IMMEDIATE */
/* A GRANT statement is executed immediately by passing it to DB2 */
/* via a varying string host variable. The example shows how to */
/* set up the host variable before passing it. */
/* */
/*********************************************************************/
#include "stdio.h"
#include "stdefs.h"
EXEC SQL INCLUDE SQLCA;
EXEC SQL INCLUDE SQLDA;
EXEC SQL BEGIN DECLARE SECTION;
short edlevel;
572 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
printf("??/n*** begin declare ***");
EXEC SQL DECLARE C2 CURSOR FOR STAT1;
printf("??/n*** begin open ***");
EXEC SQL OPEN C2;
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
main()
{
/************************************************************/
/* Include the SQLCA and SQLDA */
/************************************************************/
EXEC SQL INCLUDE SQLCA;
EXEC SQL INCLUDE SQLDA;
/************************************************************/
/* Declare variables that are not SQL-related. */
/*************************************************************/
/* Allocate the SQLDAs to be used for DESCRIBE */
/* PROCEDURE and DESCRIBE CURSOR. Assume that at most */
/* three cursors are returned and that each result set */
/* has no more than five columns. */
/*************************************************************/
proc_da = (struct sqlda *)malloc(SQLDASIZE(3));
res_da = (struct sqlda *)malloc(SQLDASIZE(5));
/************************************************************/
/* Call the GETPRML stored procedure to retrieve the */
/* RUNOPTS values for the stored procedure. In this */
/* example, we request the PARMLIST definition for the */
/* stored procedure named DSN8EP2. */
/* */
/* The call should complete with SQLCODE +466 because */
/* GETPRML returns result sets. */
/************************************************************/
strcpy(procnm,"dsn8ep2 ");
/* Input parameter -- PROCEDURE to be found */
strcpy(schema," ");
/* Input parameter -- Schema name for proc */
parmind.procnm_ind=0;
parmind.schema_ind=0;
parmind.out_code_ind=0;
/* Indicate that none of the input parameters */
/* have null values */
parmind.parmlst_ind=-1;
/* The parmlst parameter is an output parm. */
/* Mark PARMLST parameter as null, so the DB2 */
/* requester does not have to send the entire */
/* PARMLST variable to the server. This */
/* helps reduce network I/O time, because */
/* PARMLST is fairly large. */
EXEC SQL
CALL GETPRML(:procnm INDICATOR :parmind.procnm_ind,
:schema INDICATOR :parmind.schema_ind,
:out_code INDICATOR :parmind.out_code_ind,
:parmlst INDICATOR :parmind.parmlst_ind);
if(SQLCODE!=+466) /* If SQL CALL failed, */
{
/* print the SQLCODE and any */
/* message tokens */
printf("SQL CALL failed due to SQLCODE = %d\n",
sqlca.sqlcode);
574 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
printf("sqlca.sqlerrmc = ");
for(i=0;i<sqlca.sqlerrml;i++)
printf("%c",sqlca.sqlerrmc[i]);
printf("\n");
}
/********************************************************/
/* Use the statement DESCRIBE PROCEDURE to */
/* return information about the result sets in the */
/* SQLDA pointed to by proc_da: */
/* - SQLD contains the number of result sets that were */
/* returned by the stored procedure. */
/* - Each SQLVAR entry has the following information */
/* about a result set: */
/* - SQLNAME contains the name of the cursor that */
/* the stored procedure uses to return the result */
/* set. */
/* - SQLIND contains an estimate of the number of */
/* rows in the result set. */
/* - SQLDATA contains the result locator value for */
/* the result set. */
/********************************************************/
EXEC SQL DESCRIBE PROCEDURE INTO :*proc_da;
/********************************************************/
/* Assume that you have examined SQLD and determined */
/* that there is one result set. Use the statement */
/* ASSOCIATE LOCATORS to establish a result set locator */
/* for the result set. */
/********************************************************/
EXEC SQL ASSOCIATE LOCATORS (:loc1) WITH PROCEDURE GETPRML;
/********************************************************/
/* Use the statement ALLOCATE CURSOR to associate a */
/* cursor for the result set. */
/********************************************************/
EXEC SQL ALLOCATE C1 CURSOR FOR RESULT SET :loc1;
/********************************************************/
/* Use the statement DESCRIBE CURSOR to determine the */
/* columns in the result set. */
/********************************************************/
EXEC SQL DESCRIBE CURSOR C1 INTO :*res_da;
/********************************************************/
/* Call a routine (not shown here) to do the following: */
/* - Allocate a buffer for data and indicator values */
/* fetched from the result table. */
/* - Update the SQLDATA and SQLIND fields in each */
/* SQLVAR of *res_da with the addresses at which to */
/* to put the fetched data and values of indicator */
/* variables. */
/********************************************************/
alloc_outbuff(res_da);
/********************************************************/
/* Fetch the data from the result table. */
/********************************************************/
while(SQLCODE==0)
EXEC SQL FETCH C1 USING DESCRIPTOR :*res_da;
}
return;
}
#pragma runopts(plist(os))
#include <stdlib.h>
/***************************************************************/
/* Declare C variables for SQL operations on the parameters. */
/* These are local variables to the C program, which you must */
/* copy to and from the parameter list provided to the stored */
/* procedure. */
/***************************************************************/
EXEC SQL BEGIN DECLARE SECTION;
char PROCNM[19];
char SCHEMA[9];
char PARMLST[255];
EXEC SQL END DECLARE SECTION;
/***************************************************************/
/* Declare cursors for returning result sets to the caller. */
/***************************************************************/
EXEC SQL DECLARE C1 CURSOR WITH RETURN FOR
SELECT NAME
FROM SYSIBM.SYSTABLES
WHERE CREATOR=:SCHEMA;
main(argc,argv)
int argc;
char *argv[];
{
/********************************************************/
/* Copy the input parameters into the area reserved in */
/* the program for SQL processing. */
/********************************************************/
strcpy(PROCNM, argv[1]);
strcpy(SCHEMA, argv[2]);
/********************************************************/
/* Issue the SQL SELECT against the SYSROUTINES */
/* DB2 catalog table. */
576 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
/********************************************************/
strcpy(PARMLST, ""); /* Clear PARMLST */
EXEC SQL
SELECT RUNOPTS INTO :PARMLST
FROM SYSIBM.ROUTINES
WHERE NAME=:PROCNM AND
SCHEMA=:SCHEMA;
/********************************************************/
/* Copy SQLCODE to the output parameter list. */
/********************************************************/
*(int *) argv[3] = SQLCODE;
/********************************************************/
/* Copy the PARMLST value returned by the SELECT back to*/
/* the parameter list provided to this stored procedure.*/
/********************************************************/
strcpy(argv[4], PARMLST);
/********************************************************/
/* Open cursor C1 to cause DB2 to return a result set */
/* to the caller. */
/********************************************************/
EXEC SQL OPEN C1;
}
The following example is a C stored procedure with linkage convention GENERAL WITH NULLS.
#pragma runopts(plist(os))
#include <stdlib.h>
/***************************************************************/
/* Declare C variables used for SQL operations on the */
/* parameters. These are local variables to the C program, */
/***************************************************************/
/* Declare cursors for returning result sets to the caller. */
/***************************************************************/
EXEC SQL DECLARE C1 CURSOR WITH RETURN FOR
SELECT NAME
FROM SYSIBM.SYSTABLES
WHERE CREATOR=:SCHEMA;
main(argc,argv)
int argc;
char *argv[];
{
/********************************************************/
/* Copy the input parameters into the area reserved in */
/* the local program for SQL processing. */
/********************************************************/
strcpy(PROCNM, argv[1]);
strcpy(SCHEMA, argv[2]);
/********************************************************/
/* Copy null indicator values for the parameter list. */
/********************************************************/
memcpy(&PARM_IND,(struct INDICATORS *) argv[5],
sizeof(PARM_IND));
/********************************************************/
/* If any input parameter is NULL, return an error */
/* return code and assign a NULL value to PARMLST. */
/********************************************************/
if (PARM_IND.PROCNM_IND<0 ||
PARM_IND.SCHEMA_IND<0 || {
*(int *) argv[3] = 9999; /* set output return code */
PARM_IND.OUT_CODE_IND = 0; /* value is not NULL */
PARM_IND.PARMLST_IND = -1; /* PARMLST is NULL */
}
else {
/********************************************************/
/* If the input parameters are not NULL, issue the SQL */
/* SELECT against the SYSIBM.SYSROUTINES catalog */
/* table. */
/********************************************************/
strcpy(PARMLST, ""); /* Clear PARMLST */
EXEC SQL
SELECT RUNOPTS INTO :PARMLST
FROM SYSIBM.SYSROUTINES
WHERE NAME=:PROCNM AND
SCHEMA=:SCHEMA;
/********************************************************/
/* Copy SQLCODE to the output parameter list. */
/********************************************************/
*(int *) argv[3] = SQLCODE;
PARM_IND.OUT_CODE_IND = 0; /* OUT_CODE is not NULL */
}
/********************************************************/
/* Copy the RUNOPTS value back to the output parameter */
/* area. */
/********************************************************/
strcpy(argv[4], PARMLST);
/********************************************************/
/* Copy the null indicators back to the output parameter*/
/* area. */
/********************************************************/
578 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
memcpy((struct INDICATORS *) argv[5],&PARM_IND,
sizeof(PARM_IND));
/********************************************************/
/* Open cursor C1 to cause DB2 to return a result set */
/* to the caller. */
/********************************************************/
EXEC SQL OPEN C1;
}
Procedure
Choose one of the following actions:
Option Description
To define the a. Code the SQLCA directly in the program or use the following SQL INCLUDE
SQL communications statement to request a standard SQLCA declaration:
area:
EXEC SQL INCLUDE SQLCA
long SQLCODE;
char SQLSTATE[6];
Procedure
Code the SQLDA directly in the program, or use the following SQL INCLUDE statement to request a
standard SQLDA declaration:
You can place an SQLDA declaration wherever C allows a structure definition. Normal C scoping rules
apply. The standard declaration includes only a structure definition with the name sqlda.
Restriction: You must place SQLDA declarations before the first SQL statement that references the data
descriptor, unless you use the TWOPASS SQL processing option.
Related tasks
Defining SQL descriptor areas (SQLDA)
If your program includes certain SQL statements, you must define at least one SQL descriptor area
(SQLDA). Depending on the context in which it is used, the SQLDA stores information about prepared SQL
statements or host variables. This information can then be read by either the application program or Db2.
Related reference
SQL descriptor area (SQLDA) (Db2 SQL)
Procedure
To declare host variables, host-variable arrays, and host structures:
1. Declare the variables according to the following rules and guidelines:
• You can have more than one host variable declaration section in your program.
• You can use class members as host variables. Class members that are used as host variables are
accessible to any SQL statement within the class. However, you cannot use class objects as host
variables.
580 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
• If you specify the ONEPASS SQL processing option, you must explicitly declare each host variable
and each host-variable array before using them in an SQL statement. If you specify the TWOPASS
precompiler option, you must declare each host variable before using it in the DECLARE CURSOR
statement.
Restriction: The Db2 coprocessor for C/C++ supports only the ONEPASS option.
• If you specify the STDSQL(YES) SQL processing option, you must precede the host language
statements that define the host variables and host-variable arrays with the BEGIN DECLARE
SECTION statement and follow the host language statements with the END DECLARE SECTION
statement. Otherwise, these statements are optional.
• Ensure that any SQL statement that uses a host variable or host-variable array is within the scope of
the statement that declares that variable or array.
• If you are using the Db2 precompiler, ensure that the names of host variables and host-variable
arrays are unique within the program, even if the variables and variable arrays are in different blocks,
classes, procedures, functions, or subroutines. You can qualify the names with a structure name to
make them unique.
2. Optional: Define any associated indicator variables, arrays, and structures.
Related tasks
Declaring host variables and indicator variables
You can use host variables and indicator variables in SQL statements in your program to pass data
between Db2 and your application.
float
auto const double
extern volatile int
static short
sqlint32
int
long
int
long long
decimal ( precision )
, scale
_Decimal32
_Decimal64
_Decimal128
variable-name ;
1 =expression
*pointer-name
Notes:
1 If you use the pointer notation of the host variable, you must use the Db2 coprocessor.
Restrictions:
• If your C compiler does not have a decimal data type, no exact equivalent exists for the SQL data type
DECIMAL. In this case, you can use one of the following variables or techniques to handle decimal
values:
– An integer or floating-point variable, which converts the value. If you use an integer variable, you
lose the fractional part of the number. If the decimal number can exceed the maximum value for
an integer or if you want to preserve a fractional value, use floating-point variables. Floating-point
numbers are approximations of real numbers. Therefore, when you assign a decimal number to a
floating-point variable, the result might be different from the original number.
– A character-string host variable. Use the CHAR function to get a string representation of a decimal
number.
– The DECIMAL function to explicitly convert a value to a decimal data type, as shown in the following
example:
• z/OS 1.10 or above (z/OS V1R10 XL C/C++ ) is required to use the decimal floating-point host data type.
• The special C only 'complex floating-point' host data type is not a supported type for host variable.
• The FLOAT precompiler option does not apply to the decimal floating-point host variable types.
582 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
• To use decimal floating-point host variable, you must use the Db2 coprocessor.
For floating-point data types, use the FLOAT SQL processing option to specify whether the host variable
is in IEEE binary floating-point or z/Architecture hexadecimal floating-point format. Db2 does not check
if the format of the host variable contents match the format that you specified with the FLOAT SQL
processing option. Therefore, you need to ensure that your floating-point host variable contents match
the format that you specified with the FLOAT SQL processing option. Db2 converts all floating-point input
data to z/Architecture hexadecimal floating-point format before storing it.
char
auto const unsigned
extern volatile
static
variable-name ;
1 =expression
*pointer-name
Notes:
1 If you use the pointer notation of the host variable, you must use the Db2 coprocessor.
The following diagram shows the syntax for declaring NUL-terminated character host variables.
char
auto const unsigned
extern volatile
static
2 3
variable-name [ length ] ;
1 =expression
*pointer-name
Notes:
1 If you use the pointer notation of the host variable, you must use the Db2 coprocessor.
2 Any string that is assigned to this variable must be NUL-terminated. Any string that is retrieved from this
variable is NUL-terminated.
3 A NUL-terminated character host variable maps to a varying-length character string (except for the NUL).
int
1
struct { short var-1
auto const tag
extern volatile
static
2
; char var-2 [ length ] ; }
unsigned
variable-name ;
3 ={expression ,expression }
*pointer-name
Notes:
1 You can use the struct tag to define other variables, but you cannot use them as host variables in SQL.
2 You cannot use var-1 and var-2 as host variables in an SQL statement.
3 If you use the pointer notation of the host variable, you must use the Db2 coprocessor.
Example
The following example code shows valid and invalid declarations of the VARCHAR structured form:
For NUL-terminated string host variables, use the SQL processing options PADNTSTR and NOPADNTSTR
to specify whether the variable should be padded with blanks. The option that you specify determines
where the NUL-terminator is placed.
If you assign a string of length n to a NUL-terminated string host variable, the variable has one of the
values that is shown in the following table.
Table 99. Value of a NUL-terminated string host variable that is assigned a string of length n
Length of the NUL-terminated string host
variable Value of the variable
Less than or equal to n The source string up to a length of n-1 and a NUL at
the end of the string. 1
Db2 sets SQLWARN[1] to W and any indicator
variable that you provide to the original length of
the source string.
Equal to n+1 The source string and a NUL at the end of the
string. 1
584 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 99. Value of a NUL-terminated string host variable that is assigned a string of length n (continued)
Length of the NUL-terminated string host
variable Value of the variable
Greater than n+1 and the source is a fixed-length If PADNTSTR is in effect
string The source string, blanks to pad the value, and
a NUL at the end of the string.
If NOPADNTSTR is in effect
The source string and a NUL at the end of the
string.
Greater than n+1 and the source is a varying-length The source string and a NUL at the end of the
string string. 1
Note:
1. In these cases, whether NOPADNTSTR or PADNTSTR is in effect is irrelevant.
Restriction: If you use the Db2 precompiler, you cannot use a host variable that is of the NUL-terminated
form in either a PREPARE or DESCRIBE statement. However, if you use the Db2 coprocessor, you
can use host variables of the NUL-terminated form in PREPARE, DESCRIBE, and EXECUTE IMMEDIATE
statements.
• Use the sqldbchar data type that is defined in the typedef statement in one of the following files or
libraries:
– SQL library, sql.h
– Db2 CLI library, sqlcli.h
– SQLUDF file in data set DSN1210.SDSNC.H
• Use the C data type unsigned short.
Using sqldbchar or unsigned short enables you to manipulate DBCS and Unicode UTF-16 data in the
same format in which it is stored in Db2. Using sqldbchar also makes applications easier to port to other
platforms.
The following diagrams show the syntax for forms other than DBCLOBs.
The following diagram shows the syntax for declaring single-graphic host variables.
1 2
variable-name ;
*pointer-name =expression
Notes:
1 You cannot use array notation in variable-name.
2 The single-graphic form declares a fixed-length graphic string of length 1.
The following diagram shows the syntax for declaring NUL-terminated graphic host variables.
sqldbchar
auto const
extern volatile
static
2 3 4
variable-name [ length ] ;
1 =expression
*pointer-name
Notes:
1 If you use the pointer notation of the host variable, you must use the Db2 coprocessor.
2 length must be a decimal integer constant greater than 1 and not greater than 16352.
3 Any string that is assigned to this variable must be NUL-terminated. Any string that is retrieved from this
variable is NUL-terminated.
4 The NUL-terminated graphic form does not accept single-byte characters for the variable.
The following diagram shows the syntax for declaring graphic host variables that use the VARGRAPHIC
structured form.
int
1
struct { short
auto const tag
extern volatile
static
2 3 4
var-1 ; sqldbchar var-2 [ length ] ; }
variable-name ;
5 ={expression ,expression }
*pointer-name
586 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Notes:
1 You can use the struct tag to define other variables, but you cannot use them as host variables in SQL.
2 var-1 must be less than or equal to length.
3 You cannot use var-1 or var-2 as host variables in an SQL statement.
4 length must be a decimal integer constant greater than 1 and not greater than 16352.
5 f you use the pointer notation of the host variable, you must use the Db2 coprocessor.
Example
The following example shows valid and invalid declarations of graphic host variables that use the
VARGRAPHIC structured form:
1
SQL TYPE IS BINARY ( length )
auto const
extern volatile
static
variable-name ;
Notes:
1 The length must be a value in the range 1 - 255.
The following diagram shows the syntax for declaring VARBINARY host variables.
variable-name ;
= { init-len , " init-data " }
Notes:
1 For VARBINARY host variables, the length must be in the range 1 - 32704.
The C language does not have variables that correspond to the SQL binary data types BINARY and
VARBINARY. To create host variables that can be used with these data types, use the SQL TYPE IS
clause. The SQL precompiler replaces this declaration with the C language structure in the output source
member.
When you reference a BINARY or VARBINARY host variable in an SQL statement, you must use the
variable that you specify in the SQL TYPE declaration. When you reference the host variable in a host
language statement, you must use the variable that Db2 generates.
Recommendation: Be careful when you use binary host variables with C and C++. The SQL TYPE
declaration for BINARY and VARBINARY does not account for the NUL-terminator that C expects, because
binary strings are not NUL-terminated strings. Also, the binary host variable might contain zeroes at any
point in the string.
588 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
SQL TYPE IS RESULT_SET_LOCATOR VARYING
auto const
extern volatile
static
register
variable-name ;
*pointer-name = init-value
Table locators
The following diagram shows the syntax for declaring table locators.
register
variable-name ;
*pointer-name =init-value
register
BLOB K
CLOB
DBCLOB
BLOB_LOCATOR
CLOB_LOCATOR
DBCLOB_LOCATOR
BLOB_FILE
CLOB_FILE
DBCLOB_FILE
variable-name ;
*pointer-name 1
=init-value
Notes:
1Specify the initial value as a series of expressions. For example, specify ={expression,
expression}. For BLOB_FILE, CLOB_FILE, and DBCLOB_FILE, specify ={name_length,
data_length, file_option_map, file_name}.
XML AS DBCLOB_FILE
1
variable-name ;
*pointer-name =init-value
590 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Notes:
1Specify the initial value as a series of expressions. For example, specify ={expression,
expression}. For BLOB_FILE, CLOB_FILE, and DBCLOB_FILE, specify ={name_length,
data_length, file_option_map, file_name}.
register
Constants
The syntax for constants in C and C++ programs differs from the syntax for constants in SQL statements in
the following ways:
• C/C++ uses various forms for numeric literals (possible suffixes are: ll, LL, u, U, f,F,l,L,df,DF, dd, DD, dl,
DL,d, D). For example, in C/C++:
4850976 is a decimal literal
0x4bD is a hexadecimal integer literal
03245 is an octal integer literal
3.2E+4 is a double floating-point literal
3.2E+4f is a float floating-point literal
3.2E+4l is a long double floating-point literal
0x4bDP+4 is a double hexadecimal floating-point literal
22.2df is a _Decimal32 decimal floating-point literal
0.00D is a fixed-point decimal literal (z/OS only when LANGLVL(EXTENDED) is specified)
• Use C/C++ literal form only outside of SQL statements. Within SQL statements, use numeric constants.
• In C, character constants and string constants can use escape sequences. You cannot use the escape
sequences in SQL statements.
• Apostrophes and quotation marks have different meanings in C and SQL. In C, you can use double
quotation marks to delimit string constants, and apostrophes to delimit character constants.
Example: Use of quotation marks in C
In SQL, you can use double quotation marks to delimit identifiers and apostrophes to delimit string
constants.
Example: quotation marks in SQL
• Character data in SQL is distinct from integer data. Character data in C is a subtype of integer data.
Related concepts
Host variables
Use host variables to pass a single data item between Db2 and your application.
Using host variables in SQL statements
Use scalar host variables in embedded SQL statements to represent a single value. Host variables are
useful for storing retrieved data or for passing values that are to be assigned or used for comparisons.
Related tasks
Determining whether a retrieved value in a host variable is null or truncated
Before your application manipulates the data that was retrieved from Db2 into a host variable, determine
if the value is null. Also determine if it was truncated when assigned to the variable. You can use indicator
variables to obtain this information.
Inserting a single row by using a host variable
Use host variables in your INSERT statement when you don't know at least some of the values to insert
until the program runs.
Inserting null values into columns by using indicator variables or arrays
If you need to insert null values into a column, using an indicator variable or array is an easy way to do so.
An indicator variable or array is associated with a particular host variable or host-variable array.
Storing LOB data in a table
Db2 handles LOB data differently than it handles other kinds of data. As a result, in some cases, you need
to take additional actions when you define LOB columns and insert the LOB data.
Retrieving a single row of data into host variables
If you know that your query returns only one row, you can specify one or more host variables to contain
the column values of the retrieved row.
Retrieving a single row of data into a host structure
If you know that your query returns multiple column values for only one row, you can specify a host
structure to contain the column values.
Updating data by using host variables
When you want to update a value in a Db2 table, but you do not know the exact value until the program
runs, use host variables. Db2 can change a table value to match the current value of the host variable.
Related reference
Descriptions of SQL processing options
You can specify any SQL processing options regardless of whether you use the Db2 precompiler or the
Db2 coprocessor. However, the Db2 coprocessor might ignore certain options because host language
compiler options exist that provide the same information.
592 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Restrictions:
• Only some of the valid C declarations are valid host-variable array declarations. If the declaration for
a variable array is not valid, any SQL statement that references the variable array might result in the
message UNDECLARED HOST VARIABLE ARRAY.
• For both C and C++, you cannot specify the _packed attribute on the structure declarations for the
following arrays that are used in multiple-row INSERT, FETCH, and MERGE statements:
– varying-length character arrays
– varying-length graphic arrays
– LOB arrays
In addition, the #pragma pack(1) directive cannot be in effect if you plan to use these arrays in
multiple-row statements.
float
double
int
long
short
int
long long
decimal ( precision )
, scale
_Decimal32
_Decimal64
_Decimal128
1
variable-name [ dimension ]
,
= { expression }
Notes:
1 dimension must be an integer constant between 1 and 32767.
char
auto const unsigned
extern volatile
static
1
variable-name [ dimension ] [ length ]
,
= { expression }
2 3
;
Notes:
1 dimension must be an integer constant between 1 and 32767.
2 Any string that is assigned to this variable must be NUL-terminated. Any string that is retrieved from this
variable is NUL-terminated.
3 The strings in a NUL-terminated character host-variable array map to varying-length character strings
The following diagram shows the syntax for declaring varying-length character host-variable arrays that
use the VARCHAR structured form.
594 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
int
1 2
struct { short var-1 ;
auto const
extern volatile
static
3
char var-2 [ length ] ; }
unsigned
4
variable-name [ dimension ]
,
= { expression }
Notes:
1 You can use the struct tag to define other variables, but you cannot use them as host-variable arrays in
SQL.
2 var-1 must be a scalar numeric variable.
3 var-2 must be a scalar CHAR array variable.
4 dimension must be an integer constant between 1 and 32767.
Example
The following example shows valid and invalid declarations of VARCHAR host-variable arrays.
register
1
variable-name [ dimension ] ;
Notes:
• Use the sqldbchar data type that is defined in the typedef statement in the header files that are
supplied by Db2.
• Use the C data type unsigned short.
The following diagram shows the syntax for declaring NUL-terminated graphic host-variable arrays.
sqldbchar
auto const unsigned
extern volatile
static
1 2
variable-name [ dimension ] [ length ]
,
= { expression }
3 4
;
Notes:
1 dimension must be an integer constant between 1 and 32767.
2 length must be a decimal integer constant greater than 1 and not greater than 16352.
3 Any string that is assigned to this variable must be NUL-terminated. Any string that is retrieved from this
variable is NUL-terminated.
4 Do not assign single-byte characters into a NUL-terminated graphic host-variable array
The following diagram shows the syntax for declaring graphic host-variable arrays that use the
VARGRAPHIC structured form.
596 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
int
1 2
struct { short var-1 ;
auto const
extern volatile
static
3 4
sqldbchar var-2 [ length ] ; }
unsigned
5
variable-name [ dimension ]
,
= { expression }
Notes:
1 You can use the struct tag to define other variables, but you cannot use them as host-variable arrays in
SQL.
2 var-1 must be a scalar numeric variable.
3 var-2 must be a scalar char array variable.
4 length must be a decimal integer constant greater than 1 and not greater than 16352.
5 dimension must be an integer constant between 1 and 32767.
Example
The following example shows valid and invalid declarations of graphic host-variable arrays that use the
VARGRAPHIC structured form.
register
BLOB K
CLOB
DBCLOB
BLOB_LOCATOR
CLOB_LOCATOR
DBCLOB_LOCATOR
BLOB_FILE
CLOB_FILE
DBCLOB_FILE
1
variable-name [ dimension ]
,
= { expression }
Notes:
1 dimension must be an integer constant between 1 and 32767.
598 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
SQL TYPE IS XML AS
auto const
extern volatile
static
register
BLOB K
CLOB
DBCLOB
BLOB_FILE
CLOB_FILE
DBCLOB_FILE
1
variable-name [ dimension ]
,
= { expression }
Notes:
1 dimension must be an integer constant between 1 and 32767.
register
1
variable-name [ dimension ] ;
Notes:
1 dimension must be an integer constant between 1 and 32767.
Related concepts
Using host-variable arrays in SQL statements
Host structures
The following diagram shows the syntax for declaring host structures.
600 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
struct {
auto const packed tag
extern volatile
static
float var-1 ;
double
int
short
sqlint32
int
long
int
long long
decimal ( precision
, scale )
_Decimal32
_Decimal64
_Decimal128
varchar structure
binary structure
vargraphic structure
char var-2 ;
unsigned [ length ]
sqldbchar var-5 ;
[ length ]
} variable-name ;
=expression
VARCHAR structures
The following diagram shows the syntax for VARCHAR structures that are used within declarations of host
structures.
VARGRAPHIC structures
The following diagram shows the syntax for VARGRAPHIC structures that are used within declarations of
host structures.
int
struct { short var-6 ; sqldbchar
tag signed
var-7 [ length ] ; }
Binary structures
The following diagram shows the syntax for binary structures that are used within declarations of host
structures.
VARBINARY
BINARY VARYING
BLOB K
CLOB
DBCLOB
BLOB_LOCATOR
CLOB_LOCATOR
DBCLOB_LOCATOR
602 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
LOB data types for XML data
The following diagram shows the syntax for LOB data types that are used within declarations of host
structures for XML data.
BLOB K
CLOB
DBCLOB
BLOB_FILE
CLOB_FILE
DBCLOB_FILE
Example
In the following example, the host structure is named target, and it contains the fields c1, c2, and c3.
c1 and c3 are character arrays, and c2 is a host variable that is equivalent to the SQL VARCHAR data
type. The target host structure can be part of another host structure but must be the deepest level of the
nested structure.
Related concepts
Host structures
Use host structures to pass a group of host variables between Db2 and your application.
variable-name ;
= expression
The following diagram shows the syntax for declaring an indicator array or a host structure indicator array
in C and C++.
int
short
auto const signed
extern volatile
static
1
variable-name [ dimension ] ;
= expression
Notes:
1 dimension must be an integer constant between 1 and 32767.
Example
The following example shows a FETCH statement with the declarations of the host variables that are
needed for the FETCH statement and their associated indicator variables.
Related concepts
Indicator variables, arrays, and structures
An indicator variable is associated with a particular host variable. Each indicator variable contains a small
integer value that indicates some information about the associated host variable. Indicator arrays and
structures serve the same purpose for host-variable arrays and structures.
Related tasks
Inserting null values into columns by using indicator variables or arrays
604 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
If you need to insert null values into a column, using an indicator variable or array is an easy way to do so.
An indicator variable or array is associated with a particular host variable or host-variable array.
Procedure
Specify the pointer host variable exactly as it was declared.
The only exception is when you reference pointers to nul-terminated character arrays. In this case, you do
not have to include the parentheses that were part of the declaration.
Examples
Examples: Scalar pointer host variable references
struct {
unsigned long len;
char * data;
} hvbcharp;
The following example references this bounded character pointer host variable:
hvcharp.len = dynlen; a
hvcharp.data = (char *) malloc (hvcharp.len); b
EXEC SQL set :hvcharp = 'data buffer with length'; c
Note:
a
dynlen can be either a compile time constant or a variable with a value that is assigned at run
time.
b
Storage is dynamically allocated for hvcharp.data.
c
The SQL statement references the name of the structure, not an element within the structure.
To reference this data is SQL statements, use the pointer as shown in the following example. Assume
that tbl_sel_cur is a declared cursor.
Related tasks
Declaring pointer host variables in C programs
If you use the Db2 coprocessor, you can use pointer host variables with statically or dynamically allocated
storage. These pointer host variables can point to numeric data, non-numeric data, or a structure.
Procedure
Include an asterisk (*) in each variable declaration to indicate that the variable is a pointer.
Restrictions:
• You cannot use pointer host variables that point to character data of an unknown length. For example,
do not specify the following declaration: char * hvcharpu. Instead, specify the length of the data
606 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
by using a bounded character pointer host variable. A bounded character pointer host variable is a host
variable that is declared as a structure with the following elements:
– A 4-byte field that contains the length of the storage area.
– A pointer to the non-numeric dynamic storage area.
• You cannot use untyped pointers. For example, do not specify the following declaration: void *
untypedprt .
Examples
Example: Scalar pointer host variable declarations
struct {
unsigned long len;
char * data;
} hvbcharp;
struct tbl_struct
{
char colname[20];
small int colno;
small int coltype;
small int collen;
};
The following example code declares a pointer to the structure tbl_struct. Storage is allocated
dynamically for up to n rows.
Related tasks
Referencing pointer host variables in C programs
If you use the Db2 coprocessor, you can reference any declared pointer host variables in your SQL
statements.
Table 105. SQL data types, SQLLEN values, and SQLTYPE values that the precompiler uses for host
variables in C programs
C host variable data type SQLTYPE of host SQLLEN of host SQL data type
variable1 variable
608 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 105. SQL data types, SQLLEN values, and SQLTYPE values that the precompiler uses for host
variables in C programs (continued)
C host variable data type SQLTYPE of host SQLLEN of host SQL data type
variable1 variable
Notes:
1. If a host variable includes an indicator variable, the SQLTYPE value is the base SQLTYPE value plus 1.
2. p is the precision; in SQL terminology, this the total number of digits. In C, this is called the size.
s is the scale; in SQL terminology, this is the number of digits to the right of the decimal point. In C,
this is called the precision.
C++ does not support the decimal data type.
3. Do not use this data type as a column type.
4. n is the number of double-byte characters.
5. No exact equivalent. Use DECIMAL(19,0).
6. The C data type long maps to the SQL data type BIGINT.
7. DFP host variable with a length of 4 is supported while DFP column can be defined only with length
8(DECFLOAT(16)) or 16(DECFLOAT(34)).
8. To use the decimal floating-point host data type, you must do the following:
• Use z/OS 1.10 or later (z/OS V1R10 XL C/C++ ).
• Compile with the C/C++ compiler option, DFP.
• Specify the SQL compiler option to enable the Db2 coprocessor.
• Specify C/C++ compiler option, ARCH(7). It is required by the DFP compiler option if the DFP type is
used in the source.
• Specify 'DEFINE(__STDC_WANT_DEC_FP__)' compiler option because DFP is not officially part of
the C/C++ Language Standard.
The following table shows equivalent C host variables for each SQL data type. Use this table to determine
the C data type for host variables that you define to receive output from the database. For example, if
you retrieve TIMESTAMP data, you can define a variable of NUL-terminated character form or VARCHAR
structured form
610 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
This table shows direct conversions between SQL data types and C data types. However, a number of SQL
data types are compatible. When you do assignments or comparisons of data that have compatible data
types, Db2 converts those compatible data types.
Table 106. C host variable equivalents that you can use when retrieving data of a particular SQL data type
SQL data type C host variable equivalent Notes
SMALLINT short int
INTEGER long int
DECIMAL(p,s) or decimal You can use the double data type if your
NUMERIC(p,s) C compiler does not have a decimal data
type; however, double is not an exact
equivalent.
REAL or FLOAT(n) float 1<=n<=21
DOUBLE PRECISION or double 22<=n<=53
FLOAT(n)
DECFLOAT(16) _Decminal32
DECFLOAT(34) _Decimal128
BIGINT long long, long long int, and sqlint64
BINARY(n) SQL TYPE IS BINARY(n) 1<=n<=255
If data can contain character NULs (\0),
certain C and C++ library functions
might not handle the data correctly.
Ensure that your application handles the
data properly.
612 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 106. C host variable equivalents that you can use when retrieving data of a particular SQL data type
(continued)
SQL data type C host variable equivalent Notes
TIMESTAMP(p) WITH NUL-terminated character form The length must be at least 27+p.
TIME ZONE
VARCHAR structured form The length must be at least 26+p.
Result set locator SQL TYPE IS RESULT_SET_LOCATOR Use this data type only for receiving
result sets. Do not use this data type as
a column type.
Table locator SQL TYPE IS TABLE LIKE table-name AS Use this data type only in a user-defined
LOCATOR function or stored procedure to receive
rows of a transition table. Do not use
this data type as a column type.
BLOB locator SQL TYPE IS BLOB_LOCATOR Use this data type only to manipulate
data in BLOB columns. Do not use this
data type as a column type.
CLOB locator SQL TYPE IS CLOB_LOCATOR Use this data type only to manipulate
data in CLOB columns. Do not use this
data type as a column type.
DBCLOB locator SQL TYPE IS DBCLOB_LOCATOR Use this data type only to manipulate
data in DBCLOB columns. Do not use
this data type as a column type.
BLOB(n) SQL TYPE IS BLOB(n) 1≤n≤2147483647
CLOB(n) SQL TYPE IS CLOB(n) 1≤n≤2147483647
DBCLOB(n) SQL TYPE IS DBCLOB(n) n is the number of double-byte
characters. 1≤n≤1073741823
XML SQL TYPE IS XML AS BLOB(n) 1≤n≤2147483647
XML SQL TYPE IS XML AS CLOB(n) 1≤n≤2147483647
XML SQL TYPE IS XML AS DBCLOB(n) n is the number of double-byte
characters. 1≤n≤1073741823
BLOB file reference SQL TYPE IS BLOB_FILE Use this data type only to manipulate
data in BLOB columns. Do not use this
data type as a column type.
CLOB file reference SQL TYPE IS CLOB_FILE Use this data type only to manipulate
data in CLOB columns. Do not use this
data type as a column type.
DBCLOB file reference SQL TYPE IS DBCLOB_FILE Use this data type only to manipulate
data in DBCLOB columns. Do not use
this data type as a column type.
XML BLOB file reference SQL TYPE IS XML AS BLOB_FILE Use this data type only to manipulate
XML data as BLOB files. Do not use this
data type as a column type.
XML CLOB file reference SQL TYPE IS XML AS CLOB_FILE Use this data type only to manipulate
XML data as CLOB files. Do not use this
data type as a column type.
The following table shows the C language definitions to use in C stored procedures and user-defined
functions, when the parameter data types in the routine definitions are LOBs, ROWIDs, or locators. For
other parameter data types, the C language definitions are the same as those in Table 106 on page 611
above.
Table 107. Equivalent C language declarations for LOBs, ROWIDs, and locators in user-defined routine
definitions
SQL data type in definition1 C declaration
BLOB(n) struct
{unsigned long length;
char data[n];
} var;
CLOB(n) struct
{unsigned long length;
char var_data[n];
} var;
DBCLOB(n) struct
{unsigned long length;
sqldbchar data[n];
} var;
ROWID struct {
short int length;
char data[40];
} var;
char data[n+1];
struct
{short len;
char data[n];
} var;
614 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 107. Equivalent C language declarations for LOBs, ROWIDs, and locators in user-defined routine
definitions (continued)
SQL data type in definition1 C declaration
Note:
1. The SQLUDF file, which is in data set DSN1210.SDSNC.H, includes the typedef sqldbchar. Using
sqldbchar lets you manipulate DBCS and Unicode UTF-16 data in the same format in which it is
stored in Db2. sqldbchar also makes applications easier to port to other Db2 platforms.
2. This row does not apply to VARCHAR(n) FOR BIT DATA. BIT DATA is always passed in a structured
representation.
Related concepts
Compatibility of SQL and language data types
The host variable data types that are used in SQL statements must be compatible with the data types of
the columns with which you intend to use them.
LOB host variable, LOB locator, and LOB file reference variable declarations
When you write applications to manipulate LOB data, you need to declare host variables to hold the LOB
data or LOB locator. Alternatively, you need to declare LOB file reference variables to point to the LOB
data.
Host variable data types for XML data in embedded SQL applications (Db2 Programming for XML)
Procedure
To request information about SQL errors in C and C++ applications, use the following approaches:
• You can use the subroutine DSNTIAR to convert an SQL return code into a text message.
DSNTIAR takes data from the SQLCA, formats it into a message, and places the result in a message
output area that you provide in your application program. For concepts and more information about the
behavior of DSNTIAR, see “Displaying SQLCA fields by calling DSNTIAR” on page 525.
DSNITAR syntax
DSNTIAR has the following syntax:
where error_message is the name of the message output area, data_dim is the number of lines
in the message output area, and data_len is the length of each line.
&lrecl
A fullword containing the logical record length of output messages, between 72 and 240.
To inform your compiler that DSNTIAR is an assembler language program, include one of the following
statements in your application.
For C, include:
Examples of calling DSNTIAR from an application appear in the Db2 sample C program DSN8BD3
and in the sample C++ program DSN8BE3. Both are in the library DSN8C10.SDSNSAMP. See “Sample
applications supplied with Db2 for z/OS” on page 1022 for instructions on how to access and print the
source code for the sample programs.
• If your CICS application requires CICS storage handling, you must use the subroutine DSNTIAC instead
of DSNTIAR.
DSNTIAC syntax
DSNTIAC has the following syntax:
616 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Application programs can request more information about SQL error codes from Db2.
Related reference
GET DIAGNOSTICS (Db2 SQL)
Notes:
1. If you use the Db2 coprocessor, you can use the LOCAL-STORAGE SECTION wherever WORKING-
STORAGE SECTION is listed in the table.
2. When including host variable declarations, the INCLUDE statement must be in the WORKING-
STORAGE SECTION or the LINKAGE SECTION.
You cannot put SQL statements in the DECLARATIVES section of a COBOL program.
Each SQL statement in a COBOL program must begin with EXEC SQL and end with END-EXEC. If you
are using the Db2 precompiler, the EXEC and SQL keywords must appear on one line, but the remainder
of the statement can appear on subsequent lines. If you are using the Db2 coprocessor, the EXEC and
SQL keywords can be on different lines. Do not include any tokens between the two keywords EXEC and
SQL except for COBOL comments, including debugging lines. Do not include SQL comments between the
keywords EXEC and SQL.
If the SQL statement appears between two COBOL statements, the period after END-EXEC is optional and
might not be appropriate. If the statement appears in an IF…THEN set of COBOL statements, omit the
ending period to avoid inadvertently ending the IF statement.
You might code an UPDATE statement in a COBOL program as follows:
EXEC SQL
UPDATE DSN8C10.DEPT
SET MGRNO = :MGR-NUM
WHERE DEPTNO = :INT-DEPT
END-EXEC.
Comments
You can include COBOL comment lines (* in column 7) in SQL statements wherever you can use a
blank.
EXEC SQL
SQL-statement
END-EXEC.
COPY
If you use the Db2 precompiler, do not use a COBOL COPY statement within host variable
declarations. If you use the Db2 coprocessor, you can use COBOL COPY.
REPLACE
If you use the Db2 precompiler, the REPLACE statement has no effect on SQL statements. It affects
only the COBOL statements that the precompiler generates.
If you use the Db2 coprocessor, the REPLACE statement replaces text strings in SQL statements as
well as in generated COBOL statements.
Declaring tables and views
Your COBOL program should include the statement DECLARE TABLE to describe each table and
view the program accesses. You can use the Db2 declarations generator (DCLGEN) to generate the
DECLARE TABLE statements. You should include the DCLGEN members in the DATA DIVISION.
Dynamic SQL in a COBOL program
In general, COBOL programs can easily handle dynamic SQL statements. COBOL programs can handle
SELECT statements if the data types and the number of fields returned are fixed. If you want to use
variable-list SELECT statements, use an SQLDA.
Including code
To include SQL statements or COBOL host variable declarations from a member of a partitioned data
set, use the following SQL statement in the source code where you want to include the statements:
618 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
EXEC SQL INCLUDE member-name END-EXEC.
If you are using the Db2 precompiler, you cannot nest SQL INCLUDE statements. In this case, do not
use COBOL verbs to include SQL statements or host variable declarations, and do not use the SQL
INCLUDE statement to include CICS preprocessor related code. In general, if you are using the Db2
precompiler, use the SQL INCLUDE statement only for SQL-related coding. If you are using the COBOL
Db2 coprocessor, none of these restrictions apply.
Use the 'EXEC SQL' and 'END-EXEC' keyword pair to include SQL statements only. COBOL statements,
such as COPY or REPLACE, are not allowed.
Margins
You must code SQL statements that begin with EXEC SQL in columns 12 through 72. Otherwise the
Db2 precompiler does not recognize the SQL statement.
Names
You can use any valid COBOL name for a host variable. Do not use external entry names or access plan
names that begin with 'DSN', and do not use host variable names that begin with 'SQL'. These names
are reserved for Db2.
Sequence numbers
The source statements that the Db2 precompiler generates do not include sequence numbers.
Statement labels
You can precede executable SQL statements in the PROCEDURE DIVISION with a paragraph name.
WHENEVER statement
The target for the GOTO clause in an SQL statement WHENEVER must be a section name or
unqualified paragraph name in the PROCEDURE DIVISION.
Special COBOL considerations
The following considerations apply to programs written in COBOL:
• In a COBOL program that uses elements in a multi-level structure as host variable names, the Db2
precompiler generates the lowest two-level names.
• Using the COBOL compiler options DYNAM and NODYNAM depends on the operating environment.
TSO and IMS: You can specify the option DYNAM when compiling a COBOL program if you use the
following guidelines. IMS and Db2 share a common alias name, DSNHLI, for the language interface
module. You must do the following when you concatenate your libraries:
– If you use IMS with the COBOL option DYNAM, be sure to concatenate the IMS library first.
– If you run your application program only under , be sure to concatenate the Db2 library first.
CICS, CAF, and RRSAF: You must specify the NODYNAM option when you compile a COBOL
program that either includes CICS statements or is translated by a separate CICS translator or
the integrated CICS translator. In these cases, you cannot specify the DYNAM option. If your CICS
program has a subroutine that is not translated by a separate CICS translator or the integrated CICS
translator but contains SQL statements, you can specify the DYNAM option. However, in this case,
you must concatenate the CICS libraries before the Db2 libraries.
You can compile COBOL stored procedures with either the DYNAM option or the NODYNAM option.
If you use DYNAM, ensure that the correct Db2 language interface module is loaded dynamically by
performing one of the following actions:
– Use the ATTACH(RRSAF) precompiler option.
– Copy the DSNRLI module into a load library that is concatenated in front of the Db2 libraries. Use
the member name DSNHLI.
• To avoid truncating numeric values, use either of the following methods:
– Use the COMP-5 data type for binary integer host variables.
– Specify the COBOL compiler option:
If you specify COBOL option RULES(NOEVENPACK), the COBOL compiler generates warning
IGYDS1348-W, because those variables have an even number of packed decimal digits.
If your program uses the Db2 precompiler and uses parameters that are defined in LINKAGE
SECTION as host variables to Db2 and the address of the input parameter might change on
subsequent invocations of your program, your program must reset the variable SQL-INIT-FLAG. This
flag is generated by the Db2 precompiler. Resetting this flag indicates that the storage must initialize
when the next SQL statement executes. To reset the flag, insert the statement MOVE ZERO TO SQL-
INIT-FLAG in the called program's PROCEDURE DIVISION, ahead of any executable SQL statements
that use the host variables. If you use the COBOL Db2 coprocessor, the called program does not need
to reset SQL-INIT-FLAG.
Handling SQL error codes
Cobol applications can request more information about SQL errors from Db2. For more information,
see “Handling SQL error codes in Cobol applications” on page 681.
620 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Related concepts
Sample applications supplied with Db2 for z/OS
Db2 provides sample applications to help you with Db2 programming techniques and coding practices
within each of the four environments: batch, TSO, IMS, and CICS. The sample applications contain various
applications that might apply to managing a company.
DCLGEN (declarations generator)
Your program should declare the tables and views that it accesses. The Db2 declarations generator,
DCLGEN, produces these DECLARE statements for C, COBOL, and PL/I programs, so that you do not need
to code the statements yourself. DCLGEN also generates corresponding host variable structures.
Using host-variable arrays in SQL statements
Use host-variable arrays in embedded SQL statements to represent values that the program does not
know until the query is executed. Host-variable arrays are useful for storing a set of retrieved values or for
passing a set of values that are to be inserted into a table.
SQL identifiers (Db2 SQL)
Related tasks
Overview of programming applications that access Db2 for z/OS data
Applications that interact with Db2 must first connect to Db2. They can then read, add, or modify data or
manipulate Db2 objects.
Including dynamic SQL in your program
Dynamic SQL is prepared and executed while the program is running.
Checking the execution of SQL statements by using the GET DIAGNOSTICS statement
One way to check whether an SQL statement executed successfully is to ask Db2 to return the diagnostic
information about the last executed SQL statement.
Defining SQL descriptor areas (SQLDA)
If your program includes certain SQL statements, you must define at least one SQL descriptor area
(SQLDA). Depending on the context in which it is used, the SQLDA stores information about prepared SQL
statements or host variables. This information can then be read by either the application program or Db2.
Displaying SQLCA fields by calling DSNTIAR
If you use the SQLCA to check whether an SQL statement executed successfully, your program needs to
read the data in the appropriate SQLCA fields. One easy way to read these fields is to use the assembler
subroutine DSNTIAR.
Setting limits for system resource usage by using the resource limit facility (Db2 Performance)
622 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* *
* FUNCTION = THIS MODULE PROVIDES THE STORAGE NEEDED BY *
* UNLDBCU2 AND CALLS THAT PROGRAM. *
* *
* NOTES = *
* DEPENDENCIES = ENTERPRISE COBOL FOR Z/OS IS REQUIRED. *
* SEVERAL NEW FACILITIES ARE USED. *
* *
* RESTRICTIONS = *
* THE MAXIMUM NUMBER OF COLUMNS IS 750, *
* WHICH IS THE SQL LIMIT. *
* *
* DATA RECORDS ARE LIMITED TO 32700 BYTES, *
* INCLUDING DATA, LENGTHS FOR VARCHAR DATA, *
* AND SPACE FOR NULL INDICATORS. *
* *
* MODULE TYPE = IBM ENTERPRISE COBOL PROGRAM *
* PROCESSOR = ENTERPRISE COBOL FOR Z/OS *
* MODULE SIZE = SEE LINK EDIT *
* ATTRIBUTES = REENTRANT *
* *
* ENTRY POINT = UNLDBCU1 *
* PURPOSE = SEE FUNCTION *
* LINKAGE = INVOKED FROM DSN RUN *
* INPUT = NONE *
* OUTPUT = NONE *
* *
* EXIT-NORMAL = RETURN CODE 0 NORMAL COMPLETION *
* *
* EXIT-ERROR = *
* RETURN CODE = NONE *
* ABEND CODES = NONE *
* ERROR-MESSAGES = NONE *
* *
* EXTERNAL REFERENCES = *
* ROUTINES/SERVICES = *
* UNLDBCU2 - ACTUAL UNLOAD PROGRAM *
* *
* DATA-AREAS = NONE *
* CONTROL-BLOCKS = NONE *
* *
* TABLES = NONE *
* CHANGE-ACTIVITY = NONE *
* *
* *PSEUDOCODE* *
* *
* PROCEDURE *
* CALL UNLDBCU2. *
* END. *
*---------------------------------------------------------------*
/
IDENTIFICATION DIVISION.
*-----------------------
PROGRAM-ID. UNLDBCU1
*
ENVIRONMENT DIVISION.
*
CONFIGURATION SECTION.
DATA DIVISION.
*
WORKING-STORAGE SECTION.
*
01 WORKAREA-IND.
02 WORKIND PIC S9(4) COMP-5 OCCURS 750 TIMES.
01 RECWORK.
02 RECWORK-LEN PIC S9(8) COMP-5 VALUE 32700.
02 RECWORK-CHAR PIC X(1) OCCURS 32700 TIMES.
*
PROCEDURE DIVISION.
*
CALL 'UNLDBCU2' USING WORKAREA-IND RECWORK.
GOBACK.
The following example is the called program that does pointer manipulation.
624 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* - IN DECIMAL. USUALLY AN ERROR IN *
* - THIS ROUTINE OR A NEW DATA TYPE. *
* DSNT497I RETURN CODE FROM MESSAGE ROUTINE DSNTIAR *
* - THE MESSAGE FORMATTING ROUTINE DETECTED *
* - AN ERROR. SEE THAT ROUTINE FOR RETURN *
* - CODE INFORMATION. USUALLY AN ERROR IN *
* - THIS ROUTINE. *
* DSNT498I ERROR, NO VALID COLUMNS FOUND *
* - THE PREPARE RETURNED DATA WHICH DID NOT *
* - PRODUCE A VALID OUTPUT RECORD. *
* - USUALLY AN ERROR IN THIS ROUTINE. *
* DSNT499I NO ROWS FOUND IN TABLE OR VIEW *
* - THE CHOSEN TABLE OR VIEWS DID NOT *
* - RETURN ANY ROWS. *
* ERROR MESSAGES FROM MODULE DSNTIAR *
* - WHEN AN ERROR OCCURS, THIS MODULE *
* - PRODUCES CORRESPONDING MESSAGES. *
* OTHER MESSAGES: *
* THE TABLE COULD NOT BE UNLOADED. EXITING. *
* *
* EXTERNAL REFERENCES = *
* ROUTINES/SERVICES = *
* DSNTIAR - TRANSLATE SQLCA INTO MESSAGES *
* DATA-AREAS = NONE *
* CONTROL-BLOCKS = *
* SQLCA - SQL COMMUNICATION AREA *
* *
* TABLES = NONE *
* CHANGE-ACTIVITY = NONE *
* *
* *PSEUDOCODE* *
* PROCEDURE *
* EXEC SQL DECLARE DT CURSOR FOR SEL END-EXEC. *
* EXEC SQL DECLARE SEL STATEMENT END-EXEC. *
* INITIALIZE THE DATA, OPEN FILES. *
* OBTAIN STORAGE FOR THE SQLDA AND THE DATA RECORDS. *
* READ A TABLE NAME. *
* OPEN SYSREC01. *
* BUILD THE SQL STATEMENT TO BE EXECUTED *
* EXEC SQL PREPARE SQL STATEMENT INTO SQLDA END-EXEC. *
* SET UP ADDRESSES IN THE SQLDA FOR DATA. *
* INITIALIZE DATA RECORD COUNTER TO 0. *
* EXEC SQL OPEN DT END-EXEC. *
* DO WHILE SQLCODE IS 0. *
* EXEC SQL FETCH DT USING DESCRIPTOR SQLDA END-EXEC. *
* ADD IN MARKERS TO DENOTE NULLS. *
* WRITE THE DATA TO SYSREC01. *
* INCREMENT DATA RECORD COUNTER. *
* END. *
* EXEC SQL CLOSE DT END-EXEC. *
* INDICATE THE RESULTS OF THE UNLOAD OPERATION. *
* CLOSE THE SYSIN, SYSPRINT, AND SYSREC01 FILES. *
* END. *
*---------------------------------------------------------------*
/
IDENTIFICATION DIVISION.
*-----------------------
PROGRAM-ID. UNLDBCU2
*
ENVIRONMENT DIVISION.
*--------------------
CONFIGURATION SECTION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT SYSIN
ASSIGN TO DA-S-SYSIN.
SELECT SYSPRINT
ASSIGN TO UT-S-SYSPRINT.
SELECT SYSREC01
ASSIGN TO DA-S-SYSREC01.
*
DATA DIVISION.
*-------------
*
FILE SECTION.
FD SYSIN
RECORD CONTAINS 80 CHARACTERS
BLOCK CONTAINS 0 RECORDS
LABEL RECORDS ARE OMITTED
RECORDING MODE IS F.
01 CARDREC PIC X(80).
*
626 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
INDEXED BY ERROR-INDEX.
77 ERROR-TEXT-LEN PIC S9(8) COMP-5 VALUE +120.
*****************************************************
* SQL DESCRIPTOR AREA *
*****************************************************
01 SQLDA.
02 SQLDAID PIC X(8) VALUE 'SQLDA '.
02 SQLDABC PIC S9(8) COMPUTATIONAL VALUE 33016.
02 SQLN PIC S9(4) COMP-5 VALUE 750.
02 SQLD PIC S9(4) COMP-5 VALUE 0.
02 SQLVAR OCCURS 1 TO 750 TIMES
DEPENDING ON SQLN.
03 SQLTYPE PIC S9(4) COMP-5.
03 SQLLEN PIC S9(4) COMP-5.
03 SQLDATA POINTER.
03 SQLIND POINTER.
03 SQLNAME.
49 SQLNAMEL PIC S9(4) COMP-5.
49 SQLNAMEC PIC X(30).
*
* DATA TYPES FOUND IN SQLTYPE, AFTER REMOVING THE NULL BIT
*
77 VARCTYPE PIC S9(4) COMP-5 VALUE +448.
77 CHARTYPE PIC S9(4) COMP-5 VALUE +452.
77 VARLTYPE PIC S9(4) COMP-5 VALUE +456.
77 VARGTYPE PIC S9(4) COMP-5 VALUE +464.
77 GTYPE PIC S9(4) COMP-5 VALUE +468.
77 LVARGTYP PIC S9(4) COMP-5 VALUE +472.
77 FLOATYPE PIC S9(4) COMP-5 VALUE +480.
77 DECTYPE PIC S9(4) COMP-5 VALUE +484.
77 INTTYPE PIC S9(4) COMP-5 VALUE +496.
77 HWTYPE PIC S9(4) COMP-5 VALUE +500.
77 DATETYP PIC S9(4) COMP-5 VALUE +384.
77 TIMETYP PIC S9(4) COMP-5 VALUE +388.
77 TIMESTMP PIC S9(4) COMP-5 VALUE +392.
*
01 RECPTR POINTER.
01 RECNUM REDEFINES RECPTR PICTURE S9(8) COMPUTATIONAL.
01 IRECPTR POINTER.
01 IRECNUM REDEFINES IRECPTR PICTURE S9(8) COMPUTATIONAL.
01 I PICTURE S9(4) COMPUTATIONAL.
01 J PICTURE S9(4) COMPUTATIONAL.
01 DUMMY PICTURE S9(4) COMPUTATIONAL.
01 MYTYPE PICTURE S9(4) COMPUTATIONAL.
01 COLUMN-IND PICTURE S9(4) COMPUTATIONAL.
01 COLUMN-LEN PICTURE S9(4) COMPUTATIONAL.
01 COLUMN-PREC PICTURE S9(4) COMPUTATIONAL.
01 COLUMN-SCALE PICTURE S9(4) COMPUTATIONAL.
01 INDCOUNT PIC S9(4) COMPUTATIONAL.
01 ROWCOUNT PIC S9(4) COMPUTATIONAL.
01 ERR-FOUND PICTURE X(1).
01 WORKAREA2.
02 WORKINDPTR POINTER OCCURS 750 TIMES.
*****************************************************
* DECLARE CURSOR AND STATEMENT FOR DYNAMIC SQL
*****************************************************
*
EXEC SQL DECLARE DT CURSOR FOR SEL END-EXEC.
EXEC SQL DECLARE SEL STATEMENT END-EXEC.
*
*****************************************************
* SQL INCLUDE FOR SQLCA *
*****************************************************
EXEC SQL INCLUDE SQLCA END-EXEC.
*
77 ONE PIC S9(4) COMP-5 VALUE +1.
77 TWO PIC S9(4) COMP-5 VALUE +2.
77 FOUR PIC S9(4) COMP-5 VALUE +4.
77 QMARK PIC X(1) VALUE '?'.
*
LINKAGE SECTION.
01 LINKAREA-IND.
02 IND PIC S9(4) COMP-5 OCCURS 750 TIMES.
01 LINKAREA-REC.
02 REC1-LEN PIC S9(8) COMP.
02 REC1-CHAR PIC X(1) OCCURS 1 TO 32700 TIMES
DEPENDING ON REC1-LEN.
01 LINKAREA-QMARK.
02 INDREC PIC X(1).
/
PROCEDURE DIVISION USING LINKAREA-IND LINKAREA-REC.
*
OUTPUT SYSPRINT
OUTPUT SYSREC01.
* **WRITE HEADER
WRITE MSGREC FROM HEADER
AFTER ADVANCING 2 LINES.
* **GET FIRST INPUT
READ SYSIN RECORD INTO IOAREA.
* **MAIN ROUTINE
PERFORM PROCESS-INPUT THROUGH IND-RESULT.
*
PROG-END.
* **CLOSE FILES
CLOSE SYSIN
SYSPRINT
SYSREC01.
GOBACK.
/
***************************************************************
* *
* PERFORMED SECTION: *
* PROCESSING FOR THE TABLE OR VIEW JUST READ *
* *
***************************************************************
PROCESS-INPUT.
*
MOVE TNAME TO STMTTAB.
MOVE STMTBLD TO STMTCHAR.
MOVE +750 TO SQLN.
EXEC SQL PREPARE SEL INTO :SQLDA FROM :STMTBUF END-EXEC.
***************************************************************
* *
* SET UP ADDRESSES IN THE SQLDA FOR DATA. *
* *
***************************************************************
IF SQLD = ZERO THEN
WRITE MSGREC FROM MSGNOCOL
AFTER ADVANCING 2 LINES
MOVE 'Y' TO ERR-FOUND
GO TO IND-RESULT.
MOVE ZERO TO ROWCOUNT.
MOVE ZERO TO REC1-LEN.
SET RECPTR TO IRECPTR.
MOVE ONE TO I.
PERFORM COLADDR UNTIL I > SQLD.
****************************************************************
* *
* SET LENGTH OF OUTPUT RECORD. *
* EXEC SQL OPEN DT END-EXEC. *
* DO WHILE SQLCODE IS 0. *
* EXEC SQL FETCH DT USING DESCRIPTOR :SQLDA END-EXEC. *
* ADD IN MARKERS TO DENOTE NULLS. *
* WRITE THE DATA TO SYSREC01. *
* INCREMENT DATA RECORD COUNTER. *
* END. *
* *
****************************************************************
* **OPEN CURSOR
EXEC SQL OPEN DT END-EXEC.
PERFORM BLANK-REC.
EXEC SQL FETCH DT USING DESCRIPTOR :SQLDA END-EXEC.
* **NO ROWS FOUND
* **PRINT ERROR MESSAGE
IF SQLCODE = NOT-FOUND
WRITE MSGREC FROM MSG-NOROW
AFTER ADVANCING 2 LINES
628 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
MOVE 'Y' TO ERR-FOUND
ELSE
* **WRITE ROW AND
* **CONTINUE UNTIL
* **NO MORE ROWS
PERFORM WRITE-AND-FETCH
UNTIL SQLCODE IS NOT EQUAL TO ZERO.
*
EXEC SQL WHENEVER NOT FOUND GOTO CLOSEDT END-EXEC.
*
CLOSEDT.
EXEC SQL CLOSE DT END-EXEC.
*
****************************************************************
* *
* INDICATE THE RESULTS OF THE UNLOAD OPERATION. *
* *
****************************************************************
IND-RESULT.
IF ERR-FOUND = 'N' THEN
MOVE TNAME TO TABLENAM
MOVE ROWCOUNT TO ROWS
WRITE MSGREC FROM UNLOADED
AFTER ADVANCING 2 LINES
ELSE
WRITE MSGREC FROM MSG-OTHER-ERR
AFTER ADVANCING 2 LINES
MOVE +0012 TO RETURN-CODE
GO TO PROG-END.
*
WRITE-AND-FETCH.
* ADD IN MARKERS TO DENOTE NULLS.
MOVE ONE TO INDCOUNT.
PERFORM NULLCHK UNTIL INDCOUNT = SQLD.
MOVE REC1-LEN TO REC01-LEN.
WRITE REC01 FROM LINKAREA-REC.
ADD ONE TO ROWCOUNT.
PERFORM BLANK-REC.
EXEC SQL FETCH DT USING DESCRIPTOR :SQLDA END-EXEC.
*
NULLCHK.
IF IND(INDCOUNT) < 0 THEN
SET ADDRESS OF LINKAREA-QMARK TO WORKINDPTR(INDCOUNT)
MOVE QMARK TO INDREC.
ADD ONE TO INDCOUNT.
*****************************************************
* BLANK OUT RECORD TEXT FIRST *
*****************************************************
BLANK-REC.
MOVE ONE TO J.
PERFORM BLANK-MORE UNTIL J > REC1-LEN.
BLANK-MORE.
MOVE ' ' TO REC1-CHAR(J).
ADD ONE TO J.
*
COLADDR.
SET SQLDATA(I) TO RECPTR.
****************************************************************
*
* DETERMINE THE LENGTH OF THIS COLUMN (COLUMN-LEN)
* THIS DEPENDS UPON THE DATA TYPE. MOST DATA TYPES HAVE
* THE LENGTH SET, BUT VARCHAR, GRAPHIC, VARGRAPHIC, AND
* DECIMAL DATA NEED TO HAVE THE BYTES CALCULATED.
* THE NULL ATTRIBUTE MUST BE SEPARATED TO SIMPLIFY MATTERS.
*
****************************************************************
MOVE SQLLEN(I) TO COLUMN-LEN.
* COLUMN-IND IS 0 FOR NO NULLS AND 1 FOR NULLS
DIVIDE SQLTYPE(I) BY TWO GIVING DUMMY REMAINDER COLUMN-IND.
* MYTYPE IS JUST THE SQLTYPE WITHOUT THE NULL BIT
MOVE SQLTYPE(I) TO MYTYPE.
SUBTRACT COLUMN-IND FROM MYTYPE.
* SET THE COLUMN LENGTH, DEPENDENT UPON DATA TYPE
EVALUATE MYTYPE
WHEN CHARTYPE CONTINUE,
WHEN DATETYP CONTINUE,
WHEN TIMETYP CONTINUE,
WHEN TIMESTMP CONTINUE,
WHEN FLOATYPE CONTINUE,
WHEN VARCTYPE
ADD TWO TO COLUMN-LEN,
WHEN VARLTYPE
630 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
*****************************************************
ERROR-PRINT.
WRITE MSGREC FROM ERROR-TEXT (ERROR-INDEX)
AFTER ADVANCING 1 LINE.
Related concepts
Program directories for Db2 12 (Db2 for z/OS in IBM Documentation)
IDENTIFICATION DIVISION.
PROGRAM-ID. TWOPHASE.
AUTHOR.
REMARKS.
*****************************************************************
* *
* MODULE NAME = TWOPHASE *
* *
* DESCRIPTIVE NAME = DB2 SAMPLE APPLICATION USING *
* TWO PHASE COMMIT AND THE DRDA DISTRIBUTED *
* ACCESS METHOD WITH CONNECT STATEMENTS *
* *
* COPYRIGHT = 5665-DB2 (C) COPYRIGHT IBM CORP 1982, 1989 *
* REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083 *
* *
* STATUS = VERSION 5 *
* *
* FUNCTION = THIS MODULE DEMONSTRATES DISTRIBUTED DATA ACCESS *
* USING 2 PHASE COMMIT BY TRANSFERRING AN EMPLOYEE *
* FROM ONE LOCATION TO ANOTHER. *
* *
* NOTE: THIS PROGRAM ASSUMES THE EXISTENCE OF THE *
* TABLE SYSADM.EMP AT LOCATIONS STLEC1 AND *
* STLEC2. *
* *
* MODULE TYPE = COBOL PROGRAM *
* PROCESSOR = DB2 PRECOMPILER, ENTERPRISE COBOL FOR Z/OS *
* MODULE SIZE = SEE LINK EDIT *
* ATTRIBUTES = NOT REENTRANT OR REUSABLE *
* *
* ENTRY POINT = *
* PURPOSE = TO ILLUSTRATE 2 PHASE COMMIT *
* LINKAGE = INVOKE FROM DSN RUN *
* INPUT = NONE *
* OUTPUT = *
* SYMBOLIC LABEL/NAME = SYSPRINT *
* DESCRIPTION = PRINT OUT THE DESCRIPTION OF EACH *
* STEP AND THE RESULTANT SQLCA *
* *
* EXIT NORMAL = RETURN CODE 0 FROM NORMAL COMPLETION *
* *
* EXIT ERROR = NONE *
* *
* EXTERNAL REFERENCES = *
* ROUTINE SERVICES = NONE *
* DATA-AREAS = NONE *
* CONTROL-BLOCKS = *
* SQLCA - SQL COMMUNICATION AREA *
* *
* TABLES = NONE *
* *
* CHANGE-ACTIVITY = NONE *
* *
* *
* *
* PSEUDOCODE *
* *
* MAINLINE. *
* Perform CONNECT-TO-SITE-1 to establish *
* a connection to the local connection. *
* FETCH-DELETE-SITE-1. *
* Provide a text description of the following step. *
* Fetch information about the transferring employee. *
* Print the SQLCA out. *
* If the information was retrieved successfully Then *
* Do. *
* | Perform DELETE-SITE-1 to delete the employee *
* | at this site. *
* End if the information was retrieved successfully. *
* *
* DELETE-SITE-1. *
* Provide a text description of the following step. *
* Delete the information about the transferring employee *
* from this site. *
* Print the SQLCA out. *
* *
* CLOSE-CURSOR-SITE-1. *
* Provide a text description of the following step. *
* Close the cursor used to retrieve information about *
* the transferring employee. *
* Print the SQLCA out. *
* *
* UPDATE-ADDRESS. *
* Update the address of the employee. *
* Update the city of the employee. *
* Update the location of the employee. *
* *
* CONNECT-TO-SITE-2. *
* Provide a text description of the following step. *
632 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* Establish a connection to the location where the *
* employee is transferring to. *
* Print the SQLCA out. *
* *
* PROCESS-SITE-2. *
* Provide a text description of the following step. *
* Insert the employee information at the location where *
* the employee is being transferred to. *
* Print the SQLCA out. *
* *
* COMMIT-WORK. *
* COMMIT all the changes made to STLEC1 and STLEC2. *
* *
*****************************************************************
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT PRINTER, ASSIGN TO S-OUT1.
DATA DIVISION.
FILE SECTION.
FD PRINTER
RECORD CONTAINS 120 CHARACTERS
DATA RECORD IS PRT-TC-RESULTS
LABEL RECORD IS OMITTED.
01 PRT-TC-RESULTS.
03 PRT-BLANK PIC X(120).
WORKING-STORAGE SECTION.
*****************************************************************
* Variable declarations *
*****************************************************************
01 H-EMPTBL.
05 H-EMPNO PIC X(6).
05 H-NAME.
49 H-NAME-LN PIC S9(4) COMP-5.
49 H-NAME-DA PIC X(32).
05 H-ADDRESS.
49 H-ADDRESS-LN PIC S9(4) COMP-5.
49 H-ADDRESS-DA PIC X(36).
05 H-CITY.
49 H-CITY-LN PIC S9(4) COMP-5.
49 H-CITY-DA PIC X(36).
05 H-EMPLOC PIC X(4).
05 H-SSNO PIC X(11).
05 H-BORN PIC X(10).
05 H-SEX PIC X(1).
05 H-HIRED PIC X(10).
05 H-DEPTNO PIC X(3).
05 H-JOBCODE PIC S9(3)V COMP-3.
05 H-SRATE PIC S9(5) COMP.
05 H-EDUC PIC S9(5) COMP.
05 H-SAL PIC S9(6)V9(2) COMP-3.
05 H-VALIDCHK PIC S9(6)V COMP-3.
01 H-EMPTBL-IND-TABLE.
02 H-EMPTBL-IND PIC S9(4) COMP-5 OCCURS 15 TIMES.
*****************************************************************
* Includes for the variables used in the COBOL standard *
* language procedures and the SQLCA. *
*****************************************************************
*****************************************************************
* Declaration for the table that contains employee information *
*****************************************************************
*****************************************************************
* Constants *
*****************************************************************
*****************************************************************
* Declaration of the cursor that will be used to retrieve *
* information about a transferring employee *
*****************************************************************
PROCEDURE DIVISION.
A101-HOUSE-KEEPING.
OPEN OUTPUT PRINTER.
*****************************************************************
* An employee is transferring from location STLEC1 to STLEC2. *
* Retrieve information about the employee from STLEC1, delete *
* the employee from STLEC1 and insert the employee at STLEC2 *
* using the information obtained from STLEC1. *
*****************************************************************
MAINLINE.
PERFORM CONNECT-TO-SITE-1
IF SQLCODE IS EQUAL TO 0
PERFORM PROCESS-CURSOR-SITE-1
IF SQLCODE IS EQUAL TO 0
PERFORM UPDATE-ADDRESS
PERFORM CONNECT-TO-SITE-2
IF SQLCODE IS EQUAL TO 0
PERFORM PROCESS-SITE-2.
PERFORM COMMIT-WORK.
PROG-END.
CLOSE PRINTER.
GOBACK.
*****************************************************************
* Establish a connection to STLEC1 *
*****************************************************************
CONNECT-TO-SITE-1.
*****************************************************************
* When a connection has been established successfully at STLEC1,*
* open the cursor that will be used to retrieve information *
* about the transferring employee. *
*****************************************************************
634 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
PROCESS-CURSOR-SITE-1.
*****************************************************************
* Retrieve information about the transferring employee. *
* Provided that the employee exists, perform DELETE-SITE-1 to *
* delete the employee from STLEC1. *
*****************************************************************
FETCH-DELETE-SITE-1.
*****************************************************************
* Delete the employee from STLEC1. *
*****************************************************************
DELETE-SITE-1.
*****************************************************************
* Close the cursor used to retrieve information about the *
* transferring employee. *
*****************************************************************
CLOSE-CURSOR-SITE-1.
*****************************************************************
* Update certain employee information in order to make it *
* current. *
*****************************************************************
UPDATE-ADDRESS.
MOVE TEMP-ADDRESS-LN TO H-ADDRESS-LN.
MOVE '1500 NEW STREET' TO H-ADDRESS-DA.
MOVE TEMP-CITY-LN TO H-CITY-LN.
MOVE 'NEW CITY, CA 97804' TO H-CITY-DA.
MOVE 'SJCA' TO H-EMPLOC.
*****************************************************************
* Establish a connection to STLEC2 *
*****************************************************************
CONNECT-TO-SITE-2.
*****************************************************************
* Using the employee information that was retrieved from STLEC1 *
* and updated previously, insert the employee at STLEC2. *
*****************************************************************
PROCESS-SITE-2.
*****************************************************************
* COMMIT any changes that were made at STLEC1 and STLEC2. *
*****************************************************************
COMMIT-WORK.
*****************************************************************
* Include COBOL standard language procedures *
*****************************************************************
INCLUDE-SUBS.
EXEC SQL INCLUDE COBSSUB END-EXEC.
IDENTIFICATION DIVISION.
PROGRAM-ID. TWOPHASE.
AUTHOR.
REMARKS.
*****************************************************************
* *
* MODULE NAME = TWOPHASE *
* *
* DESCRIPTIVE NAME = DB2 SAMPLE APPLICATION USING *
* TWO PHASE COMMIT AND DRDA WITH *
* ALIASES FOR THREE-PART NAMES *
* *
* FUNCTION = THIS MODULE DEMONSTRATES DISTRIBUTED DATA ACCESS *
* USING 2 PHASE COMMIT BY TRANSFERRING AN EMPLOYEE *
* FROM ONE LOCATION TO ANOTHER. *
* *
* NOTE: THIS PROGRAM ASSUMES THE EXISTENCE OF THE *
636 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* TABLE SYSADM.ALLEMPLOYEES AT LOCATIONS STLEC1
* AND STLEC2. *
* *
* MODULE TYPE = COBOL PROGRAM *
* PROCESSOR = DB2 PRECOMPILER, ENTERPRISE COBOL FOR Z/OS *
* MODULE SIZE = SEE LINK EDIT *
* ATTRIBUTES = NOT REENTRANT OR REUSABLE *
* *
* ENTRY POINT = *
* PURPOSE = TO ILLUSTRATE 2 PHASE COMMIT *
* LINKAGE = INVOKE FROM DSN RUN *
* INPUT = NONE *
* OUTPUT = *
* SYMBOLIC LABEL/NAME = SYSPRINT *
* DESCRIPTION = PRINT OUT THE DESCRIPTION OF EACH *
* STEP AND THE RESULTANT SQLCA *
* *
* EXIT NORMAL = RETURN CODE 0 FROM NORMAL COMPLETION *
* *
* EXIT ERROR = NONE *
* *
* EXTERNAL REFERENCES = *
* ROUTINE SERVICES = NONE *
* DATA-AREAS = NONE *
* CONTROL-BLOCKS = *
* SQLCA - SQL COMMUNICATION AREA *
* *
* TABLES = NONE *
* *
* CHANGE-ACTIVITY = NONE *
* *
* *
* *
* PSEUDOCODE *
* *
* MAINLINE. *
* Perform PROCESS-CURSOR-SITE-1 to obtain the information *
* about an employee that is transferring to another *
* location. *
* If the information about the employee was obtained *
* successfully Then *
* Do. *
* | Perform UPDATE-ADDRESS to update the information to *
* | contain current information about the employee. *
* | Perform PROCESS-SITE-2 to insert the employee *
* | information at the location where the employee is *
* | transferring to. *
* End if the employee information was obtained *
* successfully. *
* Perform COMMIT-WORK to COMMIT the changes made to STLEC1 *
* and STLEC2. *
* *
* PROG-END. *
* Close the printer. *
* Return. *
* *
* PROCESS-CURSOR-SITE-1. *
* Provide a text description of the following step. *
* Open a cursor that will be used to retrieve information *
* about the transferring employee from this site. *
* Print the SQLCA out. *
* If the cursor was opened successfully Then *
* Do. *
* | Perform FETCH-DELETE-SITE-1 to retrieve and *
* | delete the information about the transferring *
* | employee from this site. *
* | Perform CLOSE-CURSOR-SITE-1 to close the cursor. *
* End if the cursor was opened successfully. *
* *
* FETCH-DELETE-SITE-1. *
* Provide a text description of the following step. *
* Fetch information about the transferring employee. *
* Print the SQLCA out. *
* If the information was retrieved successfully Then *
* Do. *
* | Perform DELETE-SITE-1 to delete the employee *
* | at this site. *
* End if the information was retrieved successfully. *
* *
* DELETE-SITE-1. *
* Provide a text description of the following step. *
* Delete the information about the transferring employee *
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT PRINTER, ASSIGN TO S-OUT1.
DATA DIVISION.
FILE SECTION.
FD PRINTER
RECORD CONTAINS 120 CHARACTERS
DATA RECORD IS PRT-TC-RESULTS
LABEL RECORD IS OMITTED.
01 PRT-TC-RESULTS.
03 PRT-BLANK PIC X(120).
WORKING-STORAGE SECTION.
*****************************************************************
* Variable declarations *
*****************************************************************
01 H-EMPTBL.
05 H-EMPNO PIC X(6).
05 H-NAME.
49 H-NAME-LN PIC S9(4) COMP-5.
49 H-NAME-DA PIC X(32).
05 H-ADDRESS.
49 H-ADDRESS-LN PIC S9(4) COMP-5.
49 H-ADDRESS-DA PIC X(36).
05 H-CITY.
49 H-CITY-LN PIC S9(4) COMP-5.
49 H-CITY-DA PIC X(36).
05 H-EMPLOC PIC X(4).
05 H-SSNO PIC X(11).
05 H-BORN PIC X(10).
05 H-SEX PIC X(1).
05 H-HIRED PIC X(10).
05 H-DEPTNO PIC X(3).
05 H-JOBCODE PIC S9(3)V COMP-3.
05 H-SRATE PIC S9(5) COMP.
05 H-EDUC PIC S9(5) COMP.
05 H-SAL PIC S9(6)V9(2) COMP-3.
05 H-VALIDCHK PIC S9(6)V COMP-3.
01 H-EMPTBL-IND-TABLE.
02 H-EMPTBL-IND PIC S9(4) COMP-5 OCCURS 15 TIMES.
*****************************************************************
* Includes for the variables used in the COBOL standard *
* language procedures and the SQLCA. *
*****************************************************************
*****************************************************************
* Declaration for the table that contains employee information *
*****************************************************************
638 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
EXEC SQL DECLARE SYSADM.ALLEMPLOYEES TABLE
(EMPNO CHAR(6) NOT NULL,
NAME VARCHAR(32),
ADDRESS VARCHAR(36) ,
CITY VARCHAR(36) ,
EMPLOC CHAR(4) NOT NULL,
SSNO CHAR(11),
BORN DATE,
SEX CHAR(1),
HIRED CHAR(10),
DEPTNO CHAR(3) NOT NULL,
JOBCODE DECIMAL(3),
SRATE SMALLINT,
EDUC SMALLINT,
SAL DECIMAL(8,2) NOT NULL,
VALCHK DECIMAL(6))
END-EXEC.
*****************************************************************
* Constants *
*****************************************************************
*****************************************************************
* Declaration of the cursor that will be used to retrieve *
* information about a transferring employee *
* EC1EMP is the alias for STLEC1.SYSADM.ALLEMPLOYEES *
*****************************************************************
*****************************************************************
* An employee is transferring from location STLEC1 to STLEC2. *
* Retrieve information about the employee from STLEC1, delete *
* the employee from STLEC1 and insert the employee at STLEC2 *
* using the information obtained from STLEC1. *
*****************************************************************
MAINLINE.
PERFORM PROCESS-CURSOR-SITE-1
IF SQLCODE IS EQUAL TO 0
PERFORM UPDATE-ADDRESS
PERFORM PROCESS-SITE-2.
PERFORM COMMIT-WORK.
PROG-END.
CLOSE PRINTER.
GOBACK.
*****************************************************************
* Open the cursor that will be used to retrieve information *
* about the transferring employee. *
*****************************************************************
PROCESS-CURSOR-SITE-1.
*****************************************************************
* Retrieve information about the transferring employee. *
* Provided that the employee exists, perform DELETE-SITE-1 to *
FETCH-DELETE-SITE-1.
*****************************************************************
* Delete the employee from STLEC1. *
*****************************************************************
DELETE-SITE-1.
*****************************************************************
* Close the cursor used to retrieve information about the *
* transferring employee. *
*****************************************************************
CLOSE-CURSOR-SITE-1.
*****************************************************************
* Update certain employee information in order to make it *
* current. *
*****************************************************************
UPDATE-ADDRESS.
MOVE TEMP-ADDRESS-LN TO H-ADDRESS-LN.
MOVE '1500 NEW STREET' TO H-ADDRESS-DA.
MOVE TEMP-CITY-LN TO H-CITY-LN.
MOVE 'NEW CITY, CA 97804' TO H-CITY-DA.
MOVE 'SJCA' TO H-EMPLOC.
****************************************************************
* Using the employee information that was retrieved from STLEC1 *
* and updated previously, insert the employee at STLEC2. *
* EC2EMP is the alias for STLEC2.SYSADM.ALLEMPLOYEES *
*****************************************************************
PROCESS-SITE-2.
640 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
*****************************************************************
* COMMIT any changes that were made at STLEC1 and STLEC2. *
*****************************************************************
COMMIT-WORK.
*****************************************************************
* Include COBOL standard language procedures *
*****************************************************************
INCLUDE-SUBS.
EXEC SQL INCLUDE COBSSUB END-EXEC.
The following example is a COBOL stored procedure with linkage convention GENERAL WITH NULLS.
CBL RENT
IDENTIFICATION DIVISION.
PROGRAM-ID. GETPRML.
AUTHOR. EXAMPLE.
DATE-WRITTEN. 03/25/98.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
DATA DIVISION.
FILE SECTION.
*
WORKING-STORAGE SECTION.
*
642 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Example COBOL stored procedure with a GENERAL linkage convention
You can call a stored procedure that uses the GENERAL linkage convention from a COBOL program.
This example stored procedure does the following:
• Searches the catalog table SYSROUTINES for a row matching the input parameters from the client
program. The two input parameters contain values for NAME and SCHEMA.
• Searches the Db2 catalog table SYSTABLES for all tables in which the value of CREATOR matches the
value of input parameter SCHEMA. The stored procedure uses a cursor to return the table names.
This stored procedure is able to return a NULL value for the output host variables.
The linkage convention for this stored procedure is GENERAL.
The output parameters from this stored procedure contain the SQLCODE from the SELECT operation, and
the value of the RUNOPTS column retrieved from the SYSROUTINES table.
The CREATE PROCEDURE statement for this stored procedure might look like this:
CBL RENT
IDENTIFICATION DIVISION.
PROGRAM-ID. GETPRML.
AUTHOR. EXAMPLE.
DATE-WRITTEN. 03/25/98.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
DATA DIVISION.
FILE SECTION.
WORKING-STORAGE SECTION.
***************************************************
* DECLARE CURSOR FOR RETURNING RESULT SETS
***************************************************
*
EXEC SQL DECLARE C1 CURSOR WITH RETURN FOR
SELECT NAME FROM SYSIBM.SYSTABLES WHERE CREATOR=:INSCHEMA
END-EXEC.
*
LINKAGE SECTION.
***************************************************
* DECLARE THE INPUT PARAMETERS FOR THE PROCEDURE
***************************************************
01 PROCNM PIC X(18).
01 SCHEMA PIC X(8).
*******************************************************
* DECLARE THE OUTPUT PARAMETERS FOR THE PROCEDURE
*******************************************************
01 OUT-CODE PIC S9(9) USAGE BINARY.
01 PARMLST.
*******************************************************
* Issue the SQL SELECT against the SYSIBM.SYSROUTINES
* DB2 catalog table.
*******************************************************
EXEC SQL
SELECT RUNOPTS INTO :PARMLST
FROM SYSIBM.ROUTINES
WHERE NAME=:PROCNM AND
SCHEMA=:SCHEMA
END-EXEC.
*******************************************************
* COPY SQLCODE INTO THE OUTPUT PARAMETER AREA
*******************************************************
MOVE SQLCODE TO OUT-CODE.
*******************************************************
* OPEN CURSOR C1 TO CAUSE DB2 TO RETURN A RESULT SET
* TO THE CALLER.
*******************************************************
EXEC SQL OPEN C1
END-EXEC.
PROG-END.
GOBACK.
IDENTIFICATION DIVISION.
PROGRAM-ID. CALPRML.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT REPOUT
ASSIGN TO UT-S-SYSPRINT.
DATA DIVISION.
FILE SECTION.
FD REPOUT
RECORD CONTAINS 127 CHARACTERS
LABEL RECORDS ARE OMITTED
DATA RECORD IS REPREC.
01 REPREC PIC X(127).
WORKING-STORAGE SECTION.
*****************************************************
* MESSAGES FOR SQL CALL *
*****************************************************
01 SQLREC.
02 BADMSG PIC X(34) VALUE
' SQL CALL FAILED DUE TO SQLCODE = '.
02 BADCODE PIC +9(5) USAGE DISPLAY.
02 FILLER PIC X(80) VALUE SPACES.
01 ERRMREC.
02 ERRMMSG PIC X(12) VALUE ' SQLERRMC = '.
02 ERRMCODE PIC X(70).
02 FILLER PIC X(38) VALUE SPACES.
01 CALLREC.
02 CALLMSG PIC X(28) VALUE
' GETPRML FAILED DUE TO RC = '.
02 CALLCODE PIC +9(5) USAGE DISPLAY.
02 FILLER PIC X(42) VALUE SPACES.
01 RSLTREC.
02 RSLTMSG PIC X(15) VALUE
644 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
' TABLE NAME IS '.
02 TBLNAME PIC X(18) VALUE SPACES.
02 FILLER PIC X(87) VALUE SPACES.
*****************************************************
* WORK AREAS *
*****************************************************
01 PROCNM PIC X(18).
01 SCHEMA PIC X(8).
01 OUT-CODE PIC S9(9) USAGE COMP-5.
01 PARMLST.
49 PARMLEN PIC S9(4) USAGE COMP-5.
49 PARMTXT PIC X(254).
01 PARMBUF REDEFINES PARMLST.
49 PARBLEN PIC S9(4) USAGE COMP-5.
49 PARMARRY PIC X(127) OCCURS 2 TIMES.
01 NAME.
49 NAMELEN PIC S9(4) USAGE COMP-5.
49 NAMETXT PIC X(18).
77 PARMIND PIC S9(4) COMP-5.
77 I PIC S9(4) COMP-5.
77 NUMLINES PIC S9(4) COMP-5.
*****************************************************
* DECLARE A RESULT SET LOCATOR FOR THE RESULT SET *
* THAT IS RETURNED. *
*****************************************************
01 LOC USAGE SQL TYPE IS
RESULT-SET-LOCATOR VARYING.
*****************************************************
* SQL INCLUDE FOR SQLCA *
*****************************************************
EXEC SQL INCLUDE SQLCA END-EXEC.
PROCEDURE DIVISION.
*------------------
PROG-START.
OPEN OUTPUT REPOUT.
* OPEN OUTPUT FILE
MOVE 'DSN8EP2 ' TO PROCNM.
* INPUT PARAMETER -- PROCEDURE TO BE FOUND
MOVE SPACES TO SCHEMA.
* INPUT PARAMETER -- SCHEMA IN SYSROUTINES
MOVE -1 TO PARMIND.
* THE PARMLST PARAMETER IS AN OUTPUT PARM.
* MARK PARMLST PARAMETER AS NULL, SO THE DB2
* REQUESTER DOES NOT HAVE TO SEND THE ENTIRE
* PARMLST VARIABLE TO THE SERVER. THIS
* HELPS REDUCE NETWORK I/O TIME, BECAUSE
* PARMLST IS FAIRLY LARGE.
EXEC SQL
CALL GETPRML(:PROCNM,
:SCHEMA,
:OUT-CODE,
:PARMLST INDICATOR :PARMIND)
END-EXEC.
Procedure
Choose one of the following actions:
Option Description
To define the SQL a. Code the SQLCA directly in the program or use the following SQL INCLUDE
communications statement to request a standard SQLCA declaration:
area:
EXEC SQL INCLUDE SQLCA
646 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Option Description
To declare SQLCODE a. Declare the SQLCODE variable within a BEGIN DECLARE SECTION statement
and SQLSTATE host and an END DECLARE SECTION statement in your program declarations as
variables: PIC S9(9) COMP-5.
When you use the Db2 precompiler, you can declare a stand-alone SQLCODE
variable in either the WORKING-STORAGE SECTION or LINKAGE SECTION.
When you use the Db2 coprocessor, you can declare a stand-alone SQLCODE
variable in the WORKING-STORAGE SECTION, LINKAGE SECTION or LOCAL-
STORAGE SECTION.
b. Declare the SQLSTATE variable within a BEGIN DECLARE SECTION statement
and an END DECLARE SECTION statement in your program declarations as
PICTURE X(5).
Restriction: Do not declare an SQLSTATE variable as an element of a structure.
Requirement: After you declare the SQLCODE and SQLSTATE variables, ensure
that all SQL statements in the program are within the scope of the declaration of
these variables.
Related tasks
Checking the execution of SQL statements
After executing an SQL statement, your program should check for any errors before you commit the data
and handle the errors that they represent.
Checking the execution of SQL statements by using the SQLCA
One way to check whether an SQL statement executed successfully is to use the SQL communication area
(SQLCA). This area is set apart for communication with Db2.
Checking the execution of SQL statements by using SQLCODE and SQLSTATE
Whenever an SQL statement executes, the SQLCODE and SQLSTATE fields of the SQLCA receive a return
code.
Defining the items that your program can use to check whether an SQL statement executed successfully
If your program contains SQL statements, the program should define some infrastructure so that it can
check whether the statements executed successfully. You can either include an SQL communications
area (SQLCA), which contains SQLCODE and SQLSTATE variables, or declare individual SQLCODE and
SQLSTATE host variables.
Procedure
Perform one of the following actions:
• Code the SQLDA declarations directly in your program. When you use the Db2 precompiler, you
must place SQLDA declarations in the WORKING-STORAGE SECTION or LINKAGE SECTION of
your program, wherever you can specify a record description entry in that section. When you use
the Db2 coprocessor, you must place SQLDA declarations in the WORKING-STORAGE SECTION,
LINKAGE SECTION or LOCAL-STORAGE SECTION of your program, wherever you can specify a record
description entry in that section.
• Call a subroutine that is written in C, PL/I, or assembler language and that uses the INCLUDE SQLDA
statement to define the SQLDA. The subroutine can also include SQL statements for any dynamic SQL
functions that you need.
Restriction:
Procedure
To declare host variables, host-variable arrays, and host structures:
1. Declare the variables according to the following rules and guidelines:
• You must explicitly declare all host variables and host-variable arrays that are used in SQL
statements in the WORKING-STORAGE SECTION or LINKAGE SECTION of your program's DATA
DIVISION.
• You must explicitly declare each host variable and host-variable array before using them in an SQL
statement.
• You can specify OCCURS when defining an indicator structure, a host-variable array, or an indicator
variable array. You cannot specify OCCURS for any other type of host variable.
• You cannot implicitly declare any host variables through default typing or by using the IMPLICIT
statement.
• If you specify the ONEPASS SQL processing option, you must explicitly declare each host variable
and each host-variable array before using them in an SQL statement. If you specify the TWOPASS
precompiler option, you must declare each host variable before using it in the DECLARE CURSOR
statement.
• If you specify the STDSQL(YES) SQL processing option, you must precede the host language
statements that define the host variables and host-variable arrays with the BEGIN DECLARE
SECTION statement and follow the host language statements with the END DECLARE SECTION
statement. Otherwise, these statements are optional.
• Ensure that any SQL statement that uses a host variable or host-variable array is within the scope of
the statement that declares that variable or array.
• If you are using the Db2 precompiler, ensure that the names of host variables and host-variable
arrays are unique within the program, even if the variables and variable arrays are in different blocks,
classes, procedures, functions, or subroutines. You can qualify the names with a structure name to
make them unique.
2. Optional: Define any associated indicator variables, arrays, and structures.
Related tasks
Declaring host variables and indicator variables
648 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
You can use host variables and indicator variables in SQL statements in your program to pass data
between Db2 and your application.
77 IS
1 USAGE
level-1
2
COMPUTATIONAL-1 .
COMP-1 IS
3 VALUE numeric-constant
COMPUTATIONAL-2
COMP-2
Notes:
1 level-1 indicates a COBOL level between 2 and 48.
2 COMPUTATIONAL-1 and COMP-1 are equivalent.
3 COMPUTATIONAL-2 and COMP-2 are equivalent.
The following diagram shows the syntax for declaring integer and small integer host variables.
IS
01 variable-name PICTURE S9(4)
77 PIC S9999
1
level-1 S9(9)
S999999999
S9(18)
2
BINARY
IS COMPUTATIONAL-4
USAGE
COMP-4
3
COMPUTATIONAL-5
COMP-5
COMPUTATIONAL
COMP
4
.
IS
VALUE numeric-constant
Notes:
1 level-1 indicates a COBOL level between 2 and 48.
2 The COBOL binary integer data types BINARY, COMPUTATIONAL, COMP, COMPUTATIONAL-4, and
COMP-4 are equivalent. A portable application should code BINARY, because COMP, COMPUTATIONAL-4,
COMP-4, COMPUTATIONAL-5, and COMP-5 are IBM extensions that are not supported in International
Organization for Standardization (ISO)/ANSI COBOL. Declarations that use COMP-5 in applications that
use the TRUNC(OPT) compile option can avoid truncation of data that does not fit in the associated picture
clause.
3 COMPUTATIONAL-5 (and COMP-5) are equivalent to the other COBOL binary integer data types if you
650 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
The following diagram shows the syntax for declaring decimal host variables.
IS
2
01 variable-name PICTURE picture-string
77 PIC
1
level-1
IS
USAGE
3
PACKED-DECIMAL
COMPUTATIONAL-3
COMP-3
IS CHARACTER
DISPLAY SIGN LEADING SEPARATE
NATIONAL
.
IS
VALUE numeric-constant
Notes:
1 level-1 indicates a COBOL level between 2 and 48.
2 The picture-string that is associated with SIGN LEADING SEPARATE must have the form S9(i)V9(d) (or
S9...9V9...9, with i and d instances of 9 or S9...9V with i instances of 9).
3 PACKED-DECIMAL, COMPUTATIONAL-3, and COMP-3 are equivalent. The picture-string that is that is
associated with these types must have the form S9(i)V9(d) (or S9...9V9...9, with i and d instances of 9) or
S9(i)V.
In COBOL, you declare the SMALLINT and INTEGER data types as a number of decimal digits. Db2 uses
the full size of the integers (in a way that is similar to processing with the TRUNC(BIN) compiler option)
and can place larger values in the host variable than would be allowed in the specified number of digits in
the COBOL declaration. If you compile with TRUNC(OPT) or TRUNC(STD), ensure that the size of numbers
in your application is within the declared number of digits.
For small integers that can exceed 9999, use S9(4) COMP-5 or compile with TRUNC(BIN). For large
integers that can exceed 999,999,999, use S9(10) COMP-3 to obtain the decimal data type. If you use
COBOL for integers that exceed the COBOL PICTURE, specify the column as decimal to ensure that the
data types match and perform well.
If you are using a COBOL compiler that does not support decimal numbers of more than 18 digits, use one
of the following data types to hold values of greater than 18 digits:
• A decimal variable with a precision less than or equal to 18, if the actual data values fit. If you retrieve
a decimal value into a decimal variable with a scale that is less than the source column in the database,
the fractional part of the value might be truncated.
• An integer or a floating-point variable, which converts the value. If you use an integer variable, you lose
the fractional part of the number. If the decimal number might exceed the maximum value for an integer
or if you want to preserve a fractional value, use a floating-point variable. Floating-point numbers are
approximations of real numbers. Therefore, when you assign a decimal number to a floating-point
variable, the result might be different from the original number.
• A character-string host variable. Use the CHAR function to retrieve a decimal value into it.
Restriction: The SQL data type DECFLOAT has no equivalent in COBOL.
IS
2
01 variable-name PICTURE picture-string
77 PIC
1
level-1
DISPLAY
IS
USAGE
.
IS
VALUE character-constant
Notes:
1level-1 indicates a COBOL level between 2 and 48.
2The picture-string that is associated with these forms must be X(m) (or XX…X, with m instances of X),
where m is up to COBOL's limitation. However, the maximum length of the CHAR data type (fixed-length
character string) in Db2 is 255 bytes.
The following diagrams show the syntax for declaring varying-length character host variables.
01 variable-name .
1
level-1
Notes:
1 level-1 indicates a COBOL level between 2 and 48.
652 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
IS
1 2 3
49 var-1 PICTURE S9(4)
PIC S9999
BINARY
IS COMPUTATIONAL-4
USAGE
COMP-4
COMPUTATIONAL-5
COMP-5
COMPUTATIONAL
COMP
.
IS
VALUE numeric-constant
Notes:
1 You cannot use an intervening REDEFINE at level 49.
2 You cannot directly reference var-1 as a host variable.
3 Db2 uses the full length of the S9(4) BINARY variable even though COBOL with TRUNC(STD) recognizes
values up to only 9999. This behavior can cause data truncation errors when COBOL statements execute
and might effectively limit the maximum length of variable-length character strings to 9999. Consider
using the TRUNC(BIN) compiler option or USAGE COMP-5 to avoid data truncation.
IS
1 2 3
49 var-2 PICTURE picture-string
PIC
DISPLAY
IS
USAGE
.
IS
VALUE character-constant
Notes:
1 You cannot use an intervening REDEFINE at level 49.
2 You cannot directly reference var-2 as a host variable.
3 For fixed-length strings, the picture-string must be X(m) (or XX, with m instances of X), where mis up to
COBOL's limitation. However, the maximum length of the VARCHAR data type in Db2 varies depending on
the data page size.
IS
2
01 variable-name PICTURE picture-string
77 PIC
1
level-1
DISPLAY-1
IS 3
NATIONAL
USAGE
.
IS
VALUE graphic-constant
Notes:
1 level-1 indicates a COBOL level between 2 and 48.
2 For fixed-length strings, the picture-string is G(m) or N(m) (or, m instances of GG...G or NN...N), where m
is up to COBOL's limitation. However, the maximum length of the GRAPHIC data type (fixed-length graphic
string) in Db2 is 127 double-bytes.
3 Use USAGE NATIONAL only for Unicode UTF-16 data. In the picture-string for USAGE NATIONAL, you
must use N in place of G. USAGE NATIONAL is supported only by the Db2 coprocessor.
The following diagrams show the syntax for declaring varying-length graphic host variables.
01 variable-name .
1
level-1
Notes:
1 level-1 indicates a COBOL level between 2 and 48.
IS
1 2
49 var-1 PICTURE S9(4)
PIC S9999
BINARY
IS COMPUTATIONAL-4
USAGE
COMP-4
COMPUTATIONAL-5
COMP-5
COMPUTATIONAL
COMP
.
IS
VALUE numeric-constant
654 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Notes:
1You cannot directly reference var-1 as a host variable.
2Db2 uses the full length of the S9(4) BINARY variable even though COBOL with TRUNC(STD) recognizes
values up to only 9999. This behavior can cause data truncation errors when COBOL statements execute
and might effectively limit the maximum length of variable-length character strings to 9999. Consider
using the TRUNC(BIN) compiler option or USAGE COMP-5 to avoid data truncation.
IS
1 2
49 var-2 PICTURE picture-string
PIC
DISPLAY-1
IS 3
NATIONAL
USAGE
.
IS
VALUE graphic-constant
Notes:
1 You cannot directly reference var-2 as a host variable.
2 For fixed-length strings, the picture-string is G(m) or N(m) (or, m instances of GG...G or NN...N), where
m is up to COBOL's limitation. However, the maximum length of the VARGRAPHIC data type in Db2 varies
depending on the data page size.
3 Use USAGE NATIONAL only for Unicode UTF-16 data. In the picture-string for USAGE NATIONAL, you
must use N in place of G. USAGE NATIONAL is supported only by the Db2 coprocessor.
IS
USAGE
01 variable-name SQL TYPE IS BINARY
VARBINARY
BINARY VARYING
1
( length ) .
Notes:
1 For BINARY host variables, the length must be in the range 1 - 255. For VARBINARY host variables, the
length must be in the range1 - 32704.
Table 109. Examples of BINARY and VARBINARY variable declarations for COBOL
Variable declaration that you include in your COBOL Corresponding variable that Db2 generates in the
program output source member
VARYING .
Table Locators
The following diagram shows the syntax for declaring table locators.
table-name AS LOCATOR .
Notes:
1 level-1 indicates a COBOL level between 2 and 48.
656 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
01 variable-name SQL TYPE IS
level-1 IS
USAGE
BLOB K
CLOB
DBCLOB
BLOB-LOCATOR
CLOB-LOCATOR
DBCLOB-LOCATOR
BLOB-FILE
CLOB-FILE
DBCLOB-FILE
BLOB K
CLOB
DBCLOB
BLOB-FILE
CLOB-FILE
DBCLOB-FILE
Notes:
1 level-1 indicates a COBOL level between 2 and 48.
Notes:
1 level-1 indicates a COBOL level between 2 and 48.
Related concepts
Host variables
Use host variables to pass a single data item between Db2 and your application.
Related tasks
Storing LOB data in a table
Db2 handles LOB data differently than it handles other kinds of data. As a result, in some cases, you need
to take additional actions when you define LOB columns and insert the LOB data.
Related reference
Limits in Db2 for z/OS (Db2 SQL)
658 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
1
level-1 variable-name COMPUTATIONAL-1
IS 2
COMP-1
USAGE
COMPUTATIONAL-2
3
COMP-2
4
OCCURS dimension
TIMES
.
IS
VALUE numeric-constant
Notes:
1 level-1 indicates a COBOL level between 2 and 48.
2 COMPUTATIONAL-1 and COMP-1 are equivalent.
3 COMPUTATIONAL-2 and COMP-2 are equivalent.
4 dimension must be an integer constant between 1 and 32767.
The following diagram shows the syntax for declaring integer and small integer host-variable arrays.
IS
1
level-1 variable-name PICTURE S9(4)
PIC S9999
S9(9)
S999999999
2 4
BINARY OCCURS dimension
IS COMPUTATIONAL-4
USAGE
COMP-4
COMPUTATIONAL-5
3
COMP-5
COMPUTATIONAL
COMP
5
.
TIMES IS
VALUE numeric-constant
Notes:
1 level-1 indicates a COBOL level between 2 and 48.
2 The COBOL binary integer data types BINARY, COMPUTATIONAL, COMP, COMPUTATIONAL-4, and
COMP-4 are equivalent.
3 COMPUTATIONAL-5 (and COMP-5) are equivalent to the other COBOL binary integer data types if you
IS
1
level-1 variable-name PICTURE picture-string
PIC
IS
USAGE
2
PACKED-DECIMAL
COMPUTATIONAL-3
COMP-3
IS CHARACTER
3
DISPLAY SIGN LEADING SEPARATE
NATIONAL
4
OCCURS dimension
TIMES
.
IS
VALUE numeric-constant
Notes:
1 level-1 indicates a COBOL level between 2 and 48.
2 PACKED-DECIMAL, COMPUTATIONAL-3, and COMP-3 are equivalent. The picture-string that is associated
with these types must have the form S9(i)V9(d) (or S9...9V9...9, with i and d instances of 9) or S9(i)V.
3 The picture-string that is associated with SIGN LEADING SEPARATE must have the form S9(i)V9(d) (or
660 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
IS
1 2
level-1 variable-name PICTURE picture-string
PIC
3
OCCURS dimension
DISPLAY
IS
USAGE
.
TIMES IS
VALUE character-constant
Notes:
1 level-1 indicates a COBOL level between 2 and 48.
2 The picture-string must be in the form X(m) (or XX…X, with m instances of X), where 1 <= m <= 32767 for
fixed-length strings. However, the maximum length of the CHAR data type (fixed-length character string) in
Db2 is 255 bytes.
3 dimension must be an integer constant between 1 and 32767.
The following diagrams show the syntax for declaring varying-length character string arrays.
1 2
level-1 variable-name OCCURS dimension .
TIMES
Notes:
1 level-1 indicates a COBOL level between 2 and 48.
2 dimension must be an integer constant between 1 and 32767.
IS
1 2
49 var-1 PICTURE S9(4)
PIC S9999
BINARY SYNCHRONIZED
IS COMPUTATIONAL-4 SYNC
USAGE
COMP-4
COMPUTATIONAL-5
COMP-5
COMPUTATIONAL
COMP
.
IS
VALUE numeric-constant
Notes:
1You cannot directly reference var-1 as a host-variable array.
2Db2 uses the full length of the S9(4) BINARY variable even though COBOL with TRUNC(STD) recognizes
values up to only 9999. This behavior can cause data truncation errors when COBOL statements execute
IS
1 2
49 var-2 PICTURE picture-string
PIC
DISPLAY
IS
USAGE
3
.
IS
VALUE character-constant
Notes:
1 You cannot directly reference var-2 as a host-variable array.
2 The picture-string must be in the form X(m) (or XX…X, with m instances of X), where 1 <= m <= 32767
for fixed-length strings; for other strings, m cannot be greater than the maximum size of a varying-length
character string.
3 You cannot use an intervening REDEFINE at level 49.
The following example shows declarations of a fixed-length character array and a varying-length
character array.
01 OUTPUT-VARS.
05 NAME OCCURS 10 TIMES.
49 NAME-LEN PIC S9(4) COMP-4 SYNC.
49 NAME-DATA PIC X(40).
05 SERIAL-NUMBER PIC S9(9) COMP-4 OCCURS 10 TIMES.
662 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
IS
1 2
level-1 variable-name PICTURE picture-string USAGE
PIC
IS
5
DISPLAY-1 OCCURS dimension
34 TIMES
NATIONAL
.
IS
VALUE graphic-constant
Notes:
1 level-1 indicates a COBOL level between 2 and 48.
2 For fixed-length strings, the format for picture-string is G(m) or N(m) (or, m instances of GG...G or NN...N),
where 1 <= m <= 127; for other strings, m cannot be greater than the maximum size of a varying-length
graphic string.
3 Use USAGE NATIONAL only for Unicode UTF-16 data. In the picture-string for USAGE NATIONAL, you
The following diagrams show the syntax for declaring varying-length graphic string arrays.
1 2
level-1 variable-name OCCURS dimension .
TIMES
Notes:
1 level-1 indicates a COBOL level between 2 and 48.
2 dimension must be an integer constant between 1 and 32767.
IS
1 2
49 var-1 PICTURE S9(4)
PIC S9999
BINARY SYNCHRONIZED
IS COMPUTATIONAL-4 SYNC
USAGE
COMP-4
COMPUTATIONAL-5
COMP-5
COMPUTATIONAL
COMP
.
IS
VALUE numeric-constant
Notes:
IS IS
1 2
49 var-2 PICTURE picture-string USAGE
PIC
DISPLAY-1 .
34 IS
NATIONAL
VALUE graphic-constant
Notes:
1 You cannot directly reference var-2 as a host-variable array.
2 For fixed-length strings, the format for picture-string is G(m) or N(m) (or, m instances of GG...G or NN...N),
where 1 <= m <= 127; for other strings, m cannot be greater than the maximum size of a varying-length
graphic string.
3 Use USAGE NATIONAL only for Unicode UTF-16 data. In the picture-string for USAGE NATIONAL, you
1 2
level-1 variable-name SQL TYPE IS BINARY ( length )
BINARY VARYING
VARBINARY
3
OCCURS dimension .
TIMES
Notes:
1 level-1 indicates a COBOL level between 2 and 48.
2 For BINARY host variables, the length must be in the range 1 to 255. For VARBINARY host variables, the
length must be in the range 1 to 32704.
3 dimension must be an integer constant between 1 and 32767.
664 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
1
level-1 variable-name SQL TYPE IS
IS
USAGE
BLOB K
CLOB
DBCLOB
BLOB-LOCATOR
CLOB-LOCATOR
DBCLOB-LOCATOR
BLOB-FILE
CLOB-FILE
DBCLOB-FILE
2
OCCURS dimension .
TIMES
Notes:
1 level-1 indicates a COBOL level between 2 and 48.
2 dimension must be an integer constant between 1 and 32767.
1
level-1 variable-name SQL TYPE IS XML AS
IS
USAGE
BLOB K
CLOB
DBCLOB
BLOB-FILE
CLOB-FILE
DBCLOB-FILE
2
OCCURS dimension .
TIMES
Notes:
1
level-1 variable-name SQL TYPE IS ROWID OCCURS
IS
USAGE
2
dimension .
TIMES
Notes:
1 level-1 indicates a COBOL level between 2 and 48.
2 dimension must be an integer constant between 1 and 32767.
Related concepts
Using host-variable arrays in SQL statements
Use host-variable arrays in embedded SQL statements to represent values that the program does not
know until the query is executed. Host-variable arrays are useful for storing a set of retrieved values or for
passing a set of values that are to be inserted into a table.
Host-variable arrays
You can use host-variable arrays to pass a data array between Db2 and your application. A host-variable
array is a data array that is declared in the host language to be used within an SQL statement.
Host-variable arrays in PL/I, C, C++, and COBOL (Db2 SQL)
Related tasks
Inserting multiple rows of data from host-variable arrays
Use host-variable arrays in your INSERT statement when you do not know at least some of the values to
insert until the program runs.
Storing LOB data in a table
Db2 handles LOB data differently than it handles other kinds of data. As a result, in some cases, you need
to take additional actions when you define LOB columns and insert the LOB data.
Retrieving multiple rows of data into host-variable arrays
If you know that your query returns multiple rows, you can specify host-variable arrays to store the
retrieved column values.
666 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
– Any SQL statement (except SQL INCLUDE)
– Any SQL statement within an included member
When the Db2 precompiler encounters one of the preceding items in a host structure, it considers the
structure to be complete.
When you write an SQL statement that contains a qualified host variable name (perhaps to identify a field
within a structure), use the name of the structure followed by a period and the name of the field. For
example, for structure B that contains field C1, specify B.C1 rather than C1 OF B or C1 IN B.
Host structures
The following diagram shows the syntax for declaring host structures.
1
level-1 variable-name .
23
level-2 var-1 numeric-usage .
IS
PICTURE integer-decimal-usage .
PIC picture-string
char-inner-variable .
varchar-inner-variables
vargraphic-inner-variables
Notes:
1 level-1 indicates a COBOL level between 1 and 47.
2 level-2 indicates a COBOL level between 2 and 48.
3 For elements within a structure, use any level 02 through 48 (rather than 01 or 77), up to a maximum of
two levels.
4 Using a FILLER or optional FILLER item within a host structure declaration can invalidate the whole
structure.
COMP-2
IS
VALUE constant
IS
USAGE
BINARY
COMPUTATIONAL-4
COMP-4
COMPUTATIONAL-5
COMP-5
COMPUTATIONAL
COMP
PACKED-DECIMAL
COMPUTATIONAL-3
COMP-3
IS
DISPLAY SIGN LEADING SEPARATE
NATIONAL CHARACTER
IS
VALUE constant
668 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
IS
PICTURE picture-string
PIC
DISPLAY IS
IS VALUE constant
USAGE
IS
1
49 var-2 PICTURE S9(4)
PIC S9999 IS
USAGE
BINARY .
COMPUTATIONAL-4 IS
VALUE numeric-constant
COMP-4
COMPUTATIONAL-5
COMP-5
COMPUTATIONAL
COMP
Notes:
1 The number 49 has a special meaning to Db2. Do not specify another number.
IS
49 var-3 PICTURE picture-string
PIC
DISPLAY
IS
USAGE
.
IS
VALUE character-constant
PIC S9999 IS
USAGE
BINARY .
COMPUTATIONAL-4 IS
VALUE numeric-constant
COMP-4
COMPUTATIONAL-5
COMP-5
COMPUTATIONAL
COMP
IS
1
49 var-5 PICTURE picture-string
PIC IS
USAGE
23
DISPLAY-1 .
NATIONAL IS
VALUE graphic-constant
Notes:
1 For fixed-length strings, the format of picture-string is G(m) or N(m) (or, m instances of GG...G or NN...N),
where 1 <= m <= 127; for other strings, m cannot be greater than the maximum size of a varying-length
graphic string.
2 Use USAGE NATIONAL for only Unicode UTF-16 data. In the picture-string for USAGE NATIONAL, you
670 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
SQL TYPE IS BINARY LARGE OBJECT ( length )
BLOB K
CLOB
DBCLOB
BLOB-LOCATOR
CLOB-LOCATOR
DBCLOB-LOCATOR
BLOB-FILE
CLOB-FILE
DBCLOB-FILE
BLOB K
CLOB
DBCLOB
BLOB-FILE
CLOB-FILE
DBCLOB-FILE
Example
In the following example, B is the name of a host structure that contains the elementary items C1 and C2.
01 A
02 B
03 C1 PICTURE ...
03 C2 PICTURE ...
IS
01 variable-name PICTURE S9(4)
77 PIC S9999
BINARY
IS COMPUTATIONAL-4
USAGE
COMP-4
COMPUTATIONAL-5
COMP-5
COMPUTATIONAL
COMP
.
IS
VALUE constant
The following diagram shows the syntax for declaring an indicator array in COBOL.
IS
1
level-1 variable-name PICTURE S9(4)
PIC S9999
2
BINARY OCCURS dimension
IS COMPUTATIONAL-4
USAGE
COMP-4
COMPUTATIONAL-5
COMP-5
COMPUTATIONAL
COMP
.
TIMES IS
VALUE constant
Notes:
1 level-1 must be an integer between 2 and 48.
2 dimension must be an integer constant between 1 and 32767.
672 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Examples
Example 1:
The following example shows declarations of three variables, with an indicator variable declaration for
each host variable.
The following FETCH statement retrieves values from a table into the three host variables. If a table
column value is null, Db2 sets the corresponding indicator variable to -1.
Example 2:
The following example shows a declaration of a host structure, and a corresponding structure that
contains an indicator array with the same number of elements as the number of variables in the host
structure.
01 CLS.
10 DAYVAR PIC S9(4) BINARY.
10 BGNVAR PIC X(8).
10 ENDVAR PIC X(8).
01 CLS-IND-STRUCT.
02 CLS-IND PIC S9(4) BINARY OCCURS 3 TIMES.
The following FETCH statement retrieves values from a table into the host structure. If a table value is
null, Db2 sets the corresponding indicator array element to -1.
Related concepts
Indicator variables, arrays, and structures
An indicator variable is associated with a particular host variable. Each indicator variable contains a small
integer value that indicates some information about the associated host variable. Indicator arrays and
structures serve the same purpose for host-variable arrays and structures.
Related tasks
Inserting null values into columns by using indicator variables or arrays
If you need to insert null values into a column, using an indicator variable or array is an easy way to do so.
An indicator variable or array is associated with a particular host variable or host-variable array.
Procedure
Use one or more of the following items:
Example
Assume that the COBOL SQLCCSID compiler option is specified and that the COBOL CODEPAGE compiler
option is specified as CODEPAGE(1141). The following code shows how you can control the CCSID:
DATA DIVISION.
01 HV1 PIC N(10) USAGE NATIONAL.
01 HV2 PIC X(20) USAGE DISPLAY.
01 HV3 PIC X(30) USAGE DISPLAY.
...
EXEC SQL
DECLARE :HV3 VARIABLE CCSID 1047
END-EXEC.
...
PROCEDURE DIVISION.
...
EXEC SQL
SELECT C1, C2, C3 INTO :HV1, :HV2, :HV3 FROM T1
END-EXEC.
674 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
HV3
1047
Related reference
Host variables in COBOL
In COBOL programs, you can specify numeric, character, graphic, binary, LOB, XML, and ROWID host
variables. You can also specify result set and table locators and LOB and XML file reference variables.
Compiler options (COBOL) (Enterprise COBOL for z/OS Programming Guide)
Table 110. SQL data types, SQLLEN values, and SQLTYPE values that the precompiler uses for host variables in
COBOL programs
COBOL host variable data SQLTYPE of host
type variable1 SQLLEN of host variable SQL data type
COMP-1 480 4 REAL or FLOAT(n) 1≤n≤21
COMP-2 480 8 DOUBLE PRECISION, or
FLOAT(n) 22≤n≤53
S9(i)V9(d) COMP-3 or 484 i+d in byte 1, d in byte 2 DECIMAL(i+d,d) or
S9(i)V9(d) PACKED-DECIMAL NUMERIC(i+d,d)
S9(i)V9(d) DISPLAY SIGN 504 i+d in byte 1, d in byte 2 No exact equivalent.
LEADING SEPARATE Use DECIMAL(i+d,d) or
NUMERIC(i+d,d)
S9(i)V9(d) NATIONAL SIGN 504 i+d in byte 1, d in byte 2 No exact equivalent.
LEADING SEPARATE Use DECIMAL(i+d,d) or
NUMERIC(i+d,d)
S9(4) COMP-4, S9(4) COMP-5, 500 2 SMALLINT
S9(4) COMP, or S9(4) BINARY
S9(9) COMP-4, S9(9) COMP-5, 496 4 INTEGER
S9(9) COMP, or S9(9) BINARY
S9(18) COMP-4, S9(18) 492 8 BIGINT
COMP-5, S9(18) COMP, or
S9(18) BINARY
Fixed-length character data 452 n CHAR(n)
Varying-length character data 448 n VARCHAR(n)
1≤n≤255
Varying-length character data 456 m VARCHAR(m)
m>255
Fixed-length graphic data 468 m GRAPHIC(m)
Varying-length graphic data 464 m VARGRAPHIC(m)
1≤m≤127
676 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 110. SQL data types, SQLLEN values, and SQLTYPE values that the precompiler uses for host variables in
COBOL programs (continued)
COBOL host variable data SQLTYPE of host
type variable1 SQLLEN of host variable SQL data type
Notes:
1. If a host variable includes an indicator variable, the SQLTYPE value is the base SQLTYPE value plus 1.
2. Do not use this data type as a column type.
3. m is the number of double-byte characters.
The following table shows equivalent COBOL host variables for each SQL data type. Use this table to
determine the COBOL data type for host variables that you define to receive output from the database. For
example, if you retrieve TIMESTAMP data, you can define a fixed-length character string variable of length
n
This table shows direct conversions between SQL data types and COBOL data types. However, a number
of SQL data types are compatible. When you do assignments or comparisons of data that have compatible
data types, Db2 converts those compatible data types.
Table 111. COBOL host variable equivalents that you can use when retrieving data of a particular SQL data type
SQL data type COBOL host variable equivalent Notes
SMALLINT
S9(4) COMP-4,
S9(4) COMP-5,
S9(4) COMP,
or S9(4) BINARY
INTEGER
S9(9) COMP-4,
S9(9) COMP-5,
S9(9) COMP,
or S9(9) BINARY
01 VAR-NAME.
49 VAR-LEN PIC S9(4)
USAGE BINARY.
49 VAR-TEXT PIC X(n).
TIME Fixed-length character string of length n. If you are using a time exit routine, n is
For example, determined by that routine. Otherwise, n
must be at least 6; to include seconds, n
01 VAR-NAME PIC X(n). must be at least 8.
TIMESTAMP(p) p > 0 Fixed-length character string of length n. n must be at least 19. To include
For example, fractional seconds, n must be 20+x
where x is the number of fractional
01 VAR-NAME PIC X(n seconds to include; if x is less than
p, truncation occurs on the fractional
).
seconds part.
678 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 111. COBOL host variable equivalents that you can use when retrieving data of a particular SQL data type
(continued)
SQL data type COBOL host variable equivalent Notes
TIMESTAMP(0) WITH Varying-length character string. For The inner variables must have a level of
TIME ZONE example, 49. n must be at least 25.
01 VAR-NAME.
49 VAR-LEN PIC S9(4) USAGE
BINARY. 49 VAR-TEXT PIC
X(n).
TIMESTAMP(p) WITH Varying-length character string. For The inner variables must have a level of
TIME ZONE example, 49. n must be at least 26+p.
01 VAR-NAME.
49 VAR-LEN PIC S9(4) USAGE
BINARY. 49 VAR-TEXT PIC
X(n).
Result set locator Use this data type only for receiving
SQL TYPE IS
RESULT-SET-LOCATOR result sets. Do not use this data type as
a column type.
Table locator Use this data type only in a user-defined
SQL TYPE IS
TABLE LIKE function or stored procedure to receive
table-name rows of a transition table. Do not use
AS LOCATOR
this data type as a column type.
CLOB(i) 1≤n≤2147483647
USAGE IS SQL TYPE IS
CLOB(i)
The following table shows the COBOL language definitions to use in COBOL stored procedures and
user-defined functions, when the parameter data types in the routine definitions are LOBs, ROWIDs, or
locators. For other parameter data types, the COBOL language definitions are the same as those in Table
111 on page 677 above.
Table 112. Equivalent COBOL declarations for LOBs, ROWIDs, and locators in user-defined routine
definitions
SQL data type in definition COBOL declaration
BLOB(n) 01 var.
49 var-LENGTH PIC S9(9) COMP-5.
49 var-DATA PIC X(n).
CLOB(n) 01 var.
49 var-LENGTH PIC S9(9) COMP-5.
49 var-DATA PIC X(n).
DBCLOB(n) 01 var.
49 var-LENGTH PIC S9(9) COMP-5.
49 var-DATA PIC G(n) DISPLAY-1.
ROWID 01 var.
49 var-LEN PIC S9(4) COMP-5.
49 var-TEXT PIC X(40).
680 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Related concepts
Compatibility of SQL and language data types
The host variable data types that are used in SQL statements must be compatible with the data types of
the columns with which you intend to use them.
LOB host variable, LOB locator, and LOB file reference variable declarations
When you write applications to manipulate LOB data, you need to declare host variables to hold the LOB
data or LOB locator. Alternatively, you need to declare LOB file reference variables to point to the LOB
data.
Host variable data types for XML data in embedded SQL applications (Db2 Programming for XML)
Procedure
To request more information about SQL errors from Cobol programs, use the following approaches:
• You can use the MESSAGE_TEXT condition item field of the GET DIAGNOSTICS statement to convert
an SQL return code into a text message. Programs that require long token message support should
code the GET DIAGNOSTICS statement instead of DSNTIAR.
• You can use the subroutine DSNTIAR to convert an SQL return code into a text message. DSNTIAR
takes data from the SQLCA, formats it into a message, and places the result in a message output area
that you provide in your application program.
DSNTIAR syntax
DSNTIAR has the following syntax:
01 ERROR-MESSAGE.
02 ERROR-LEN PIC S9(4) COMP-5 VALUE +1320.
02 ERROR-TEXT PIC X(132) OCCURS 10 TIMES
INDEXED BY ERROR-INDEX.
77 ERROR-TEXT-LEN PIC S9(9) COMP-5 VALUE +132.
⋮
CALL 'DSNTIAR' USING SQLCA ERROR-MESSAGE ERROR-TEXT-LEN.
where ERROR-MESSAGE is the name of the message output area containing 10 lines of length
132 each, and ERROR-TEXT-LEN is the length of each line.
lrecl
A fullword containing the logical record length of output messages, between 72 and 240.
An example of calling DSNTIAR from an application appears in the Db2 sample assembler program
DSN8BC3, which is contained in the library DSN8C10.
• If your CICS application requires CICS storage handling, you must use the subroutine DSNTIAC instead
of DSNTIAR.
If you call DSNTIAR dynamically from a CICS COBOL application program, be sure you do the
following:
– Compile the COBOL application with the NODYNAM option.
– Define DSNTIAR in the CSD.
DSNTIAC syntax
If your CICS application requires CICS storage handling, you must use the subroutine DSNTIAC
instead of DSNTIAR. DSNTIAC has the following syntax:
DSNTIAC parameters
DSNTIAC has extra parameters, which you must use for calls to routines that use CICS commands.
eib
EXEC interface block
commarea
communication area
For more information on these parameters, see the appropriate application programming guide for
CICS. The remaining parameter descriptions are the same as those for DSNTIAR. Both DSNTIAC
and DSNTIAR format the SQLCA in the same way.
You must define DSNTIA1 in the CSD. If you load DSNTIAR or DSNTIAC, you must also define them
in the CSD. For an example of CSD entry generation statements for use with DSNTIAC, see job
DSNTEJ5A.
The assembler source code for DSNTIAC and job DSNTEJ5A, which assembles and link-edits
DSNTIAC, are in the data set prefix.SDSNSAMP.
Related tasks
Handling SQL error codes
682 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Application programs can request more information about SQL error codes from Db2.
Related reference
GET DIAGNOSTICS (Db2 SQL)
EXEC SQL
C UPDATE DSN8C10.DEPT
C SET MGRNO = :MGRNUM
C WHERE DEPTNO = :INTDEPT
You cannot follow an SQL statement with another SQL statement or Fortran statement on the same line.
Fortran does not require blanks to delimit words within a statement, but the SQL language requires
blanks. The rules for embedded SQL follow the rules for SQL syntax, which require you to use one or more
blanks as a delimiter.
Comments
You can include Fortran comment lines within embedded SQL statements wherever you can use a
blank, except between the keywords EXEC and SQL. You can include SQL comments in any embedded
SQL statement. For more information, see SQL comments (Db2 SQL).
The Db2 precompiler does not support the exclamation point (!) as a comment recognition character
in Fortran programs.
Continuation for SQL statements
The line continuation rules for SQL statements are the same as those for Fortran statements, except
that you must specify EXEC SQL on one line. The SQL examples in this topic have Cs in the sixth
column to indicate that they are continuations of EXEC SQL.
Delimiters in Fortran
Delimit an SQL statement in your Fortran program with the beginning keyword EXEC SQL
and an end of line or end of last continued line.
Declaring tables and views
Your Fortran program should also include the DECLARE TABLE statement to describe each table and
view the program accesses.
Dynamic SQL in a Fortran program
In general, Fortran programs can easily handle dynamic SQL statements. SELECT statements can be
handled if the data types and the number of returned fields are fixed. If you want to use variable-list
SELECT statements, you need to use an SQLDA, as described in “Defining SQL descriptor areas
(SQLDA)” on page 472.
You can use a Fortran character variable in the statements PREPARE and EXECUTE IMMEDIATE, even
if it is fixed-length.
Including code
To include SQL statements or Fortran host variable declarations from a member of a partitioned data
set, use the following SQL statement in the source code where you want to include the statements:
684 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Defining the SQL communications area, SQLSTATE, and SQLCODE in Fortran
Fortran programs that contain SQL statements can include an SQL communications area (SQLCA) to check
whether an SQL statement executed successfully. Alternatively, these programs can declare individual
SQLCODE and SQLSTATE host variables.
Procedure
Choose one of the following actions:
Option Description
To define the a. Code the SQLCA directly in the program or use the following SQL INCLUDE
SQL communications statement to request a standard SQLCA declaration:
area:
EXEC SQL INCLUDE SQLCA
Db2 sets the SQLCODE and SQLSTATE values in the SQLCA after each SQL
statement executes. Your application should check these values to determine
whether the last SQL statement was successful.
To declare SQLCODE a. Declare the SQLCODE variable within a BEGIN DECLARE SECTION
and SQLSTATE host statement and an END DECLARE SECTION statement in your program
variables: declarations as INTEGER*4.
This variable can also be called SQLCOD.
b. Declare the SQLSTATE variable within a BEGIN DECLARE SECTION
statement and an END DECLARE SECTION statement in your program
declarations as CHARACTER*5.
This variable can also be called SQLCOD.
Restriction: Do not declare an SQLSTATE variable as an element of a structure.
Requirement: After you declare the SQLCODE and SQLSTATE variables, ensure
that all SQL statements in the program are within the scope of the declaration
of these variables.
Related tasks
Checking the execution of SQL statements
After executing an SQL statement, your program should check for any errors before you commit the data
and handle the errors that they represent.
Checking the execution of SQL statements by using the SQLCA
One way to check whether an SQL statement executed successfully is to use the SQL communication area
(SQLCA). This area is set apart for communication with Db2.
Checking the execution of SQL statements by using SQLCODE and SQLSTATE
Whenever an SQL statement executes, the SQLCODE and SQLSTATE fields of the SQLCA receive a return
code.
Defining the items that your program can use to check whether an SQL statement executed successfully
Procedure
Call a subroutine that is written in C, PL/I, or assembler language and that uses the INCLUDE SQLDA
statement to define the SQLDA. The subroutine can also include SQL statements for any dynamic SQL
functions that you need.
Restrictions:
• You must place SQLDA declarations before the first SQL statement that references the data descriptor,
unless you use the TWOPASS SQL processing option.
• You cannot use the SQL INCLUDE statement for the SQLDA, because it is not supported in COBOL.
Related tasks
Defining SQL descriptor areas (SQLDA)
If your program includes certain SQL statements, you must define at least one SQL descriptor area
(SQLDA). Depending on the context in which it is used, the SQLDA stores information about prepared SQL
statements or host variables. This information can then be read by either the application program or Db2.
Procedure
To declare host variables, host-variable arrays, and host structures:
1. Declare the variables according to the following rules and guidelines:
• When you declare a character host variable, do not use an expression to define the length of the
character variable. You can use a character host variable with an undefined length (for example,
CHARACTER *(*)). The length of any such variable is determined when the associated SQL statement
executes.
• Host variables must be scalar variables; they cannot be elements of vectors or arrays (subscripted
variables).
• Be careful when calling subroutines that might change the attributes of a host variable. Such
alteration can cause an error while the program is running.
• If you specify the ONEPASS SQL processing option, you must explicitly declare each host variable
and each host-variable array before using them in an SQL statement. If you specify the TWOPASS
precompiler option, you must declare each host variable before using it in the DECLARE CURSOR
statement.
• If you specify the STDSQL(YES) SQL processing option, you must precede the host language
statements that define the host variables and host-variable arrays with the BEGIN DECLARE
SECTION statement and follow the host language statements with the END DECLARE SECTION
statement. Otherwise, these statements are optional.
• Ensure that any SQL statement that uses a host variable or host-variable array is within the scope of
the statement that declares that variable or array.
686 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
• If you are using the Db2 precompiler, ensure that the names of host variables and host-variable
arrays are unique within the program, even if the variables and variable arrays are in different blocks,
classes, procedures, functions, or subroutines. You can qualify the names with a structure name to
make them unique.
2. Optional: Define any associated indicator variables, arrays, and structures.
Related tasks
Declaring host variables and indicator variables
You can use host variables and indicator variables in SQL statements in your program to pass data
between Db2 and your application.
INTEGER*2 variable-name
*4 / numeric-constant /
INTEGER
*4
REAL
REAL*8
DOUBLE PRECISION
CHARACTER variable-name
*n *n
/ character-constant /
SQL TYPE IS
BLOB K
CLOB
BLOB_LOCATOR
CLOB_LOCATOR
variable-name
688 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
ROWID host variables
The following diagram shows the syntax for declarations of ROWID variables.
Constants
The syntax for constants in Fortran programs differs from the syntax for constants in SQL statements in
the following ways:
• Fortran interprets a string of digits with a decimal point to be a real constant. An SQL statement
interprets such a string to be a decimal constant. Therefore, use exponent notation when specifying a
real (that is, floating-point) constant in an SQL statement.
• In Fortran, a real (floating-point) constant that has a length of 8 bytes uses a D as the exponent
indicator (for example, 3.14159D+04). An 8-byte floating-point constant in an SQL statement must use
an E (for example, 3.14159E+04).
Related concepts
Host variables
Use host variables to pass a single data item between Db2 and your application.
Using host variables in SQL statements
Use scalar host variables in embedded SQL statements to represent a single value. Host variables are
useful for storing retrieved data or for passing values that are to be assigned or used for comparisons.
Related tasks
Determining whether a retrieved value in a host variable is null or truncated
Before your application manipulates the data that was retrieved from Db2 into a host variable, determine
if the value is null. Also determine if it was truncated when assigned to the variable. You can use indicator
variables to obtain this information.
Inserting a single row by using a host variable
Use host variables in your INSERT statement when you don't know at least some of the values to insert
until the program runs.
Inserting null values into columns by using indicator variables or arrays
If you need to insert null values into a column, using an indicator variable or array is an easy way to do so.
An indicator variable or array is associated with a particular host variable or host-variable array.
Storing LOB data in a table
Db2 handles LOB data differently than it handles other kinds of data. As a result, in some cases, you need
to take additional actions when you define LOB columns and insert the LOB data.
Retrieving a single row of data into host variables
If you know that your query returns only one row, you can specify one or more host variables to contain
the column values of the retrieved row.
Updating data by using host variables
When you want to update a value in a Db2 table, but you do not know the exact value until the program
runs, use host variables. Db2 can change a table value to match the current value of the host variable.
INTEGER*2 variable-name
/ numeric-constant /
Example
The following example shows a FETCH statement with the declarations of the host variables that are
needed for the FETCH statement and their associated indicator variables.
CHARACTER*7 CLSCD
INTEGER*2 DAY
CHARACTER*8 BGN, END
INTEGER*2 DAYIND, BGNIND, ENDIND
Related concepts
Indicator variables, arrays, and structures
An indicator variable is associated with a particular host variable. Each indicator variable contains a small
integer value that indicates some information about the associated host variable. Indicator arrays and
structures serve the same purpose for host-variable arrays and structures.
Related tasks
Inserting null values into columns by using indicator variables or arrays
If you need to insert null values into a column, using an indicator variable or array is an easy way to do so.
An indicator variable or array is associated with a particular host variable or host-variable array.
Procedure
To request more information about SQL errors from Fortran programs, use the following approaches:
• You can use the subroutine DSNTIR to convert an SQL return code into a text message. DSNTIR builds
a parameter list and calls DSNTIAR for you.
DSNTIAR takes data from the SQLCA, formats it into a message, and places the result in a message
output area that you provide in your application program. For concepts and more information on the
behavior of DSNTIAR, see “Displaying SQLCA fields by calling DSNTIAR” on page 525.
DSNTIAR syntax
DSNTIAR has the following syntax:
DSNTIAR parameters
The DSNTIR parameters have the following meanings:
error-length
The total length of the message output area.
690 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
message
An output area, in VARCHAR format, in which DSNTIAR places the message text. The first
halfword contains the length of the remaining area; its minimum value is 240.
The output lines of text are put into this area. For example, you could specify the format of the
output area as:
where ERRLEN is the total length of the message output area, ERRTXT is the name of the
message output area, and ICODE is the return code.
return-code
Accepts a return code from DSNTIAR.
An example of calling DSNTIR (which then calls DSNTIAR) from an application appears in the Db2
sample assembler program DSN8BF3, which is contained in the library DSN8C10.SDSNSAMP. See
“Sample applications supplied with Db2 for z/OS” on page 1022 for instructions on how to access and
print the source code for the sample program.
• You can also use the MESSAGE_TEXT condition item field of the GET DIAGNOSTICS statement to
convert an SQL return code into a text message. Programs that require long token message support
should code the GET DIAGNOSTICS statement instead of DSNTIAR.
For more information about GET DIAGNOSTICS, see “Checking the execution of SQL statements by
using the GET DIAGNOSTICS statement ” on page 530.
Related tasks
Handling SQL error codes
Application programs can request more information about SQL error codes from Db2.
Related reference
GET DIAGNOSTICS (Db2 SQL)
Table 113. SQL data types, SQLLEN values, and SQLTYPE values that the precompiler uses for host variables in
Fortran programs
Fortran host variable data SQLTYPE of host
type variable1 SQLLEN of host variable SQL data type
INTEGER*2 500 2 SMALLINT
INTEGER*4 496 4 INTEGER
REAL*4 480 4 FLOAT (single precision)
REAL*8 480 8 FLOAT (double precision)
CHARACTER*n 452 n CHAR(n)
SQL TYPE IS 972 4 Result set locator. Do not use
RESULT_SET_LOCATOR this data type as a column
type.
Notes:
1. If a host variable includes an indicator variable, the SQLTYPE value is the base SQLTYPE value plus 1.
The following table shows equivalent Fortran host variables for each SQL data type. Use this table to
determine the Fortran data type for host variables that you define to receive output from the database.
For example, if you retrieve TIMESTAMP data, you can define a variable of type CHARACTER*n.
This table shows direct conversions between SQL data types and Fortran data types. However, a number
of SQL data types are compatible. When you do assignments or comparisons of data that have compatible
data types, Db2 converts those compatible data types.
Table 114. Fortran host variable equivalents that you can use when retrieving data of a particular SQL data type
SQL data type Fortran host variable equivalent Notes
SMALLINT INTEGER*2
INTEGER INTEGER*4
BIGINT not supported
DECIMAL(p,s) or no exact equivalent Use REAL*8
NUMERIC(p,s)
FLOAT(n) single precision REAL*4 1<=n<=21
FLOAT(n) double precision REAL*8 22<=n<=53
CHAR(n) CHARACTER*n 1<=n<=255
VARCHAR(n) no exact equivalent Use a character host variable that is
large enough to contain the largest
expected VARCHAR value.
BINARY not supported
VARBINARY not supported
GRAPHIC(n) not supported
VARGRAPHIC(n) not supported
DATE CHARACTER*n If you are using a date exit routine, n is
determined by that routine; otherwise, n
must be at least 10.
692 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 114. Fortran host variable equivalents that you can use when retrieving data of a particular SQL data type
(continued)
SQL data type Fortran host variable equivalent Notes
TIME CHARACTER*n If you are using a time exit routine, n is
determined by that routine. Otherwise, n
must be at least 6; to include seconds, n
must be at least 8.
TIMESTAMP CHARACTER*n n must be at least 19. To include
microseconds, n must be 26; if n is
less than 26, truncation occurs on the
microseconds part.
TIMESTAMP(0) CHARACTER*n n must be at least 19.
TIMESTAMP(p) p > 0 CHARACTER*n n must be at least 19. To include
fractional seconds, n must be 20+x
where x is the number of fractional
seconds to include; if x is less than
p, truncation occurs on the fractional
seconds part.
TIMESTAMP(p) WITH no exact equivalent Use a character host variable that is
TIME ZONE large enough to contain the largest
expected timestamp with time zone
value.
Result set locator SQL TYPE IS RESULT_SET_LOCATOR Use this data type only for receiving
result sets. Do not use this data type as
a column type.
BLOB locator SQL TYPE IS BLOB_LOCATOR Use this data type only to manipulate
data in BLOB columns. Do not use this
data type as a column type.1
CLOB locator SQL TYPE IS CLOB_LOCATOR Use this data type only to manipulate
data in CLOB columns. Do not use this
data type as a column type.1
DBCLOB locator not supported
BLOB(n) SQL TYPE IS BLOB(n) 1≤n≤21474836471
CLOB(n) SQL TYPE IS CLOB(n) 1≤n≤21474836471
DBCLOB(n) not supported
ROWID SQL TYPE IS ROWID
XML not supported
Related concepts
Compatibility of SQL and language data types
The host variable data types that are used in SQL statements must be compatible with the data types of
the columns with which you intend to use them.
LOB host variable, LOB locator, and LOB file reference variable declarations
Comments
You can include PL/I comments in embedded SQL statements wherever you can use a blank, except
between the keywords EXEC and SQL. You can also include SQL comments in any SQL statement. For
more information, see SQL comments (Db2 SQL).
To include DBCS characters in comments, you must delimit the characters by a shift-out and shift-in
control character; the first shift-in character in the DBCS string signals the end of the DBCS string.
Continuation for SQL statements
The line continuation rules for SQL statements are the same as those for other PL/I statements,
except that you must specify EXEC SQL on one line.
Delimiters for SQL statements
Delimit an SQL statement in your PL/I program with the beginning keyword EXEC SQL and a
Semicolon (;).
Declaring tables and views
Your PL/I program should include a DECLARE TABLE statement to describe each table and view the
program accesses. You can use the Db2 declarations generator (DCLGEN) to generate the DECLARE
TABLE statements.
Including code
You can use SQL statements or PL/I host variable declarations from a member of a partitioned
data set by using the following SQL statement in the source code where you want to include the
statements:
You cannot nest SQL INCLUDE statements. Do not use the PL/I %INCLUDE statement to include
SQL statements or host variable DCL statements. You must use the PL/I preprocessor to resolve any
%INCLUDE statements before you use the Db2 precompiler. Do not use PL/I preprocessor directives
within SQL statements.
Margins
Code SQL statements in columns 2 through 72, unless you have specified other margins to the
Db2 precompiler. If EXEC SQL starts before the specified left margin, the Db2 precompiler does not
recognize the SQL statement.
Names
You can use any valid PL/I name for a host variable. Do not use external entry names or access plan
names that begin with 'DSN', and do not use host variable names that begin with 'SQL'. These names
are reserved for Db2.
694 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Sequence numbers
The source statements that the Db2 precompiler generates do not include sequence numbers.
IEL0378I messages from the PL/I compiler identify lines of code without sequence numbers. You
can ignore these messages.
Statement labels
You can specify a statement label for executable SQL statements. However, the INCLUDE text-file-
name and END DECLARE SECTION statements cannot have statement labels.
WHENEVER statement
The target for the GOTO clause in an SQL statement WHENEVER must be a label in the PL/I source
code and must be within the scope of any SQL statements that WHENEVER affects.
Using double-byte character set (DBCS) characters
The following considerations apply to using DBCS in PL/I programs with SQL statements:
• If you use DBCS in the PL/I source, Db2 rules for the following language elements apply:
– Graphic strings
– Graphic string constants
– Host identifiers
– Mixed data in character strings
– MIXED DATA option
• The PL/I preprocessor transforms the format of DBCS constants. If you do not want that
transformation, run the Db2 precompiler before the preprocessor.
• If you use graphic string constants or mixed data in dynamically prepared SQL statements, and
if your application requires the PL/I Version 2 (or later) compiler, the dynamically prepared
statements must use the PL/I mixed constant format.
– If you prepare the statement from a host variable, change the string assignment to a PL/I mixed
string.
– If you prepare the statement from a PL/I string, change that to a host variable, and then change
the string assignment to a PL/I mixed string.
Example:
• If you want a DBCS identifier to resemble a PL/I graphic string, you must use a delimited identifier.
• If you include DBCS characters in comments, you must delimit the characters with a shift-out and
shift-in control character. The first shift-in character signals the end of the DBCS string.
• You can declare host variable names that use DBCS characters in PL/I application programs. The
rules for using DBCS variable names in PL/I follow existing rules for DBCS SQL ordinary identifiers,
except for length. The maximum length for a host variable is 128 Unicode bytes in Db2. For
information about the rules for DBCS SQL ordinary identifiers, see the information about SQL
identifiers.
Restrictions:
– DBCS variable names must contain DBCS characters only. Mixing single-byte character set (SBCS)
characters with DBCS characters in a DBCS variable name produces unpredictable results.
– A DBCS variable name cannot continue to the next line.
• The PL/I preprocessor changes non-Kanji DBCS characters into extended binary coded decimal
interchange code (EBCDIC) SBCS characters. To avoid this change, use Kanji DBCS characters for
DBCS variable names, or run the PL/I compiler without the PL/I preprocessor.
Special PL/I considerations
The following considerations apply to programs written in PL/I:
HVWC1 = '003100320033006100620063'WX;
Equivalent to:
HVWC1 = '123abc';
696 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
For parameter marker used in dynamic SQL, ensuring accurate CCSID for the corresponding
host variable is assigned/derived through DECLARE VARIABLE ... CCSID xxxx, ENCODING BIND
option or the installation default. The source CCSID has no influence on parameter marker.
Handling SQL error codes
PLI/I applications can request more information about SQL errors from Db2. For more information,
see “Handling SQL error codes in PL/I applications” on page 700.
Related concepts
DCLGEN (declarations generator)
Your program should declare the tables and views that it accesses. The Db2 declarations generator,
DCLGEN, produces these DECLARE statements for C, COBOL, and PL/I programs, so that you do not need
to code the statements yourself. DCLGEN also generates corresponding host variable structures.
Using host-variable arrays in SQL statements
Use host-variable arrays in embedded SQL statements to represent values that the program does not
know until the query is executed. Host-variable arrays are useful for storing a set of retrieved values or for
passing a set of values that are to be inserted into a table.
SQL identifiers (Db2 SQL)
Related tasks
Overview of programming applications that access Db2 for z/OS data
Applications that interact with Db2 must first connect to Db2. They can then read, add, or modify data or
manipulate Db2 objects.
Including dynamic SQL in your program
Dynamic SQL is prepared and executed while the program is running.
Handling SQL error codes
Application programs can request more information about SQL error codes from Db2.
Setting limits for system resource usage by using the resource limit facility (Db2 Performance)
/************************************************************/
/* Declare the parameters used to call the GETPRML */
/* stored procedure. */
/************************************************************/
DECLARE PROCNM CHAR(18), /* INPUT parm -- PROCEDURE name */
SCHEMA CHAR(8), /* INPUT parm -- User's schema */
OUT_CODE FIXED BIN(31),
/* OUTPUT -- SQLCODE from the */
/* SELECT operation. */
PARMLST CHAR(254) /* OUTPUT -- RUNOPTS for */
VARYING, /* the matching row in the */
/* catalog table SYSROUTINES */
PARMIND FIXED BIN(15);
/* PARMLST indicator variable */
/************************************************************/
/* Include the SQLCA */
/************************************************************/
EXEC SQL INCLUDE SQLCA;
/************************************************************/
/* Call the GETPRML stored procedure to retrieve the */
/* RUNOPTS values for the stored procedure. In this */
/* example, we request the RUNOPTS values for the */
/* stored procedure named DSN8EP2. */
/************************************************************/
PROCNM = 'DSN8EP2';
/* Input parameter -- PROCEDURE to be found */
SCHEMA = ' ';
/* Input parameter -- SCHEMA in SYSROUTINES */
PARMIND = -1; /* The PARMLST parameter is an output parm. */
/* Mark PARMLST parameter as null, so the DB2 */
/* requester does not have to send the entire */
/* PARMLST variable to the server. This */
/* helps reduce network I/O time, because */
/* PARMLST is fairly large. */
EXEC SQL
CALL GETPRML(:PROCNM,
:SCHEMA,
:OUT_CODE,
:PARMLST INDICATOR :PARMIND);
698 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
CREATE PROCEDURE GETPRML(PROCNM CHAR(18) IN, SCHEMA CHAR(8) IN,
OUTCODE INTEGER OUT, PARMLST VARCHAR(254) OUT)
LANGUAGE PLI
DETERMINISTIC
READS SQL DATA
EXTERNAL NAME "GETPRML"
COLLID GETPRML
ASUTIME NO LIMIT
PARAMETER STYLE GENERAL
STAY RESIDENT NO
RUN OPTIONS "MSGFILE(OUTFILE),RPTSTG(ON),RPTOPTS(ON)"
WLM ENVIRONMENT SAMPPROG
PROGRAM TYPE MAIN
SECURITY DB2
RESULT SETS 0
COMMIT ON RETURN NO;
The following example is a PL/I stored procedure with linkage convention GENERAL.
*PROCESS SYSTEM(MVS);
GETPRML:
PROC(PROCNM, SCHEMA, OUT_CODE, PARMLST)
OPTIONS(MAIN NOEXECOPS REENTRANT);
/************************************************************/
/* Execute SELECT from SYSIBM.SYSROUTINES in the catalog. */
/************************************************************/
EXEC SQL
SELECT RUNOPTS INTO :PARMLST
FROM SYSIBM.SYSROUTINES
WHERE NAME=:PROCNM AND
SCHEMA=:SCHEMA;
The following example is a PL/I stored procedure with linkage convention GENERAL WITH NULLS.
*PROCESS SYSTEM(MVS);
GETPRML:
PROC(PROCNM, SCHEMA, OUT_CODE, PARMLST, INDICATORS)
OPTIONS(MAIN NOEXECOPS REENTRANT);
IF PROCNM_IND<0 |
SCHEMA_IND<0 THEN
DO; /* If any input parm is NULL, */
OUT_CODE = 9999; /* Set output return code. */
OUT_CODE_IND = 0;
/* Output return code is not NULL.*/
PARMLST_IND = -1; /* Assign NULL value to PARMLST. */
END;
ELSE /* If input parms are not NULL, */
DO; /* */
/************************************************************/
/* Issue the SQL SELECT against the SYSIBM.SYSROUTINES */
/* DB2 catalog table. */
/************************************************************/
EXEC SQL
SELECT RUNOPTS INTO :PARMLST
FROM SYSIBM.SYSROUTINES
WHERE NAME=:PROCNM AND
SCHEMA=:SCHEMA;
PARMLST_IND = 0; /* Mark PARMLST as not NULL. */
END GETPRML;
Procedure
To request information about SQL errors in PL/I programs, use the following approaches:
• You can use the subroutine DSNTIAR to convert an SQL return code into a text message.
700 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
DSNTIAR takes data from the SQLCA, formats it into a message, and places the result in a message
output area that you provide in your application program. For concepts and more information on the
behavior of DSNTIAR, see “Displaying SQLCA fields by calling DSNTIAR” on page 525.
DSNTIAR syntax
DSNTIAR parameters
The DSNTIAR parameters have the following meanings:
sqlca
An SQL communication area.
message
An output area, in VARCHAR format, in which DSNTIAR places the message text. The first
halfword contains the length of the remaining area; its minimum value is 240.
The output lines of text, each line being the length specified in lrecl, are put into this area. For
example, you could specify the format of the output area as:
where ERROR_MESSAGE is the name of the message output area, DATA_DIM is the number of
lines in the message output area, and DATA_LEN is the length of each line.
lrecl
A fullword containing the logical record length of output messages, between 72 and 240.
Because DSNTIAR is an assembler language program, you must include the following directives in your
PL/I application:
An example of calling DSNTIAR from an application appears in the Db2 sample assembler program
DSN8BP3, contained in the library DSN8C10.SDSNSAMP. See “Sample applications supplied with Db2
for z/OS” on page 1022 for instructions on how to access and print the source code for the sample
program.
• If your CICS application requires CICS storage handling, you must use the subroutine DSNTIAC instead
of DSNTIAR.
DSNTIAC syntax
DSNTIAC has the following syntax:
DSNTIAC parameters
DSNTIAC has extra parameters, which you must use for calls to routines that use CICS commands.
eib
EXEC interface block
commarea
communication area
For more information on these parameters, see the appropriate application programming guide for
CICS. The remaining parameter descriptions are the same as those for DSNTIAR. Both DSNTIAC
and DSNTIAR format the SQLCA in the same way.
Procedure
Choose one of the following actions:
Option Description
To define the SQL a. Code the SQLCA directly in the program or use the following SQL INCLUDE
communications area: statement to request a standard SQLCA declaration:
Db2 sets the SQLCODE and SQLSTATE values in the SQLCA after each SQL
statement executes. Your application should check these values to determine
whether the last SQL statement was successful.
To declare SQLCODE a. Declare the SQLCODE variable within a BEGIN DECLARE SECTION
and SQLSTATE host statement and an END DECLARE SECTION statement in your program
variables: declarations as BIN FIXED (31).
b. Declare the SQLSTATE variable within a BEGIN DECLARE SECTION
statement and an END DECLARE SECTION statement in your program
declarations as CHARACTER(5).
Restriction: Do not declare an SQLSTATE variable as an element of a structure.
702 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Option Description
Requirement: After you declare the SQLCODE and SQLSTATE variables, ensure
that all SQL statements in the program are within the scope of the declaration
of these variables.
Related tasks
Checking the execution of SQL statements
After executing an SQL statement, your program should check for any errors before you commit the data
and handle the errors that they represent.
Checking the execution of SQL statements by using the SQLCA
One way to check whether an SQL statement executed successfully is to use the SQL communication area
(SQLCA). This area is set apart for communication with Db2.
Checking the execution of SQL statements by using SQLCODE and SQLSTATE
Whenever an SQL statement executes, the SQLCODE and SQLSTATE fields of the SQLCA receive a return
code.
Defining the items that your program can use to check whether an SQL statement executed successfully
If your program contains SQL statements, the program should define some infrastructure so that it can
check whether the statements executed successfully. You can either include an SQL communications
area (SQLCA), which contains SQLCODE and SQLSTATE variables, or declare individual SQLCODE and
SQLSTATE host variables.
Procedure
Code the SQLDA directly in the program, or use the following SQL INCLUDE statement to request a
standard SQLDA declaration:
Restriction: You must place SQLDA declarations before the first SQL statement that references the data
descriptor, unless you use the TWOPASS SQL processing option.
Related tasks
Defining SQL descriptor areas (SQLDA)
If your program includes certain SQL statements, you must define at least one SQL descriptor area
(SQLDA). Depending on the context in which it is used, the SQLDA stores information about prepared SQL
statements or host variables. This information can then be read by either the application program or Db2.
Related reference
SQL descriptor area (SQLDA) (Db2 SQL)
Procedure
To declare host variables, host-variable arrays, and host structures:
1. Declare the variables according to the following rules and guidelines:
704 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
• Be careful of overflow. For example, if you retrieve an INTEGER column value into a BIN FIXED(15) host
variable and the column value is larger than 32767 or smaller than -32768, you get an overflow warning
or an error, depending on whether you provided an indicator variable.
• Be careful of truncation. For example, if you retrieve an 80-character CHAR column value into a
CHAR(70) host variable, the rightmost ten characters of the retrieved string are truncated. Retrieving
a double-precision floating-point or decimal column value into a BIN FIXED(31) host variable removes
any fractional part of the value. Similarly, retrieving a column value with a DECIMAL data type into a PL/I
decimal variable with a lower precision might truncate the value.
DCL , BIN
DECIMAL
( variable-name )
DEC
2 3
FIXED
( precision )
1
,scale
FLOAT ( precision )
Notes:
1 You can specify a scale only for DECIMAL FIXED.
2 You can specify host variable attributes in any order that is acceptable to PL/I. For example, BIN
FIXED(31), BINARY FIXED(31), BIN(31) FIXED, and FIXED BIN(31) are all acceptable.
3 The UNSIGNED attribute must not be specified with BINARY and FIXED for a numeric host variable
declaration.
For binary floating-point or hexadecimal floating-point data types, use the FLOAT SQL processing option
to specify whether the host variable is in IEEE binary floating-point or z/Architecture hexadecimal
floating-point format. Db2 does not check if the format of the host variable contents match the format
that you specified with the FLOAT SQL processing option. Therefore, you need to ensure that your
floating-point host variable contents match the format that you specified with the FLOAT SQL processing
option. Db2 converts all floating-point input data to z/Architecture hexadecimal floating-point format
before storing it.
If the PL/I compiler that you are using does not support a decimal data type with a precision greater than
15, use one of the following variable types for decimal data:
• Decimal variables with precision less than or equal to 15, if the actual data values fit. If you retrieve a
decimal value into a decimal variable with a scale that is less than the source column in the database,
the fractional part of the value might truncate.
DCL , CHAR
( variable-name )
( length )
VARYING Alignment and/or Scope and/or Storage
VAR
DCL , 1
WIDECHAR
( variable-name )
length )
VARYING Alignment and/or Scope and/or Storage
VAR
Notes:
1 Use WIDECHAR only for UNICODE UTF-16 data. WIDECHAR is supported only by the Db2 coprocessor.
706 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Binary host variables
You can specify the following forms of binary host variables:
• Fixed-length strings
• Varying-length strings
• BLOBs
The following diagram shows the syntax for declaring BINARY host variables.
DCL ,
( variable-name )
1
BINARY ( length ) ;
VARBINARY
BINARY VARYING
Notes:
1 For BINARY host variables, the length must be in the range 1 - 255. For VARBINARY host variables, the
length must be in the range 1 - 32704.
PL/I does not have variables that correspond to the SQL binary data types BINARY and VARBINARY. To
create host variables that can be used with these data types, use the SQL TYPE IS clause.
When you reference a BINARY or VARBINARY host variable in an SQL statement, you must use the
variable that you specify in the SQL TYPE declaration. When you reference the host variable in a host
language statement, you must use the variable that Db2 generates.
Table 115. Examples of BINARY and VARBINARY variable declarations for PL/I
Variable declaration that you include in your PL/I Corresponding variable that Db2 generates in the
program output source member
DCL ,
( variable-name )
RESULT_SET_LOCATOR VARYING
Alignment and/or Scope and/or Storage
Table locators
The following diagram shows the syntax for declaring table locators.
DECLARE ,
( variable-name )
table-name AS LOCATOR
( variable-name )
2
BINARY LARGE OBJECT ( length )
BLOB K
CLOB
DBCLOB
BLOB_LOCATOR
CLOB_LOCATOR
DBCLOB_LOCATOR
BLOB_FILE
CLOB_FILE
DBCLOB_FILE
Notes:
1 A single PL/I declaration that contains a LOB variable declaration is limited to no more than 1000 lines of
source code.
2 Variable attributes such as STATIC and AUTOMATIC are ignored if specified on a LOB variable declaration.
708 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Note: Variable attributes such as STATIC and AUTOMATIC are ignored if specified on a LOB variable
declaration.
DECLARE ,
( variable-name )
BLOB K
CLOB
DBCLOB
BLOB_FILE
CLOB_FILE
DBCLOB_FILE
DECLARE ,
( variable-name )
Related concepts
Host variables
Use host variables to pass a single data item between Db2 and your application.
Using host variables in SQL statements
Use scalar host variables in embedded SQL statements to represent a single value. Host variables are
useful for storing retrieved data or for passing values that are to be assigned or used for comparisons.
Decimal floating-point (DECFLOAT) (Db2 SQL)
Related tasks
Determining whether a retrieved value in a host variable is null or truncated
Before your application manipulates the data that was retrieved from Db2 into a host variable, determine
if the value is null. Also determine if it was truncated when assigned to the variable. You can use indicator
variables to obtain this information.
Inserting a single row by using a host variable
Use host variables in your INSERT statement when you don't know at least some of the values to insert
until the program runs.
Inserting null values into columns by using indicator variables or arrays
710 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
DECLARE variable-name ( dimension )
DCL ,
( variable-name )
,
1
( variable-name ( dimension ) )
BINARY FIXED
BIN ( precision )
DECIMAL 2
,scale
DEC
FLOAT ( precision )
Notes:
1 dimension must be an integer constant between 1 and 32767.
2 You can specify the scale for only DECIMAL FIXED.
3 You can specify host-variable array attributes in any order that is acceptable to PL/I. For example, BIN
FIXED(31), BINARY FIXED(31), BIN(31) FIXED, and FIXED BIN(31) are all acceptable.
Example
The following example shows a declaration of an indicator array.
To use the PL/I decimal floating-point host data types, you need to use the FLOAT(DFP) and ARCH(7)
compiler options and the Db2 coprocessor. The maximum precision for extended DECIMAL FLOAT will be
34 (not 33 as it is for hexadecimal float). The maximum precision for short DECIMAL FLOAT will be 7 (not
6 as it is for hexadecimal float).
DCL ,
( variable-name )
,
1
( variable-name ( dimension ) )
CHARACTER ( length )
CHAR VARYING
VAR
Notes:
1 dimension must be an integer constant between 1 and 32767.
Example
The following example shows the declarations needed to retrieve 10 rows of the department number and
name from the department table:
DCL ,
( variable-name )
,
1
( variable-name ( dimension ) )
GRAPHIC ( length )
VARYING
VAR
Notes:
1 dimension must be an integer constant between 1 and 32767.
712 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
DCL variable-name ( dimension )
DECLARE ,
( variable-name )
,
( variable-name ( dimension ) )
VARBINARY
DECLARE ,
( variable-name )
,
1
( variable-name ( dimension ) )
SQL TYPE IS
BLOB K
CLOB
DBCLOB
BLOB_LOCATOR
CLOB_LOCATOR
DBCLOB_LOCATOR
BLOB_FILE
CLOB_FILE
DBCLOB_FILE
Notes:
1 dimension must be an integer constant between 1 and 32767.
DECLARE ,
( variable-name )
,
1
( variable-name ( dimension ) )
BLOB K
CLOB
DBCLOB
BLOB_FILE
CLOB_FILE
DBCLOB_FILE
Notes:
1 dimension must be an integer constant between 1 and 32767.
DECLARE ,
( variable-name )
,
1
( variable-name ( dimension ) )
Notes:
1 dimension must be an integer constant between 1 and 32767.
Related concepts
Using host-variable arrays in SQL statements
Use host-variable arrays in embedded SQL statements to represent values that the program does not
know until the query is executed. Host-variable arrays are useful for storing a set of retrieved values or for
passing a set of values that are to be inserted into a table.
Host-variable arrays
You can use host-variable arrays to pass a data array between Db2 and your application. A host-variable
array is a data array that is declared in the host language to be used within an SQL statement.
Host-variable arrays in PL/I, C, C++, and COBOL (Db2 SQL)
714 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Decimal floating-point (DECFLOAT) (Db2 SQL)
Related tasks
Inserting multiple rows of data from host-variable arrays
Use host-variable arrays in your INSERT statement when you do not know at least some of the values to
insert until the program runs.
Storing LOB data in a table
Db2 handles LOB data differently than it handles other kinds of data. As a result, in some cases, you need
to take additional actions when you define LOB columns and insert the LOB data.
Retrieving multiple rows of data into host-variable arrays
If you know that your query returns multiple rows, you can specify host-variable arrays to store the
retrieved column values.
DCL 1 A,
2 B CHAR,
2 (C, D) CHAR;
DCL (E, F) CHAR;
• You can specify host variable attributes in any order that is acceptable to PL/I. For example, BIN
FIXED(31), BIN(31) FIXED, and FIXED BIN(31) are all acceptable.
When you reference a host variable, you can qualify it with a structure name. For example, you can specify
STRUCTURE.FIELD.
Host structures
The following diagram shows the syntax for declaring host structures.
( var-2 )
Data types
The following diagram shows the syntax for data types that are used within declarations of host
structures.
VAR
GRAPHIC
( integer ) VARYING
VAR
BINARY FIXED
BIN ( precision )
DECIMAL , scale
DEC FLOAT
( precision )
CLOB M
DBCLOB G
BLOB
CLOB_LOCATOR
DBCLOB_LOCATOR
BLOB_LOCATOR
CLOB_FILE
DBCLOB_FILE
BLOB_FILE
716 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
SQL TYPE IS XML AS
BLOB K
CLOB
DBCLOB
BLOB_FILE
CLOB_FILE
DBCLOB_FILE
Example
In the following example, B is the name of a host structure that contains the scalars C1 and C2.
DCL 1 A,
2 B,
3 C1 CHAR(...),
3 C2 CHAR(...);
Related concepts
Host structures
Use host structures to pass a group of host variables between Db2 and your application.
1
DECLARE ( variable-name ) BINARY FIXED(15) ;
DCL BIN
Notes:
1You can specify host variable attributes in any order that is acceptable to PL/I. For example, BIN
FIXED(31), BIN(31) FIXED, and FIXED BIN(31) are all acceptable.
The following diagram shows the syntax for declaring an indicator array in PL/I.
DCL ,
1
( variable-name ( dimension ) )
BINARY FIXED(15) ;
Example
The following example shows a FETCH statement with the declarations of the host variables that are
needed for the FETCH statement and their associated indicator variables.
Related concepts
Indicator variables, arrays, and structures
An indicator variable is associated with a particular host variable. Each indicator variable contains a small
integer value that indicates some information about the associated host variable. Indicator arrays and
structures serve the same purpose for host-variable arrays and structures.
Related tasks
Inserting null values into columns by using indicator variables or arrays
If you need to insert null values into a column, using an indicator variable or array is an easy way to do so.
An indicator variable or array is associated with a particular host variable or host-variable array.
Table 116. SQL data types, SQLLEN values, and SQLTYPE values that the precompiler uses for host variables in
PL/I programs
SQLTYPE of host
variable “1” on page
PL/I host variable data type 722 SQLLEN of host variable SQL data type
BIN FIXED(n) 1≤n≤15 500 2 SMALLINT
BIN FIXED(n) 16≤n≤31 496 4 INTEGER
FIXED BIN(63) 492 8 BIGINT
DEC FIXED(p,s) 0≤p≤31 and 484 p in byte 1, s in byte 2 DECIMAL(p,s)
0≤s≤p “2” on page 722
DEC FLOAT (p) where 1 ≤ p ≤ 7 996/997 4 DECFLOAT(16) “6” on page 722
DEC FLOAT (p) where 8 ≤ p ≤ 996/997 8 DECFLOAT(16)
16
DEC FLOAT (p) where 17 ≤ p 996/997 16 DECFLOAT(34)
718 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 116. SQL data types, SQLLEN values, and SQLTYPE values that the precompiler uses for host variables in
PL/I programs (continued)
SQLTYPE of host
variable “1” on page
PL/I host variable data type 722 SQLLEN of host variable SQL data type
BIN FLOAT(p) 1≤p≤21 480 4 REAL or FLOAT(n) 1≤n≤21
BIN FLOAT(p) 22≤p≤53 480 8 DOUBLE PRECISION or
FLOAT(n) 22≤n≤53
DEC FLOAT(m) 1≤m≤6 480 4 FLOAT (single precision)
DEC FLOAT(m) 7≤m≤16 480 8 FLOAT (double precision)
CHAR(n) 452 n CHAR(n)
CHAR(n) VARYING 1≤n≤255 448 n VARCHAR(n)
CHAR(n) VARYING n>255 456 n VARCHAR(n)
GRAPHIC(n) 468 n GRAPHIC(n)
GRAPHIC VARYING(n) 464 n VARGRAPHIC(n)
SQL TYPE IS BINARY(n), 912 n BINARY(n)
1≤n≤255
SQL TYPE IS VARBINARY(n), 908 n VARBINARY(n)
1≤n≤32704
SQL TYPE IS 972 4 Result set locator “3” on page
RESULT_SET_LOCATOR 722
SQL TYPE IS TABLE LIKE table- 976 4 Table locator “3” on page 722
name AS LOCATOR
SQL TYPE IS BLOB_LOCATOR 960 4 BLOB locator “3” on page 722
SQL TYPE IS CLOB_LOCATOR 964 4 CLOB locator “3” on page 722
SQL TYPE IS 968 4 DBCLOB locator “3” on page 722
DBCLOB_LOCATOR
SQL TYPE IS BLOB(n) 404 n BLOB(n)
1≤n≤2147483647
SQL TYPE IS CLOB(n) 408 n CLOB(n)
1≤n≤2147483647
SQL TYPE IS DBCLOB(n) 412 n DBCLOB(n) “4” on page 722
1≤n≤1073741823 “4” on page
722
SQL TYPE IS CLOB_FILE 920/921 267 CLOB file reference “3” on page
722
SQL TYPE IS XML AS 916/917 267 XML BLOB file reference “3” on
BLOB_FILE page 722
SQL TYPE IS XML AS 920/921 267 XML CLOB file reference “3” on
CLOB_FILE page 722
SQL TYPE IS XML AS 924/925 267 XML DBCLOB file reference “3”
DBCLOB_FILE on page 722
The following table shows equivalent PL/I host variables for each SQL data type. Use this table to
determine the PL/I data type for host variables that you define to receive output from the database. For
example, if you retrieve TIMESTAMP data, you can define a variable of type CHAR(n).
This table shows direct conversions between SQL data types and PL/I data types. However, a number of
SQL data types are compatible. When you do assignments or comparisons of data that have compatible
data types, Db2 converts those compatible data types.
Table 117. PL/I host variable equivalents that you can use when retrieving data of a particular SQL data type
SQL data type PL/I host variable equivalent Remarks
SMALLINT BIN FIXED(n) 1≤n≤15
INTEGER BIN FIXED(n) 16≤n≤31
BIGINT FIXED BIN(63) “7” on page 722
720 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 117. PL/I host variable equivalents that you can use when retrieving data of a particular SQL data type
(continued)
SQL data type PL/I host variable equivalent Remarks
VARGRAPHIC(n) GRAPHIC(n) VARYING or WIDECHAR(n) n refers to the number of double-byte
VARYING characters, not to the number of bytes.
BINARY(n) SQL TYPE IS BINARY(n) 1≤n≤255
VARBINARY(n) SQL TYPE IS VARBINARY(n) 1≤n≤32704
DATE CHAR(n) If you are using a date exit routine, that
routine determines n; otherwise, n must
be at least 10.
TIME CHAR(n) If you are using a time exit routine, that
routine determines n. Otherwise, n must
be at least 6; to include seconds, n must
be at least 8.
TIMESTAMP CHAR(n) n must be at least 19. To include
microseconds, n must be 26; if n is
less than 26, the microseconds part is
truncated.
TIMESTAMP(0) CHAR(n) n must be at least 19.
TIMESTAMP(p) p > 0 CHAR(n) n must be at least 19. To include
fractional seconds, n must be 20+x
where x is the number of fractional
seconds to include; if x is less than
p, truncation occurs on the fractional
seconds part.
TIMESTAMP(0) WITH CHAR(n) VAR n must be at least 25.
TIME ZONE
TIMESTAMP(p) WITH CHAR(n) VAR n must be at least 26+p.
TIME ZONE
Result set locator SQL TYPE IS RESULT_SET_LOCATOR Use this data type only for receiving
result sets. “3” on page 722
Table locator SQL TYPE IS TABLE LIKE table-name AS Use this data type only in a user-defined
LOCATOR function or stored procedure to receive
rows of a transition table. “3” on page 722
BLOB locator SQL TYPE IS BLOB_LOCATOR Use this data type only to manipulate
data in BLOB columns. “3” on page 722, “6”
on page 722, “7” on page 722
CLOB locator SQL TYPE IS CLOB_LOCATOR Use this data type only to manipulate
data in CLOB columns. “3” on page 722, “6”
on page 722, “7” on page 722
DBCLOB locator SQL TYPE IS DBCLOB_LOCATOR Use this data type only to manipulate
data in DBCLOB columns. “3” on page 722,
“6” on page 722, “7” on page 722
BLOB file reference SQL TYPE IS BLOB_FILE Use this data type only to manipulate
data in BLOB columns. “3” on page 722, “6”
on page 722, “7” on page 722
CLOB file reference SQL TYPE IS CLOB_FILE Use this data type only to manipulate
data in CLOB columns. “3” on page 722, “6”
on page 722, “7” on page 722
DBCLOB file reference SQL TYPE IS DBCLOB_FILE Use this data type only to manipulate
data in DBCLOB columns. “3” on page 722,
“6” on page 722, “7” on page 722
XML BLOB file reference SQL TYPE IS XML AS BLOB_FILE Use this data type only to manipulate
XML data as BLOB files. “3” on page 722
XML CLOB file reference SQL TYPE IS XML AS CLOB_FILE Use this data type only to manipulate
XML data as CLOB files. “3” on page 722
XML DBCLOB file reference SQL TYPE IS XML AS DBCLOB_FILE Use this data type only to manipulate
XML data as DBCLOB files. “3” on page 722
ROWID SQL TYPE IS ROWID
Table notes:
The following notes apply as indicated to Table 116 on page 718 and Table 117 on page 720.
1. If a host variable includes an indicator variable, the SQLTYPE value is the base SQLTYPE value plus 1.
2. If p=0, Db2 interprets it as DECIMAL(31). For example, Db2 interprets a PL/I data type of DEC
FIXED(0,0) to be DECIMAL(31,0), which equates to the SQL data type of DECIMAL(31,0).
3. Do not use this data type as a column type.
4. n is the number of double-byte characters.
5. CCSID 1200 is always assigned to WIDECHAR type host var.
6. The data type conversions can be used only if the Db2 coprocessor is used, and the PL/I compiler
options FLOAT(DFP) and ARCH(7) are specified.
7. Specify the following compiler options when you compile your program: LIMITS(FIXEDBIN(63),
FIXEDDEC(31)).
The following table shows the PL/I language definitions to use in PL/I stored procedures and user-defined
functions, when the parameter data types in the routine definitions are LOBs, ROWIDs, or locators. For
other parameter data types, the PL/I language definitions are the same as those in Table 117 on page 720
above.
722 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 118. Equivalent PL/I language declarations for LOBs, ROWIDs, and locators in user-defined routine
definitions
SQL data type in definition PL/I
01 var,
03 var_LENGTH
BIN FIXED(31),
03 var_DATA
CHAR(n);
If n > 32767:
01 var,
02 var_LENGTH
BIN FIXED(31),
02 var_DATA,
03 var_DATA1(n)
CHAR(32767),
03 var_DATA2
CHAR(mod(n,32767));
01 var,
03 var_LENGTH
BIN FIXED(31),
03 var_DATA
CHAR(n);
If n > 32767:
01 var,
02 var_LENGTH
BIN FIXED(31),
02 var_DATA,
03 var_DATA1(n)
CHAR(32767),
03 var_DATA2
CHAR(mod(n,32767));
01 var,
03 var_LENGTH
BIN FIXED(31),
03 var_DATA
GRAPHIC(n);
If n > 16383:
01 var,
02 var_LENGTH
BIN FIXED(31),
02 var_DATA,
03 var_DATA1(n)
GRAPHIC(16383),
03 var_DATA2
GRAPHIC(mod(n,16383));
724 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
• A REXX variable that contains an SQL statement. The REXX variable must not be preceded by a colon.
For example, you can use either of the following methods to execute the COMMIT statement in a REXX
program:
EXECSQL "COMMIT"
rexxvar="COMMIT"
EXECSQL rexxvar
The following dynamic statements must be executed using EXECUTE IMMEDIATE or PREPARE and
EXECUTE under DSNREXX:
• DECLARE GLOBAL TEMPORARY TABLE
• SET CURRENT DEBUG MODE
• SET CURRENT DECFLOAT ROUNDING MODE
• SET CURRENT MAINTAINED TABLE TYPES FOR OPTIMIZATION
• SET CURRENT QUERY ACCELERATION
• SET CURRENT REFRESH AGE
• SET CURRENT ROUTINE VERSION
• SET SCHEMA
You cannot execute a SELECT, INSERT, UPDATE, MERGE, or DELETE statement that contains host
variables. Instead, you must execute PREPARE on the statement, with parameter markers substituted
for the host variables, and then use the host variables in an EXECUTE, OPEN, or FETCH statement. See
“Host variables” on page 473 for more information.
An SQL statement follows rules that apply to REXX commands. The SQL statement can optionally end
with a semicolon and can be enclosed in single or double quotation marks, as in the following example:
'EXECSQL COMMIT';
Comments
You cannot include REXX comments (/* … */) or SQL comments (--) within SQL statements. However,
you can include REXX comments anywhere else in the program.
Delimiters for SQL statements
Delimit SQL statements in REXX program by preceding the statement with EXECSQL. If the statement
is in a literal string, enclose it in single or double quotation marks.
Continuation for SQL statements
SQL statements that span lines follow REXX rules for statement continuation. You can break the
statement into several strings, each of which fits on a line, and separate the strings with commas or
with concatenation operators followed by commas. For example, either of the following statements is
valid:
EXECSQL ,
"UPDATE DSN8C10.DEPT" ,
"SET MGRNO = '000010'" ,
"WHERE DEPTNO = 'D11'"
"EXECSQL " || ,
" UPDATE DSN8C10.DEPT " || ,
" SET MGRNO = '000010'" || ,
" WHERE DEPTNO = 'D11'"
Including code
The EXECSQL INCLUDE statement is not valid for REXX. You therefore cannot include externally
defined SQL statements in a program.
Margins
Like REXX commands, SQL statements can begin and end anywhere on a line.
DRAW syntax:
%DRAW object-name (
SSID= ssid SELECT
TYPE= INSERT
UPDATE
LOAD
DRAW parameters:
726 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
object-name
The name of the table or view for which DRAW builds an SQL statement or utility control statement.
The name can be a one-, two-, or three-part name. The table or view to which object-name refers
must exist before DRAW can run.
object-name is a required parameter.
SSID=ssid
Specifies the name of the local Db2 subsystem.
S can be used as an abbreviation for SSID.
If you invoke DRAW from the command line of the edit session in SPUFI, SSID=ssid is an optional
parameter. DRAW uses the subsystem ID from the DB2I Defaults panel.
TYPE=operation-type
The type of statement that DRAW builds.
T can be used as an abbreviation for TYPE.
operation-type has one of the following values:
SELECT
Builds a SELECT statement in which the result table contains all columns of object-name.
S can be used as an abbreviation for SELECT.
INSERT
Builds a template for an INSERT statement that inserts values into all columns of object-name.
The template contains comments that indicate where the user can place column values.
I can be used as an abbreviation for INSERT.
UPDATE
Builds a template for an UPDATE statement that updates columns of object-name. The template
contains comments that indicate where the user can place column values and qualify the update
operation for selected rows.
U can be used as an abbreviation for UPDATE.
LOAD
Builds a template for a LOAD utility control statement for object-name.
L can be used as an abbreviation for LOAD.
TYPE=operation-type is an optional parameter. The default is TYPE=SELECT.
DRAW data sets:
Edit data set
The data set from which you issue the DRAW command when you are in an ISPF edit session. If you
issue the DRAW command from a SPUFI session, this data set is the data set that you specify in field 1
of the main SPUFI panel (DSNESP01). The output from the DRAW command goes into this data set.
DRAW return codes:
Return code
Meaning
0
Successful completion.
12
An error occurred when DRAW edited the input file.
20
One of the following errors occurred:
• No input parameters were specified.
• One of the input parameters was not valid.
Generate a template for an INSERT statement that inserts values into table DSN8C10.EMP at location
SAN_JOSE. The local subsystem ID is DSN.
The DRAW invocation is:
Generate a template for an UPDATE statement that updates values of table DSN8C10.EMP. The local
subsystem ID is DSN.
The DRAW invocation is:
728 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
, "COMM"= -- DECIMAL(9,2)
WHERE
Generate a LOAD control statement to load values into table DSN8C10.EMP. The local subsystem ID is
DSN.
The draw invocation is:
/* REXX ***************************************************************/
L1 = WHEREAMI()
/*
DRAW creates basic SQL queries by retrieving the description of a
table. You must specify the name of the table or view to be queried.
You can specify the type of query you want to compose. You might need
to specify the name of the DB2 subsystem.
>>--DRAW-----tablename-----|---------------------------|-------><
|-(-|-Ssid=subsystem-name-|-|
| +-Select-+ |
|-Type=-|-Insert-|----|
|-Update-|
+--Load--+
Ssid=subsystem-name
subsystem-name specified the name of a DB2 subsystem.
Select
Composes a basic query for selecting data from the columns of a
table or view. If TYPE is not specified, SELECT is assumed.
Using SELECT with the DRAW command produces a query that would
retrieve all rows and all columns from the specified table. You
can then modify the query as needed.
A SELECT query of EMP composed by DRAW looks like this:
SELECT "EMPNO" , "FIRSTNME" , "MIDINIT" , "LASTNAME" , "WORKDEPT" ,
"PHONENO" , "HIREDATE" , "JOB" , "EDLEVEL" , "SEX" , "BIRTHDATE" ,
"SALARY" , "BONUS" , "COMM"
FROM DSN8C10.EMP
If you include a location qualifier, the query looks like this:
SELECT "EMPNO" , "FIRSTNME" , "MIDINIT" , "LASTNAME" , "WORKDEPT" ,
"PHONENO" , "HIREDATE" , "JOB" , "EDLEVEL" , "SEX" , "BIRTHDATE" ,
"SALARY" , "BONUS" , "COMM"
FROM STLEC1.DSN8C10.EMP
To use this SELECT query, type the other clauses you need. If
you are selecting from more than one table, use a DRAW command
for each table name you want represented.
730 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
NULLIF( 96)='?'
)
To use this LOAD statement, type the changes you want to make,
and delete the lines you do not need.
*/
L2 = WHEREAMI()
/**********************************************************************/
/* TRACE ?R */
/**********************************************************************/
Address ISPEXEC
"ISREDIT MACRO (ARGS) NOPROCESS"
If ARGS = "" Then
Do
Do I = L1+2 To L2-2;Say SourceLine(I);End
Exit (20)
End
Parse Upper Var Args Table "(" Parms
Parms = Translate(Parms," ",",")
Type = "SELECT" /* Default */
SSID = "" /* Default */
"VGET (DSNEOV01)"
If RC = 0 Then SSID = DSNEOV01
If (Parms <> "") Then
Do Until(Parms = "")
Parse Var Parms Var "=" Value Parms
If Var = "T" | Var = "TYPE" Then Type = Value
Else
If Var = "S" | Var = "SSID" Then SSID = Value
Else
Exit (20)
End
"CONTROL ERRORS RETURN"
"ISREDIT (LEFTBND,RIGHTBND) = BOUNDS"
"ISREDIT (LRECL) = DATA_WIDTH" /*LRECL*/
BndSize = RightBnd - LeftBnd + 1
If BndSize > 72 Then BndSize = 72
"ISREDIT PROCESS DEST"
Select
When rc = 0 Then
'ISREDIT (ZDEST) = LINENUM .ZDEST'
When rc <= 8 Then /* No A or B entered */
Do
zedsmsg = 'Enter "A"/"B" line cmd'
zedlmsg = 'DRAW requires an "A" or "B" line command'
'SETMSG MSG(ISRZ001)'
Exit 12
End
When rc < 20 Then /* Conflicting line commands - edit sets message */
Exit 12
When rc = 20 Then
zdest = 0
Otherwise
Exit 12
End
/**********************************************************************/
WHEREAMI:; RETURN SIGL
/**********************************************************************/
/* Draw SELECT */
/**********************************************************************/
DrawSelect:
Line.0 = 0
Line = "SELECT"
Do I = 1 To SQLDA.SQLD
If I > 1 Then Line = Line ','
ColName = '"'SQLDA.I.SQLNAME'"'
Null = SQLDA.I.SQLTYPE//2
If Length(Line)+Length(ColName)+LENGTH(" ,") > BndSize THEN
Do
L = Line.0 + 1; Line.0 = L
Line.L = Line
Line = " "
End
Line = Line ColName
End I
If Line ^= "" Then
Do
L = Line.0 + 1; Line.0 = L
Line.L = Line
Line = " "
End
L = Line.0 + 1; Line.0 = L
Line.L = "FROM" TABLE
Return
/**********************************************************************/
/* Draw INSERT */
/**********************************************************************/
DrawInsert:
Line.0 = 0
Line = "INSERT INTO" TABLE "("
Do I = 1 To SQLDA.SQLD
If I > 1 Then Line = Line ','
ColName = '"'SQLDA.I.SQLNAME'"'
If Length(Line)+Length(ColName) > BndSize THEN
Do
L = Line.0 + 1; Line.0 = L
Line.L = Line
Line = " "
End
Line = Line ColName
If I = SQLDA.SQLD Then Line = Line ')'
End I
If Line ^= "" Then
Do
L = Line.0 + 1; Line.0 = L
Line.L = Line
Line = " "
End
L = Line.0 + 1; Line.0 = L
Line.L = " VALUES ("
L = Line.0 + 1; Line.0 = L
Line.L = ,
"-- ENTER VALUES BELOW COLUMN NAME DATA TYPE"
Do I = 1 To SQLDA.SQLD
If SQLDA.SQLD > 1 & I < SQLDA.SQLD Then
732 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Line = " , --"
Else
Line = " ) --"
Line = Line Left(SQLDA.I.SQLNAME,18)
Type = SQLDA.I.SQLTYPE
Null = Type//2
If Null Then Type = Type - 1
Len = SQLDA.I.SQLLEN
Prcsn = SQLDA.I.SQLLEN.SQLPRECISION
Scale = SQLDA.I.SQLLEN.SQLSCALE
Select
When (Type = CHTYPE ,
|Type = VCHTYPE ,
|Type = LVCHTYPE ,
|Type = GRTYP ,
|Type = VGRTYP ,
|Type = LVGRTYP ) THEN
Type = SQLTYPES.Type"("STRIP(LEN)")"
When (Type = FLOTYPE ) THEN
Type = SQLTYPES.Type"("STRIP((LEN*4)-11) ")"
When (Type = DCTYPE ) THEN
Type = SQLTYPES.Type"("STRIP(PRCSN)","STRIP(SCALE)")"
Otherwise
Type = SQLTYPES.Type
End
Line = Line Type
If Null = 0 Then
Line = Line "NOT NULL"
L = Line.0 + 1; Line.0 = L
Line.L = Line
End I
Return
/**********************************************************************/
/* Draw UPDATE */
/**********************************************************************/
DrawUpdate:
Line.0 = 1
Line.1 = "UPDATE" TABLE "SET"
L = Line.0 + 1; Line.0 = L
Line.L = ,
"-- COLUMN NAME ENTER VALUES BELOW DATA TYPE"
Do I = 1 To SQLDA.SQLD
If I = 1 Then
Line = " "
Else
Line = " ,"
Line = Line Left('"'SQLDA.I.SQLNAME'"=',21)
Line = Line Left(" ",20)
Type = SQLDA.I.SQLTYPE
Null = Type//2
If Null Then Type = Type - 1
Len = SQLDA.I.SQLLEN
Prcsn = SQLDA.I.SQLLEN.SQLPRECISION
Scale = SQLDA.I.SQLLEN.SQLSCALE
Select
When (Type = CHTYPE ,
|Type = VCHTYPE ,
|Type = LVCHTYPE ,
|Type = GRTYP ,
|Type = VGRTYP ,
|Type = LVGRTYP ) THEN
Type = SQLTYPES.Type"("STRIP(LEN)")"
When (Type = FLOTYPE ) THEN
Type = SQLTYPES.Type"("STRIP((LEN*4)-11) ")"
When (Type = DCTYPE ) THEN
Type = SQLTYPES.Type"("STRIP(PRCSN)","STRIP(SCALE)")"
Otherwise
Type = SQLTYPES.Type
End
Line = Line "--" Type
If Null = 0 Then
Line = Line "NOT NULL"
L = Line.0 + 1; Line.0 = L
Line.L = Line
End I
L = Line.0 + 1; Line.0 = L
Line.L = "WHERE"
Return
Line.L = Line
If Null = 1 Then
Do
Line = " "
Line = Line Left('',20)
Line = Line " NULLIF("RIGHT(POSITION,5)")='?'"
L = Line.0 + 1; Line.0 = L
Line.L = Line
End
Position = Position + Len + 1
End I
L = Line.0 + 1; Line.0 = L
Line.L = " )"
Return
/**********************************************************************/
/* Display SQLCA */
/**********************************************************************/
SQLCA:
"ISREDIT LINE_AFTER "zdest" = MSGLINE 'SQLSTATE="SQLSTATE"'"
"ISREDIT LINE_AFTER "zdest" = MSGLINE 'SQLWARN ="SQLWARN.0",",
|| SQLWARN.1",",
|| SQLWARN.2",",
|| SQLWARN.3",",
|| SQLWARN.4",",
|| SQLWARN.5",",
|| SQLWARN.6",",
|| SQLWARN.7",",
|| SQLWARN.8",",
|| SQLWARN.9",",
734 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
|| SQLWARN.10"'"
"ISREDIT LINE_AFTER "zdest" = MSGLINE 'SQLERRD ="SQLERRD.1",",
|| SQLERRD.2",",
|| SQLERRD.3",",
|| SQLERRD.4",",
|| SQLERRD.5",",
|| SQLERRD.6"'"
"ISREDIT LINE_AFTER "zdest" = MSGLINE 'SQLERRP ="SQLERRP"'"
"ISREDIT LINE_AFTER "zdest" = MSGLINE 'SQLERRMC ="SQLERRMC"'"
"ISREDIT LINE_AFTER "zdest" = MSGLINE 'SQLCODE ="SQLCODE"'"
Exit 20
SQLSTMT="UPDATE EMP" ,
"SET WORKDEPT = ?"
HVWORKDEPT='000'
INDWORKDEPT=-1
"EXECSQL PREPARE S100 FROM :SQLSTMT"
"EXECSQL EXECUTE S100 USING :HVWORKDEPT :INDWORKDEPT"
In the following program, the phone number for employee Haas is selected into variable HVPhone. After
the SELECT statement executes, if no phone number for employee Haas is found, indicator variable
INDPhone contains -1.
'SUBCOM DSNREXX'
IF RC THEN ,
S_RC = RXSUBCOM('ADD','DSNREXX','DSNREXX')
ADDRESS DSNREXX
'CONNECT' 'DSN'
SQLSTMT = ,
"SELECT PHONENO FROM DSN8C10.EMP WHERE LASTNAME='HAAS'"
"EXECSQL DECLARE C1 CURSOR FOR S1"
"EXECSQL PREPARE S1 FROM :SQLSTMT"
Say "SQLCODE from PREPARE is "SQLCODE
"EXECSQL OPEN C1"
Say "SQLCODE from OPEN is "SQLCODE
"EXECSQL FETCH C1 INTO :HVPhone :INDPhone"
Say "SQLCODE from FETCH is "SQLCODE
If INDPhone < 0 Then ,
Say 'Phone number for Haas is null.'
"EXECSQL CLOSE C1"
Say "SQLCODE from CLOSE is "SQLCODE
S_RC = RXSUBCOM('DELETE','DSNREXX','DSNREXX')
ssid = "VA1A" ;
Address DSNREXX ;
"CONNECT" ssid ;
if sqlcode \= 0 then do ;
say "CONNECT to" ssid "failed.";
Address DSNREXX ,
"EXECSQL EXECUTE IMMEDIATE :STMT" ;
mydata = copies('Z',75000) ;
say "length of :mydata="length(mydata) ;
say "length(var1)="length(var1) ;
say "var2="var2 ;
/**********************************************************************\
* Disconnect from the DB2 system. *
\**********************************************************************/
"DISCONNECT" ;
say "RC after DISCONNECT is" rc
s_rc = RXSUBCOM("DELETE","DSNREXX","DSNREXX") ;
exit 0 ;
sqlca_error:
call sqlca
exit 16
736 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
/*********************************************************************/
/* Error handling routine for bad SQL codes - just report and end. */
/*********************************************************************/
SQLCA:
/*********************************************************************/
SAY "Error. SQLCODE = >"SQLCODE"<"
SAY " SQLSTATE = >"SQLSTATE"<"
SAY " SQLERRMC = >"SQLERRMC"<"
SAY " SQLERRP = >"SQLERRP"<"
SAY " SQLERRD.1= >"SQLERRD.1"<"
SAY " SQLERRD.2= >"SQLERRD.2"<"
SAY " SQLERRD.3= >"SQLERRD.3"<"
SAY " SQLERRD.4= >"SQLERRD.4"<"
SAY " SQLERRD.5= >"SQLERRD.5"<"
SAY " SQLERRD.6= >"SQLERRD.6"<"
SAY " SQLWARN.0= >"SQLWARN.0"<"
SAY " SQLWARN.1= >"SQLWARN.1"<"
SAY " SQLWARN.2= >"SQLWARN.2"<"
SAY " SQLWARN.3= >"SQLWARN.3"<"
SAY " SQLWARN.4= >"SQLWARN.4"<"
SAY " SQLWARN.5= >"SQLWARN.5"<"
SAY " SQLWARN.6= >"SQLWARN.6"<"
SAY " SQLWARN.7= >"SQLWARN.7"<"
SAY " SQLWARN.8= >"SQLWARN.8"<"
SAY " SQLWARN.9= >"SQLWARN.9"<"
SAY " SQLWARN.10= >"SQLWARN.10"<"
return ;
ssid = "VA1A" ;
Address DSNREXX "CONNECT" ssid ;
if sqlcode \= 0 then do ;
say "CONNECT to" ssid "failed.";
call sqlca
exit 8 ;
end ;
d1.sqld = 1 ;
d1.1.sqltype = 408 ;
d1.1.sqllongl= length(mydata) ;
d1.1.sqldata = mydata ;
Do forever ;
Address DSNREXX "EXECSQL FETCH C1 INTO DESCRIPTOR :OUTDA" ;
do i = 1 to outda.sqld ;
say i": sqlname =>"outda.i.sqlname"<" ;
say i": sqltype =>"outda.i.sqltype"<" ;
say i": sqllen =>"outda.i.sqllen"<" ;
say i": sqllongl=>"outda.i.sqllongl"<"
say i": length =>"length(outda.i.sqldata)"<" ;
if length(outda.i.sqldata) > 62 then
say i": sqldata =>"substr(outda.i.sqldata,1,62)"<..." ;
else
say i": sqldata =>"outda.i.sqldata"<" ;
say ' ' ;
end ;
end ; /* do forever */
/**********************************************************************\
* Disconnect from the DB2 system. *
\**********************************************************************/
Address DSNREXX "DISCONNECT" ;
say "RC after DISCONNECT is" rc
s_rc = RXSUBCOM("DELETE","DSNREXX","DSNREXX") ;
exit 0 ;
sqlca_error:
call sqlca
exit 16
/*********************************************************************/
/* Error handling routine for bad SQL codes - just report and end. */
/*********************************************************************/
SQLCA:
/*********************************************************************/
SAY " SQLCODE = >"SQLCODE"<"
SAY " SQLSTATE = >"SQLSTATE"<"
SAY " SQLERRMC = >"SQLERRMC"<"
SAY " SQLERRP = >"SQLERRP"<"
SAY " SQLERRD.1= >"SQLERRD.1"<"
SAY " SQLERRD.2= >"SQLERRD.2"<"
SAY " SQLERRD.3= >"SQLERRD.3"<"
SAY " SQLERRD.4= >"SQLERRD.4"<"
SAY " SQLERRD.5= >"SQLERRD.5"<"
SAY " SQLERRD.6= >"SQLERRD.6"<"
SAY " SQLWARN.0= >"SQLWARN.0"<"
738 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
SAY " SQLWARN.1= >"SQLWARN.1"<"
SAY " SQLWARN.2= >"SQLWARN.2"<"
SAY " SQLWARN.3= >"SQLWARN.3"<"
SAY " SQLWARN.4= >"SQLWARN.4"<"
SAY " SQLWARN.5= >"SQLWARN.5"<"
SAY " SQLWARN.6= >"SQLWARN.6"<"
SAY " SQLWARN.7= >"SQLWARN.7"<"
SAY " SQLWARN.8= >"SQLWARN.8"<"
SAY " SQLWARN.9= >"SQLWARN.9"<"
SAY " SQLWARN.10= >"SQLWARN.10"<"
return ;
ssid = "VA1A" ;
Address DSNREXX ;
"CONNECT" ssid ;
if sqlcode \= 0 then do ;
say "CONNECT to" ssid "failed.";
call sqlca_error
exit 8 ;
end ;
Address DSNREXX ,
"EXECSQL EXECUTE IMMEDIATE :STMT" ;
/*
Write the CLOB to the preallocated file
*/
lines = 1500; /* enough 80 byte lines to make 2,000,000 bytes */
data.1 = "THIS IS A SHORT CLOB, BUT IT IS A CLOB 01" ;
data.2 = "THIS IS A SHORT CLOB, BUT IT IS A CLOB 02" ;
data.3 = "THIS IS A SHORT CLOB, BUT IT IS A CLOB 03" ;
data.4 = "THIS IS A SHORT CLOB, BUT IT IS A CLOB 04" ;
data.5 = "THIS IS A SHORT CLOB, BUT IT IS A CLOB 05" ;
data.6 = "THIS IS A SHORT CLOB, BUT IT IS A CLOB 06" ;
data.7 = "THIS IS A SHORT CLOB, BUT IT IS A CLOB 07" ;
data.8 = "THIS IS A SHORT CLOB, BUT IT IS A CLOB 08" ;
data.9 = "THIS IS A SHORT CLOB, BUT IT IS A CLOB 09" ;
data.10= "THIS IS A SHORT CLOB, BUT IT IS A CLOB 10" ;
data.0 = 10 ;
Do i = 1 to data.0 ;
data.i = left(data.i,131) ;
end ;
Do i = 1 to lines ;
Address MVS "EXECIO" data.0 "DISKW FRVFILE (stem data." ;
if rc <> 0 then do ;
say 'rc from execio='rc ;
signal bad_write ;
end ;
end ;
/*
The file now has to be freed. Otherwise, a
SQLCODE -452, reason 12 at location 210 will be
issued.
*/
/*
Build the special SQLDA used by REXX for working with
LOBs.
*/
mysqlda.sqld = 1 ;
mysqlda.1.sqltype = 920 /* clob file ref var */
mysqlda.1.sqlind = 0 ; /* not null */
/*
Note for a file reference variable, there is
no SQLDATA value. Just use SQLDATA as part of the stem
for .name and .fileoption, which are required for FRVs.
*/
/*
There are 4 fileoptions that can be set, and you can
specify the value via text or a number. Here are the
allowable values:
SQL_FILE_READ or 2
SQL_FILE_CREATE or 8
SQL_FILE_OVERWRITE or 16
SQL_FILE_APPEND or 32
*/
mysqlda.1.sqldata.fileoption = "SQL_FILE_READ" ;
/*
sqllen is the length of the file name
*/
mysqlda.1.sqllen = length(mysqlda.1.sqldata.name) ;
say "length(var1)="length(var1) ;
740 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
say "var1=" ;
say var1 ;
/**********************************************************************\
* Disconnect from the DB2 system. *
\**********************************************************************/
"DISCONNECT" ;
say "RC after DISCONNECT is" rc
s_rc = RXSUBCOM("DELETE","DSNREXX","DSNREXX") ;
exit 0 ;
sqlca_error:
call sqlca
if sqlcode > 0 then return ;
exit 8 ;
/*********************************************************************/
/* Error handling routine for bad SQL codes - just report and end. */
/*********************************************************************/
SQLCA:
/*********************************************************************/
SAY "Error. SQLCODE = >"SQLCODE"<"
SAY " SQLSTATE = >"SQLSTATE"<"
SAY " SQLERRMC = >"SQLERRMC"<"
SAY " SQLERRP = >"SQLERRP"<"
SAY " SQLERRD.1= >"SQLERRD.1"<"
SAY " SQLERRD.2= >"SQLERRD.2"<"
SAY " SQLERRD.3= >"SQLERRD.3"<"
SAY " SQLERRD.4= >"SQLERRD.4"<"
SAY " SQLERRD.5= >"SQLERRD.5"<"
SAY " SQLERRD.6= >"SQLERRD.6"<"
SAY " SQLWARN.0= >"SQLWARN.0"<"
SAY " SQLWARN.1= >"SQLWARN.1"<"
SAY " SQLWARN.2= >"SQLWARN.2"<"
SAY " SQLWARN.3= >"SQLWARN.3"<"
SAY " SQLWARN.4= >"SQLWARN.4"<"
SAY " SQLWARN.5= >"SQLWARN.5"<"
SAY " SQLWARN.6= >"SQLWARN.6"<"
SAY " SQLWARN.7= >"SQLWARN.7"<"
SAY " SQLWARN.8= >"SQLWARN.8"<"
SAY " SQLWARN.9= >"SQLWARN.9"<"
SAY " SQLWARN.10= >"SQLWARN.10"<"
return ;
Procedure
Code the SQLDA declarations directly in your program.
Each SQLDA consists of a set of REXX variables with a common stem. The stem must be a REXX variable
name that contains no periods and is the same as the value of descriptor-name that you specify when you
use the SQLDA in an SQL statement. For more information, see The REXX SQLDA (Db2 SQL).
Restrictions:
• You must place SQLDA declarations before the first SQL statement that references the data descriptor,
unless you use the TWOPASS SQL processing option.
• You cannot use the SQL INCLUDE statement for the SQLDA, because it is not supported in COBOL.
Related tasks
Defining SQL descriptor areas (SQLDA)
If your program includes certain SQL statements, you must define at least one SQL descriptor area
(SQLDA). Depending on the context in which it is used, the SQLDA stores information about prepared SQL
statements or host variables. This information can then be read by either the application program or Db2.
Related reference
The REXX SQLDA (Db2 SQL)
SQL descriptor area (SQLDA) (Db2 SQL)
742 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
The following table shows the SQL data types that Db2 assigns to input data and the corresponding
formats for that data. The two SQLTYPE values that are listed for each data type are the value for a
column that does not accept null values and the value for a column that accepts null values.
Table 119. SQL input data types and REXX data formats
SQL data type SQLTYPE for
assigned by Db2 data type REXX input data format
INTEGER 496/497 A string of numerics that does not contain a decimal point or exponent
identifier. The first character can be a plus (+) or minus (-) sign.
The number that is represented must be between -2147483648 and
2147483647, inclusive.
BIGINT 492/493 A string of numbers that does not contain a decimal point or
an exponent identifier. The first character can be a plus (+) or
minus (-) sign. The number that is represented must be between
-9223372036854775808 and -2147483648, inclusive, or between
2147483648 and 9223372036854775807.
DECIMAL(p,s) 484/485 One of the following formats:
• A string of numerics that contains a decimal point but no exponent
identifier. p represents the precision and s represents the scale of the
decimal number that the string represents. The first character can be a
plus (+) or minus (-) sign.
• A string of numerics that does not contain a decimal point or
an exponent identifier. The first character can be a plus (+)
or minus (-) sign. The number that is represented is less than
-9223372036854775808 or greater than 9223372036854775807.
FLOAT 480/481 A string that represents a number in scientific notation. The string
consists of a series of numerics followed by an exponent identifier (an
E or e followed by an optional plus (+) or minus (-) sign and a series of
numerics). The string can begin with a plus (+) or minus (-) sign.
VARCHAR(n) 448/449 One of the following formats:
• A string of length n, enclosed in single or double quotation marks.
• The character X or x, followed by a string enclosed in single or double
quotation marks. The string within the quotation marks has a length
of 2*n bytes and is the hexadecimal representation of a string of n
characters.
• A string of length n that does not have a numeric or graphic format, and
does not satisfy either of the previous conditions.
SQLSTMT="UPDATE EMP" ,
"SET MIDINIT = ?" ,
"WHERE EMPNO = '000200'"
"EXECSQL PREPARE S100 FROM :SQLSTMT"
HVMIDINIT='H'
"EXECSQL EXECUTE S100 USING" ,
":HVMIDINIT"
Because the data that is assigned to HVMIDINIT has a format that fits a character data type, Db2 REXX
Language Support assigns a VARCHAR type to the input data.
If you do not assign a value to a host variable before you assign the host variable to a column, Db2 returns
an error code.
Related concepts
Compatibility of SQL and language data types
The host variable data types that are used in SQL statements must be compatible with the data types of
the columns with which you intend to use them.
Notes:
1. CALL SQLDBS 'ATTACH TO' ssid is an alternative to ADDRESS DSNREXX 'CONNECT' ssid.
2. The REXX-variable or 'subsystem-ID' string may also be a single member name in a data sharing
group or the group attachment name.
The following example illustrates how to establish remote connections through the DSNREXX
interface.
/* REXX */
/* Sample to connect to remote subsystems */
/* Connect to the local subsystem */
ADDRESS DSNREXX 'CONNECT' 'DB01'
744 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
/* Now connect to multiple remote subsystems */
ADDRESS DSNREXX 'EXECSQL CONNECT TO REMOTESYS1'
.
.
.
ADDRESS DSNREXX 'EXECSQL CONNECT TO REMOTESYS2'
.
.
.
DSNREXX EXECSQL
Executes SQL statements in REXX programs.
The syntax of the DSNREXX EXECSQL command is:
Notes:
1. CALL 'SQLEXEC' "SQL-statement" is an alternative to ADDRESS DSNREXX 'EXECSQL' "SQL-
statement".
2. 'EXECSQL' and "SQL-statement" can be enclosed in either single or double quotation marks.
DSNREXX DISCONNECT
Deallocates the DSNREXX plan and removes the REXX task as a connected user of Db2.
You should execute the DSNREXX DISCONNECT command to release resources that are held by Db2.
Otherwise resources are not released until the REXX task terminates.
Do not use the DSNREXX DISCONNECT command from a stored procedure.
The syntax of the DSNREXX DISCONNECT command is:
'DISCONNECT'
ADDRESS DSNREXX
These application programming interfaces are available through the DSNREXX host command
environment. To make DSNREXX available to the application, invoke the RXSUBCOM function. The syntax
is:
'DELETE'
The ADD function adds DSNREXX to the REXX host command environment table. The DELETE function
deletes DSNREXX from the REXX host command environment table.
The following example illustrates REXX code that makes DSNREXX available to an application.
Related concepts
REXX stored procedures
A REXX stored procedure is similar to any other REXX procedure and follows the same rules as stored
procedures in other languages. A REXX stored procedure receives input parameters, executes REXX
commands, optionally executes SQL statements, and returns at most one output parameter. However, a
few differences exist.
Procedure
Precede and follow character literals with a double quotation mark, followed by a single quotation mark,
followed by another double quotation mark ("'").
For example, Specify the string the string 100 as "'"100"'".
Enclosing the string in apostrophes is not adequate, because REXX removes the apostrophes when it
assigns a literal to a variable. For example, suppose that you want to pass the value in a host variable
called stringvar to Db2. The value that you want to pass is the string '100'. First, you assign the string to
the host variable by issuing the following REXX command:
stringvar = '100'
After the command executes, stringvar contains the characters 100 (without the apostrophes). Db2 REXX
Language Support then passes the numeric value 100 to Db2, which is not what you intended.
However, suppose that you write the following command:
stringvar = "'"100"'"
In this case, REXX assigns the string '100' to stringvar, including the single quotation marks. Db2 REXX
Language Support then passes the string '100' to Db2, which is the result that you want.
Passing the data type of an input data type to Db2 for REXX programs
In certain situations, you should tell Db2 the data type to use for input data in a REXX program. For
example, if you are assigning or comparing input data to columns of type SMALLINT, CHAR, or GRAPHIC,
you should tell Db2 to use those data types.
Procedure
Use an SQLDA.
746 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Examples
Example: Specifying CHAR as an input data type
Suppose that you want to tell Db2 that the data with which you update the MIDINIT column of
the EMP table is of type CHAR, rather than VARCHAR. You need to set up an SQLDA that contains
a description of a CHAR column, and then prepare and execute the UPDATE statement using that
SQLDA, as shown in the following example.
Example: specifying the input data type as DECIMAL with precision and scale
Suppose that you want to tell Db2 that the data is of type DECIMAL with precision and nonzero scale.
You need to set up an SQLDA that contains a description of a DECIMAL column, as shown in the
following example.
Related reference
SQL descriptor area (SQLDA) (Db2 SQL)
The REXX SQLDA (Db2 SQL)
Procedure
Execute the SET CURRENT PACKAGESET statement to select one of the following Db2 REXX Language
Support packages with the isolation level that you need.
Table 120. Db2 REXX Language Support packages and associated isolation levels
Package namea Isolation level
DSNREXRR Repeatable read (RR)
DSNREXRS Read stability (RS)
DSNREXCS Cursor stability (CS)
DSNREXUR Uncommitted read (UR)
Note:
a. These packages enable your program to access Db2 and are bound when you install Db2 REXX
Language Support.
For example, to change the isolation level to cursor stability, execute the following SQL statement:
Table 121. SQL output data types and REXX data formats
SQL data type REXX output data format
A string of numerics that does not contain leading zeroes, a decimal
SMALLINT
point, or an exponent identifier. If the string represents a negative
INTEGER
number, it begins with a minus (-) sign. The numeric value is between
BIGINT
-9223372036854775808 and 9223372036854775807, inclusive.
DECIMAL(p,s) A string of numerics with one of the following formats:
• Contains a decimal point but not an exponent identifier. The string
is padded with zeroes to match the scale of the corresponding table
column. If the value represents a negative number, it begins with a minus
(-) sign.
• Does not contain a decimal point or an exponent identifier. The
numeric value is less than -9223372036854775808 or greater than
9223372036854775807. If the value is negative, it begins with a minus
(-) sign.
A character string or LOB value of length n bytes. The string is not enclosed
CHAR(n)
in single or double quotation marks.
VARCHAR(n)
CLOB(n)
BLOB(n)
Because you cannot use the SELECT INTO statement in a REXX procedure, to retrieve data from a Db2
table you must prepare a SELECT statement, open a cursor for the prepared statement, and then fetch
748 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
rows into host variables or an SQLDA using the cursor. The following example demonstrates how you can
retrieve data from a Db2 table using an SQLDA:
SQLSTMT= ,
'SELECT EMPNO, FIRSTNME, MIDINIT, LASTNAME,' ,
' WORKDEPT, PHONENO, HIREDATE, JOB,' ,
' EDLEVEL, SEX, BIRTHDATE, SALARY,' ,
' BONUS, COMM' ,
' FROM EMP'
EXECSQL DECLARE C1 CURSOR FOR S1
EXECSQL PREPARE S1 INTO :OUTSQLDA FROM :SQLSTMT
EXECSQL OPEN C1
Do Until(SQLCODE ¬= 0)
EXECSQL FETCH C1 USING DESCRIPTOR :OUTSQLDA
If SQLCODE = 0 Then Do
Line = ''
Do I = 1 To OUTSQLDA.SQLD
Line = Line OUTSQLDA.I.SQLDATA
End I
Say Line
End
End
Procedure
Db2 does not support the SQL WHENEVER statement in a REXX program. To handle SQL errors and
warnings, use the following methods:
• To test for SQL errors or warnings, test the SQLCODE or SQLSTATE value and the SQLWARN. values
after each EXECSQL call. This method does not detect errors in the REXX interface to Db2.
• To test for SQL errors or warnings or errors or warnings from the REXX interface to Db2, test the REXX
RC variable after each EXECSQL call.
The following table lists the values of the RC variable.
You can also use the REXX SIGNAL ON ERROR and SIGNAL ON FAILURE keyword instructions to
detect negative values of the RC variable and transfer control to an error routine.
Related tasks
Handling SQL error codes
Application programs can request more information about SQL error codes from Db2.
Related reference
GET DIAGNOSTICS (Db2 SQL)
750 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Chapter 5. Calling a stored procedure from your
application
To run a stored procedure, you can either call it from a client program or invoke it from the command line
processor.
Procedure
To call a stored procedure from your application:
1. Assign values to the IN and INOUT parameters.
2. Optional: To improve application performance, initialize the length of LOB output parameters to zero.
3. If the stored procedure exists at a remote location, perform the following actions:
a) Assign values to the OUT parameters.
When you call a stored procedure at a remote location, the local Db2 server cannot determine
whether the parameters are input (IN) or output (OUT or INOUT) parameters. Therefore, you
must initialize the values of all output parameters before you call a stored procedure at a remote
location.
b) Optional: Issue an explicit CONNECT statement to connect to the remote server.
If you do not issue this statement explicitly, you can implicitly connect to the server by using a
three-part name to identify the stored procedure in the next step.
The advantage of issuing an explicit CONNECT statement is that your CALL statement, which is
described in the next step, is portable to other operating systems. The advantage of implicitly
connecting is that you do not need to issue this extra CONNECT statement.
Requirement: When deciding whether to implicitly or explicitly connect to the remote server,
consider the requirement for programs that execute the ASSOCIATE LOCATORS or DESCRIBE
PROCEDURE statements. You must use the same form of the procedure name on the CALL
statement and on the ASSOCIATE LOCATORS or DESCRIBE PROCEDURE statement.
4. Invoke the stored procedure with the SQL CALL statement. Make sure that you pass parameter data
types that are compatible.
If the stored procedure exists on a remote server and you did not issue an explicit CONNECT
statement, specify a three-part name to identify the stored procedure, and implicitly connect to
the server where the stored procedure is located.
For native SQL procedures, the active version of the stored procedure is invoked by default.
Optionally, you can specify a version of the stored procedure other than the active version.
To allow null values for parameters, use indicator variables.
5. Optional: Retrieve the status of the procedure.
6. Process any output, including the OUT and INOUT parameters.
7. If the stored procedure returns multiple result sets, retrieve those result sets.
Recommendation: Close the result sets after you retrieve them, and issue frequent commits to
prevent Db2 storage shortages and EDM POOL FULL conditions.
8. For PL/I applications, also perform the following actions:
a) Include the run time option NOEXECOPS in your source code.
b) Specify the compile-time option SYSTEM(MVS).
These additional steps ensure that the linkage conventions work correctly on z/OS.
9. For C applications, include the following line in your source code:
#pragma runopts(PLIST(OS))
752 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
This code ensures that the linkage conventions work correctly on z/OS.
This option is not applicable to other operating systems. If you plan to use a C stored procedure
on other platforms besides z/OS, use one of the forms of conditional compilation, as shown in the
following example, to include this option only when you compile on z/OS.
Form 1
#ifdef MVS
#pragma runopts(PLIST(OS))
#endif
Form 2
#ifndef WKSTN
#pragma runopts(PLIST(OS))
#endif
10. Prepare the application as you would any other application by precompiling, compiling, and link-
editing the application and binding the DBRM.
If the application calls a remote stored procedure, perform the following additional steps when you
bind the DBRM:
• Bind the DBRM into a package at the local Db2 server. Use the bind option DBPROTOCOL(DRDA).
If the stored procedure name cannot be resolved until run time, also specify the bind option
VALIDATE(RUN). The stored procedure name might not be resolved at run time if you use a variable
for the stored procedure name or if the stored procedure exists on a remote server.
• Bind the DBRM into a package at the remote Db2 server. If your client program accesses multiple
servers, bind the program at each server.
• Bind all packages into a plan at the local Db2 server. Use the bind option DBPROTOCOL(DRDA).
11. Ensure that stored procedure completed successfully.
If a stored procedure abnormally terminates, Db2 performs the following actions:
• The calling program receives an SQL error as notification that the stored procedure failed.
• Db2 places the calling program's unit of work in a must-rollback state.
• Db2 stops the stored procedure, and subsequent calls fail, in either of the following conditions:
– The number of abnormal terminations equals the STOP AFTER n FAILURES value for the stored
procedure.
– The number of abnormal terminations equals the default MAX ABEND COUNT value for the
subsystem.
• The stored procedure does not handle the abend condition, and Db2 refreshes the environment
for Language Environment to recover the storage that the application uses. In most cases, the
environment does not need to restart.
• A data set is allocated in the DD statement CEEDUMP in the JCL procedure that starts the stored
procedures address space. In this case, Language Environment writes a small diagnostic dump to
this data set. Use the information in the dump to debug the stored procedure.
• In a data sharing environment, the stored procedure is placed in STOPABN status only on the
member where the abends occurred. A calling program can invoke the stored procedure from other
members of the data sharing group. The status on all other members is STARTED.
Examples
Example 1: Simple CALL statement
The following example shows a simple CALL statement that you might use to invoke stored procedure
A:
EXEC SQL CALL A (:EMP, :PRJ, :ACT, :EMT, :EMS, :EME, :TYPE, :CODE);
struct {
char EMP[7];
char PRJ[7];
short ACT;
short EMT;
char EMS[11];
char EME[11];
} empstruc;
You can then issue the following CALL statement to invoke stored procedure A:
• The following example shows how to implicitly connect to LOCA by specifying the three-part name
for stored procedure A in the CALL statement:
In this example, :IEMP, :IPRJ, :IACT, :IEMT, :IEMS, :IEME, :ITYPE, and :ICODE are indicator variables
for the parameters.
Example 5: Passing string constants and null values
The following example CALL statement passes integer and character string constants, a null value,
and several host variables:
EXEC SQL CALL :procnm (:EMP, :PRJ, :ACT, :EMT, :EMS, :EME,
:TYPE, :CODE);
Assume that the stored procedure name is A. The host variable procnm is a character variable of
length 255 or less that contains the value 'A'. Use this technique if you do not know in advance the
name of the stored procedure, but you do know the parameter list convention.
Example 7: Using an SQLDA to pass parameters in a single structure
The following example CALL statement shows how to pass parameters in a single structure, the
SQLDA, rather than as separate host variables:
754 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
EXEC SQL CALL A USING DESCRIPTOR :sqlda;
Your client program must assign a stored procedure name to the host variable procnm and load the
SQLDA with the parameter information before issuing the SQL CALL statement.
Related concepts
Stored procedure parameters
You can pass information between a stored procedure and the calling application program by using
parameters. Applications pass the required parameters in the SQL CALL statement. Optionally, the
application can also include an indicator variable with each parameter to allow for null values or to pass
large output parameter values.
Related tasks
Including dynamic SQL for varying-list SELECT statements in your program
A varying-list SELECT statement returns rows that contain an unknown number of values of unknown
type. When you use this type of statement, you do not know in advance exactly what kinds of host
variables you need to declare for storing the results.
Preparing an application to run on Db2 for z/OS
To prepare and run applications that contain embedded static SQL statements or dynamic SQL
statements, you must process, compile, link-edit, and bind the SQL statements.
Managing authorization for stored procedures (Managing Security)
Temporarily overriding the active version of a native SQL procedure
If you want a particular call to a native SQL procedure to use a version other than the active version, you
can temporarily override the active version. Such an override might be helpful when you are testing a new
version of a native SQL procedure.
Related reference
Statements (Db2 SQL)
Procedures that are supplied with Db2 (Db2 SQL)
Procedure
To pass large output parameters to stored procedures by using indicator variables:
1. Declare an indicator variable for every large output parameter in the stored procedure.
If you are using the GENERAL WITH NULLS or SQL linkage convention, you must declare indicator
variables for all of your parameters. In this case, you do not need to declare another indicator variable.
2. Assign a negative value to each indicator variable that is associated with a large output variable.
3. Include the indicator variables in the CALL statement.
Example
For example, suppose that a stored procedure that is defined with the GENERAL linkage convention takes
one integer input parameter and one character output parameter of length 6000. You do not want to
pass the 6000 byte storage area to the stored procedure. The following example PL/I program passes
only 2 bytes to the stored procedure for the output variable and receives all 6000 bytes from the stored
procedure:
Related reference
Linkage conventions for external stored procedures
The linkage convention for a stored procedure can be either GENERAL, GENERAL WITH NULLS, or SQL.
These linkage conventions apply to only external stored procedures.
756 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
For languages other than REXX
For all data types except LOBs, ROWIDs, locators, and VARCHARs (for C language), see the tables listed in
the following table for the host data types that are compatible with the data types in the stored procedure
definition.
SMALLINT A string of numerics that does not contain a decimal point or exponent
INTEGER identifier. The first character can be a plus or minus sign. This format also
applies to indicator variables that are passed as parameters.
BIGINT
DECIMAL(p,s) A string of numerics that has a decimal point but no exponent identifier. The
NUMERIC(p,s) first character can be a plus or minus sign.
REAL A string that represents a number in scientific notation. The string consists of a
FLOAT(n) series of numerics followed by an exponent identifier (an E or e followed by an
optional plus or minus sign and a series of numerics).
DOUBLE
DECFLOAT
GRAPHIC(n) The character G followed by a string enclosed in single quotation marks. The
VARGRAPHIC(n) string within the quotation marks begins with a shift-out character (X'0E') and
ends with a shift-in character (X'0F'). Between the shift-out character and
shift-in character are n double-byte characters.
BINARY Recommendation: Pass BINARY and VARBINARY values by using the SQLDA.
VARBINARY If you specify an SQLDA when you call the stored procedure, set the SQLTYPE
in the SQLDA. SQLDATA is a string of characters.
If you use host variables, the REXX format of BINARY and VARBINARY data is
BX followed by a string that is enclosed in a single quotation mark.
DATE A string of length 10, enclosed in single quotation marks. The format of the
string depends on the value of field DATE FORMAT that you specify when you
install Db2.
TIME A string of length 8, enclosed in single quotation marks. The format of the
string depends on the value of field TIME FORMAT that you specify when you
install Db2.
TIMESTAMP A string of length 19 to 32, enclosed in single quotation marks. The string has
the format yyyy-mm-dd-hh.mm.ss or yyyy-mm-dd-hh.mm.ss.nnnnnnnnnnnn,
where the number of fractional second digits can range 0 - 12.
TIMESTAMP WITH TIME A string of length 148 to 161, enclosed in single quotation marks. The string
ZONE has the format yyyymm- dd-hh.mm.ss.nnnnnnnnnnnn±th:tm or yyyymm- dd-
hh.mm.ss.nnnnnnnnnnnn ±th:tm, where the number of fractional second digits
can range 0 - 12
XML No equivalent.
The following figure demonstrates how a REXX procedure calls the stored procedure in “REXX stored
procedures” on page 282. The REXX procedure performs the following actions:
• Connects to the Db2 subsystem that was specified by the REXX procedure invoker.
• Calls the stored procedure to execute a Db2 command that was specified by the REXX procedure
invoker.
• Retrieves rows from a result set that contains the command output messages.
/* REXX */
PARSE ARG SSID COMMAND /* Get the SSID to connect to */
/* and the DB2 command to be */
/* executed */
/****************************************************************/
/* Set up the host command environment for SQL calls. */
/****************************************************************/
"SUBCOM DSNREXX" /* Host cmd env available? */
IF RC THEN /* No--make one */
S_RC = RXSUBCOM('ADD','DSNREXX','DSNREXX')
/****************************************************************/
/* Connect to the DB2 subsystem. */
/****************************************************************/
ADDRESS DSNREXX "CONNECT" SSID
IF SQLCODE ¬= 0 THEN CALL SQLCA
PROC = 'COMMAND'
RESULTSIZE = 32703
RESULT = LEFT(' ',RESULTSIZE,' ')
/****************************************************************/
/* Call the stored procedure that executes the DB2 command. */
/* The input variable (COMMAND) contains the DB2 command. */
/* The output variable (RESULT) will contain the return area */
/* from the IFI COMMAND call after the stored procedure */
/* executes. */
/****************************************************************/
ADDRESS DSNREXX "EXECSQL" ,
"CALL" PROC "(:COMMAND, :RESULT)"
IF SQLCODE < 0 THEN CALL SQLCA
SAY 'RETCODE ='RETCODE
SAY 'SQLCODE ='SQLCODE
SAY 'SQLERRMC ='SQLERRMC
SAY 'SQLERRP ='SQLERRP
SAY 'SQLERRD ='SQLERRD.1',',
|| SQLERRD.2',',
|| SQLERRD.3',',
|| SQLERRD.4',',
|| SQLERRD.5',',
|| SQLERRD.6
SAY 'SQLWARN ='SQLWARN.0',',
|| SQLWARN.1',',
758 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
|| SQLWARN.2',',
|| SQLWARN.3',',
|| SQLWARN.4',',
|| SQLWARN.5',',
|| SQLWARN.6',',
|| SQLWARN.7',',
|| SQLWARN.8',',
|| SQLWARN.9',',
|| SQLWARN.10
SAY 'SQLSTATE='SQLSTATE
SAY C2X(RESULT) "'"||RESULT||"'"
/****************************************************************/
/* Display the IFI return area in hexadecimal. */
/****************************************************************/
OFFSET = 4+1
TOTLEN = LENGTH(RESULT)
DO WHILE ( OFFSET < TOTLEN )
LEN = C2D(SUBSTR(RESULT,OFFSET,2))
SAY SUBSTR(RESULT,OFFSET+4,LEN-4-1)
OFFSET = OFFSET + LEN
END
/****************************************************************/
/* Get information about result sets returned by the */
/* stored procedure. */
/****************************************************************/
ADDRESS DSNREXX "EXECSQL DESCRIBE PROCEDURE :PROC INTO :SQLDA"
IF SQLCODE ¬= 0 THEN CALL SQLCA
DO I = 1 TO SQLDA.SQLD
SAY "SQLDA."I".SQLNAME ="SQLDA.I.SQLNAME";"
SAY "SQLDA."I".SQLTYPE ="SQLDA.I.SQLTYPE";"
SAY "SQLDA."I".SQLLOCATOR ="SQLDA.I.SQLLOCATOR";"
END I
/****************************************************************/
/* Set up a cursor to retrieve the rows from the result */
/* set. */
/****************************************************************/
ADDRESS DSNREXX "EXECSQL ASSOCIATE LOCATOR (:RESULT) WITH PROCEDURE :PROC"
IF SQLCODE ¬= 0 THEN CALL SQLCA
SAY RESULT
ADDRESS DSNREXX "EXECSQL ALLOCATE C101 CURSOR FOR RESULT SET :RESULT"
IF SQLCODE ¬= 0 THEN CALL SQLCA
CURSOR = 'C101'
ADDRESS DSNREXX "EXECSQL DESCRIBE CURSOR :CURSOR INTO :SQLDA"
IF SQLCODE ¬= 0 THEN CALL SQLCA
/****************************************************************/
/* Retrieve and display the rows from the result set, which */
/* contain the command output message text. */
/****************************************************************/
DO UNTIL(SQLCODE ¬= 0)
ADDRESS DSNREXX "EXECSQL FETCH C101 INTO :SEQNO, :TEXT"
IF SQLCODE = 0 THEN
DO
SAY TEXT
END
END
IF SQLCODE ¬= 0 THEN CALL SQLCA
ADDRESS DSNREXX "EXECSQL CLOSE C101"
IF SQLCODE ¬= 0 THEN CALL SQLCA
ADDRESS DSNREXX "EXECSQL COMMIT"
IF SQLCODE ¬= 0 THEN CALL SQLCA
/****************************************************************/
/* Disconnect from the DB2 subsystem. */
/****************************************************************/
ADDRESS DSNREXX "DISCONNECT"
IF SQLCODE ¬= 0 THEN CALL SQLCA
/****************************************************************/
/* Delete the host command environment for SQL. */
/****************************************************************/
S_RC = RXSUBCOM('DELETE','DSNREXX','DSNREXX') /* REMOVE CMD ENV */
RETURN
/****************************************************************/
/* Routine to display the SQLCA */
/****************************************************************/
SQLCA:
TRACE O
SAY 'SQLCODE ='SQLCODE
SAY 'SQLERRMC ='SQLERRMC
SAY 'SQLERRP ='SQLERRP
Related concepts
REXX stored procedures
A REXX stored procedure is similar to any other REXX procedure and follows the same rules as stored
procedures in other languages. A REXX stored procedure receives input parameters, executes REXX
commands, optionally executes SQL statements, and returns at most one output parameter. However, a
few differences exist.
Procedure
To prepare a client program that calls a remote stored procedure:
1. Precompile, compile, and link-edit the client program on the local Db2 subsystem.
2. Bind the resulting DBRM into a package at the local Db2 subsystem by using the BIND PACKAGE
command with the option DBPROTOCOL(DRDA).
3. Bind the same DBRM, the one for the client program, into a package at the remote location by using
the BIND PACKAGE command and specifying a location name. If your client program needs to access
multiple servers, bind the program at each server.
For example, suppose that you want a client program to call a stored procedure at location LOCA. You
precompile the program to produce DBRM A. Then you can use the following command to bind DBRM
A into package collection COLLA at location LOCA:
4. Bind all packages into a plan on the local Db2 subsystem. Specify the bind option
DBPROTOCOL(DRDA).
5. Bind any stored procedures that run under Db2 ODBC on a remote Db2 database server as a package
at the remote site.
Those procedures do not need to be bound into the Db2 ODBC plan.
Related tasks
Binding DBRMs to create packages (Db2 Programming for ODBC)
Related reference
BIND PACKAGE (DSN) (Db2 Commands)
760 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
How Db2 determines which stored procedure to run
A procedure is uniquely identified by its name and its qualifying schema name. You can tell Db2 exactly
which stored procedure to run by qualifying it with its schema name when you call it. Otherwise, Db2
determines which stored procedure to run.
However, if you do not qualify the stored procedure name, Db2 uses the following method to determine
which stored procedure to run:
1. Db2 searches the list of schema names from the PATH bind option or the CURRENT PATH special
register from left to right until it finds a schema name for which a stored procedure definition exists
with the name in the CALL statement.
Db2 uses schema names from the PATH bind option for CALL statements of the following form:
CALL procedure-name
Db2 uses schema names from the CURRENT PATH special register for CALL statements of the
following form:
CALL host-variable
2. When Db2 finds a stored procedure definition, Db2 executes that stored procedure if the following
conditions are true:
• The caller is authorized to execute the stored procedure.
• The stored procedure has the same number of parameters as in the CALL statement.
If both conditions are not true, Db2 continues to go through the list of schemas until it finds a stored
procedure that meets both conditions or reaches the end of the list.
3. If Db2 cannot find a suitable stored procedure, it returns an SQL error code for the CALL statement.
Procedure
To call different versions of a stored procedure from a single application:
1. When you define each version of the stored procedure, use the same stored procedure name but
different schema names, different COLLID values, and different WLM environments.
2. In the program that invokes the stored procedure, specify the unqualified stored procedure name in
the CALL statement.
3. Use the SQL path to indicate which version of the stored procedure that the client program should call.
You can choose the SQL path in several ways:
• If the client program is not an ODBC or JDBC application, use one of the following methods:
– Use the CALL procedure-name form of the CALL statement. When you bind plans or packages for
the program that calls the stored procedure, bind one plan or package for each version of the
stored procedure that you want to call. In the PATH bind option for each plan or package, specify
the schema name of the stored procedure that you want to call.
– Use the CALL host-variable form of the CALL statement. In the client program, use the SET PATH
statement to specify the schema name of the stored procedure that you want to call.
• If the client program is an ODBC or JDBC application, choose one of the following methods:
– Use the SET PATH statement to specify the schema name of the stored procedure that you want to
call.
Results
For example, suppose that you want to write one program, PROGY, that calls one of two versions of
a stored procedure named PROCX. The load module for both stored procedures is named SUMMOD.
Each version of SUMMOD is in a different load library. The stored procedures run in different WLM
environments, and the startup JCL for each WLM environment includes a STEPLIB concatenation that
specifies the correct load library for the stored procedure module.
First, define the two stored procedures in different schemas and different WLM environments:
When you write CALL statements for PROCX in program PROGY, use the unqualified form of the stored
procedure name:
CALL PROCX(V1,V2);
Bind two plans for PROGY. In one BIND statement, specify PATH(TEST). In the other BIND statement,
specify PATH(PROD).
To call TEST.PROCX, execute PROGY with the plan that you bound with PATH(TEST). To call PROD.PROCX,
execute PROGY with the plan that you bound with PATH(PROD).
762 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Procedure
To invoke multiple instances of a stored procedure:
1. To optimize storage usage and prevent storage shortages, ensure that you specify appropriate values
for the following two subsystem parameters:
MAX_ST_PROC
Controls the maximum number of stored procedure instances that you can call within the same
thread.
MAX_NUM_CUR
Controls the maximum number of cursors that can be opened by the same thread.
When either of the values from these subsystem parameters is exceeded while an application is
running, the CALL statement or the OPEN statement receives SQLCODE -904.
2. In your application, issue CALL statements to the stored procedure.
3. In the calling application for the stored procedure, close the result sets and issue frequent commits.
Even read-only applications should perform these actions.
Applications that fail to close result sets or issue an adequate number of commits might terminate
abnormally with Db2 storage shortage and EDM POOL FULL conditions.
Related reference
MAX OPEN CURSORS field (MAX_NUM_CUR subsystem parameter) (Db2 Installation and Migration)
MAX STORED PROCS field (MAX_ST_PROC subsystem parameter) (Db2 Installation and Migration)
CALL (Db2 SQL)
Procedure
To designate the active version of a native SQL procedure, issue an ALTER PROCEDURE statement with
the following items:
• The name of the native SQL procedure for which you want to change the active version.
• The ACTIVATE VERSION clause with the name of the version that you want to be active.
When the ALTER statement is committed, the new version of the procedure becomes the active version
and is used by the next call for that procedure.
Example
The following ALTER PROCEDURE statement makes version V2 of the UPDATE_BALANCE procedure the
active version.
Procedure
To temporarily override the active version of a native SQL procedure, specify the following statements in
your program:
1. The SET CURRENT ROUTINE VERSION statement with the name of the version of the procedure that
you want to use. If the specified version does not exist, the active version is used.
2. The CALL statement with the name of the procedure.
Example
The following CALL statement invokes version V1 of the UPDATE_BALANCE procedure, regardless of what
the current active version of that procedure is.
Procedure
You can override that value in the following ways:
• Edit the JCL procedures that start stored procedures address spaces, and modify the value of the
NUMTCB parameter.
• Specify the following parameter in the Start Parameters field of the Create An Application Environment
panel when you set up a WLM application environment:
NUMTCB=number-of-TCBs
Special cases:
– For REXX stored procedures, you must set the NUMTCB parameter to 1.
– Stored procedures that invoke utilities can invoke only one utility at a time in a single address space.
Consequently, the value of the NUMTCB parameter is forced to 1 for those procedures.
Related concepts
Installation step 21: Configure Db2 for running stored procedures and user-defined functions (Db2
Installation and Migration)
764 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Migration step 23: Configure Db2 for running stored procedures and user-defined functions (optional)
(Db2 Installation and Migration)
Related tasks
Maximizing the number of procedures or functions that run in an address space (Db2 Performance)
Procedure
To retrieve the procedure status, perform one of the following actions in the calling program:
• Issue the GET DIAGNOSTICS statement with the DB2_RETURN_STATUS item. The specified host
variable in the GET DIAGNOSTICS statement is set to one of the following values:
0
This value indicates that the procedure returned with an SQLCODE that is greater or equal to zero.
You can access the value directly from the SQLCA by retrieving the value of SQLERRD(1). For C
applications, retrieve SQLERRD[0].
-1
This value indicates that the procedure returned with an SQLCODE that is less than zero. In this
case, the SQLERRD(1) value in the SQLCA is not set. Db2 returns -1 only.
n
Any value other than 0 or -1 is the return value that was explicitly set in the procedure with the
RETURN statement.
For example, the following SQL code creates an SQL procedure that is named TESTIT, which calls
another SQL procedure that is named TRYIT. The TRYIT procedure returns a status value. The
TESTIT procedure retrieves that value with the DB2_RETURN_STATUS item of the GET DIAGNOSTICS
statement.
• Retrieve the value of SQLERRD(1) in the SQLCA. For C applications, retrieve SQLERRD[0]. This field
contains the integer value that was set by the RETURN statement in the SQL procedure. This method is
not applicable if the status was set by Db2.
Related concepts
SQL communication area (SQLCA) (Db2 SQL)
Related reference
GET DIAGNOSTICS (Db2 SQL)
Procedure
To write a program to receive the result sets from a stored procedure:
1. Declare a locator variable for each result set that is to be returned.
If you do not know how many result sets are to be returned, declare enough result set locators for the
maximum number of result sets that might be returned.
2. Call the stored procedure and check the SQL return code.
If the SQLCODE from the CALL statement is +466, the stored procedure has returned result sets.
3. Determine how many result sets the stored procedure is returning.
If you already know how many result sets the stored procedure returns, skip this step.
Use the SQL statement DESCRIBE PROCEDURE to determine the number of result sets. DESCRIBE
PROCEDURE places information about the result sets in an SQLDA. Make this SQLDA large enough to
hold the maximum number of result sets that the stored procedure might return. When the DESCRIBE
PROCEDURE statement completes, the fields in the SQLDA contain the following values:
• SQLD contains the number of result sets that are returned by the stored procedure.
• Each SQLVAR entry gives the following information about a result set:
– The SQLNAME field contains the name of the SQL cursor that is used by the stored procedure to
return the result set.
– The SQLIND field contains the value -1, which indicates that no estimate of the number of rows in
the result set is available.
– The SQLDATA field contains the value of the result set locator, which is the address of the result
set.
4. Link result set locators to result sets by performing one of the following actions:
• Use the ASSOCIATE LOCATORS statement. You must embed this statement in an application or SQL
procedure. The ASSOCIATE LOCATORS statement assigns values to the result set locator variables.
766 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
If you specify more locators than the number of result sets that are returned, Db2 ignores the extra
locators.
• If you executed the DESCRIBE PROCEDURE statement previously, the result set locator values are in
the SQLDATA fields of the SQLDA. You can copy the values from the SQLDATA fields to the result set
locators manually, or you can execute the ASSOCIATE LOCATORS statement to do it for you.
The stored procedure name that you specify in an ASSOCIATE LOCATORS statement or DESCRIBE
PROCEDURE statement must match the stored procedure name in the CALL statement as follows:
• If the name is unqualified in the CALL statement, do not qualify it.
• If the name is qualified with a schema name in the CALL statement, qualify it with the schema name.
• If the name is qualified with a location name and schema name in the CALL statement, qualify it with
a location name and schema name.
5. Allocate cursors for fetching rows from the result sets.
Use the SQL statement ALLOCATE CURSOR to link each result set with a cursor. Execute one
ALLOCATE CURSOR statement for each result set. The cursor names can differ from the cursor names
in the stored procedure.
To use the ALLOCATE CURSOR statement, you must embed it in an application or SQL procedure.
6. Determine the contents of the result sets.
If you already know the format of the result set, skip this step.
Use the SQL statement DESCRIBE CURSOR to determine the format of a result set and put this
information in an SQLDA. For each result set, you need an SQLDA that is big enough to hold
descriptions of all columns in the result set.
You can use DESCRIBE CURSOR for only those cursors for which you executed ALLOCATE CURSOR
previously.
After you execute DESCRIBE CURSOR, if the cursor for the result set is declared WITH HOLD, the
high-order bit of byte 8 of field SQLDAID in the SQLDA is set to 1.
7. Fetch rows from the result sets into host variables by using the cursors that you allocated with the
ALLOCATE CURSOR statements.
Fetching rows from a result set is the same as fetching rows from a table.
If you executed the DESCRIBE CURSOR statement, perform the following steps before you fetch the
rows:
a. Allocate storage for host variables and indicator variables. Use the contents of the SQLDA from the
DESCRIBE CURSOR statement to determine how much storage you need for each host variable.
b. Put the address of the storage for each host variable in the appropriate SQLDATA field of the
SQLDA.
c. Put the address of the storage for each indicator variable in the appropriate SQLIND field of the
SQLDA.
Example
The following examples show C language code that accomplishes each of these steps. Coding for other
languages is similar.
The following example demonstrates how to receive result sets when you know how many result sets are
returned and what is in each result set.
/*************************************************************/
/* Declare result set locators. For this example, */
/* assume you know that two result sets will be returned. */
/* Also, assume that you know the format of each result set. */
/*************************************************************/
EXEC SQL BEGIN DECLARE SECTION;
static volatile SQL TYPE IS RESULT_SET_LOCATOR *loc1, *loc2;
EXEC SQL END DECLARE SECTION;
The following example demonstrates how to receive result sets when you do not know how many result
sets are returned or what is in each result set.
/*************************************************************/
/* Declare result set locators. For this example, */
/* assume that no more than three result sets will be */
/* returned, so declare three locators. Also, assume */
/* that you do not know the format of the result sets. */
/*************************************************************/
EXEC SQL BEGIN DECLARE SECTION;
static volatile SQL TYPE IS RESULT_SET_LOCATOR *loc1, *loc2, *loc3;
EXEC SQL END DECLARE SECTION;
⋮
/*************************************************************/
/* Call stored procedure P2. */
/* Check for SQLCODE +466, which indicates that result sets */
/* were returned. */
/*************************************************************/
EXEC SQL CALL P2(:parm1, :parm2, ...);
if(SQLCODE==+466)
{
/*************************************************************/
/* Determine how many result sets P2 returned, using the */
/* statement DESCRIBE PROCEDURE. :proc_da is an SQLDA */
/* with enough storage to accommodate up to three SQLVAR */
/* entries. */
/*************************************************************/
EXEC SQL DESCRIBE PROCEDURE P2 INTO :proc_da;
⋮
/*************************************************************/
/* Now that you know how many result sets were returned, */
/* establish a link between each result set and its */
/* locator using the ASSOCIATE LOCATORS. For this example, */
/* we assume that three result sets are returned. */
/*************************************************************/
EXEC SQL ASSOCIATE LOCATORS (:loc1, :loc2, :loc3) WITH PROCEDURE P2;
⋮
/*************************************************************/
/* Associate a cursor with each result set. */
/*************************************************************/
EXEC SQL ALLOCATE C1 CURSOR FOR RESULT SET :loc1;
768 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
EXEC SQL ALLOCATE C2 CURSOR FOR RESULT SET :loc2;
EXEC SQL ALLOCATE C3 CURSOR FOR RESULT SET :loc3;
/*************************************************************/
/* Use the statement DESCRIBE CURSOR to determine the */
/* format of each result set. */
/*************************************************************/
EXEC SQL DESCRIBE CURSOR C1 INTO :res_da1;
EXEC SQL DESCRIBE CURSOR C2 INTO :res_da2;
EXEC SQL DESCRIBE CURSOR C3 INTO :res_da3;
⋮
/*************************************************************/
/* Assign values to the SQLDATA and SQLIND fields of the */
/* SQLDAs that you used in the DESCRIBE CURSOR statements. */
/* These values are the addresses of the host variables and */
/* indicator variables into which DB2 will put result set */
/* rows. */
/*************************************************************/
⋮
/*************************************************************/
/* Fetch the result set rows into the storage areas */
/* that the SQLDAs point to. */
/*************************************************************/
while(SQLCODE==0)
{
EXEC SQL FETCH C1 USING :res_da1;
⋮
}
while(SQLCODE==0)
{
EXEC SQL FETCH C2 USING :res_da2;
⋮
}
while(SQLCODE==0)
{
EXEC SQL FETCH C3 USING :res_da3;
⋮
}
}
The following example demonstrates how you can use an SQL procedure to receive result sets. The logic
assumes that no handler exists to intercept the +466 SQLCODE, such as DECLARE CONTINUE HANDLER
FOR SQLWARNING ..... Such a handler causes SQLCODE to be reset to zero. Then the test for IF
SQLCODE = 466 is never true and the statements in the IF body are never executed.
Related concepts
Example programs that call stored procedures
770 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Chapter 6. Coding methods for distributed data
You can access distributed data by using three-part table names or explicit connect statements.
Introductory concepts
Distributed data (Introduction to Db2 for z/OS)
Effects of distributed data on programming (Introduction to Db2 for z/OS)
Distributed data access (Introduction to Db2 for z/OS)
Three-part table names are described in “Accessing distributed data by using three-part table names”
on page 771. Explicit connect statements are described in “Accessing distributed data by using explicit
CONNECT statements” on page 773.
These two methods of coding applications for distributed access are illustrated by the following example.
Spiffy Computer has a main project table that supplies information about all projects that are currently
active throughout the company. Spiffy has several branches in various locations around the world, each a
Db2 location that maintains a copy of the project table named DSN8C10.PROJ. The main branch location
occasionally inserts data into all copies of the table. The application that makes the inserts uses a
table of location names. For each row that is inserted, the application executes an INSERT statement in
DSN8C10.PROJ for each location.
Example
The following example assumes that all systems involved implement two-phase commit. This example
suggests updating several systems in a loop and ending the unit of work by committing only when the
loop is complete. Updates are coordinated across the entire set of systems.
After the application obtains the next alias of a remote table to be inserted, For example, REGION1PROJ
(which is the DSN8C10.PROJ table at location SAN_JOSE), it creates the following character string:
The application assigns the character string to the variable INSERTX and then executes these statements:
EXEC SQL
PREPARE STMT1 FROM :INSERTX;
EXEC SQL
EXECUTE STMT1 USING :PROJNO, :PROJNAME, :DEPTNO, :RESPEMP,
:PRSTAFF, :PRSTDATE, :PRENDATE, :MAJPROJ;
The host variables for Spiffy's project table match the declaration for the sample project table.
To keep the data consistent at all locations, the application commits the work only when the loop has
executed for all locations. Either every location has committed the INSERT or, if a failure has prevented
any location from inserting, all other locations have rolled back the INSERT. (If a failure occurs during the
commit process, the entire unit of work can be indoubt.)
772 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Accessing remote declared temporary tables by using three-part table
names
You can access a remote declared temporary table by using a three-part name. However, if you combine
explicit CONNECT statements and three-part names in your application, a reference to a remote declared
temporary table must be a forward reference.
In a CREATE GLOBAL TEMPORARY TABLE or DECLARE GLOBAL TEMPORARY TABLE statement, you
cannot specify an alias that resolves to a three-part name object at a remote location. You also cannot
specify a three-part name object even if the location of the three-part name refers to the location where
the object is being created or declared.
Example
You can perform the following series of actions, which includes a forward reference to a declared
temporary table:
However, you cannot perform the following series of actions, which includes a backward reference to the
declared temporary table:
EXEC SQL
DECLARE GLOBAL TEMPORARY TABLE T1 /* Define the temporary table */
(CHARCOL CHAR(6) NOT NULL) /* at the local site (ATLANTA)*/
ON COMMIT DROP TABLE;
EXEC SQL CONNECT TO CHICAGO; /* Connect to the remote site */
EXEC SQL INSERT INTO ATLANTA.SESSION.T1
(VALUES 'ABCDEF'); /* Cannot access temp table */
/* from the remote site (backward reference)*/
The CONNECT and DECLARE statements refer to the real declared temp table.
For example, the application inserts a new location name into the variable LOCATION_NAME and
executes the following statements:
EXEC SQL
CONNECT TO :LOCATION_NAME;
EXEC SQL
INSERT INTO DSN8C10.PROJ VALUES (:PROJNO, :PROJNAME, :DEPTNO, :RESPEMP,
:PRSTAFF, :PRSTDATE, :PRENDATE, :MAJPROJ);
To keep the data consistent at all locations, the application commits the work only when the loop has
executed for all locations. Either every location has committed the INSERT or, if a failure has prevented
any location from inserting, all other locations have rolled back the INSERT. (If a failure occurs during the
commit process, the entire unit of work can be indoubt.)
The host variables for Spiffy's project table match the declaration for the sample project table.
LOCATION_NAME is a character-string variable of length 16.
Related reference
Project table (DSN8C10.PROJ) (Introduction to Db2 for z/OS)
774 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
that the database is not found. If the remote server is Db2, the location SVL_EMPLOYEE might be defined
as a location alias for EMPLOYEE. Db2 z/OS servers are defined with this alias by using the DDF ALIAS
statement of the DSNJU003 change log inventory utility. Db2 locally executes any SQL statements that
contain fully qualified object names if the high-level qualifier is the location name or any of its alias
names.
Related reference
LOCATIONS catalog table (Db2 SQL)
DSNJU003 (change log inventory) (Db2 Utilities)
Releasing connections
When you connect to remote locations explicitly, you must also terminate those connections explicitly.
Example
By using the RELEASE statement, you can place any of the following connections in the release-pending
state:
• A specific connection that the next unit of work does not use:
776 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Distributed queries against ASCII or Unicode tables
When you perform a distributed query, the server determines the encoding scheme of the result table.
When a distributed query against an ASCII or Unicode table arrives at the Db2 for z/OS server, the server
indicates in the reply message that the columns of the result table contain ASCII or Unicode data, rather
than EBCDIC data. The reply message also includes the CCSIDs of the data to be returned. The CCSID of
data from a column is the CCSID that was in effect when the column was defined.
The encoding scheme in which Db2 returns data depends on two factors:
• The encoding scheme of the requesting system.
If the requester is ASCII or Unicode, the returned data is ASCII or Unicode. If the requester is EBCDIC,
the returned data is EBCDIC, even though it is stored at the server as ASCII or Unicode. However, if the
SELECT statement that is used to retrieve the data contains an ORDER BY clause, the data displays in
ASCII or Unicode order.
• Whether the application program overrides the CCSID for the returned data. The ways to do this are as
follows:
– For static SQL
You can bind a plan or package with the ENCODING bind option to control the CCSIDs for all static
data in that plan or package. For example, if you specify ENCODING(UNICODE) when you bind a
package at a remote Db2 for z/OS system, the data that is returned in host variables from the remote
system is encoded in the default Unicode CCSID for that system.
– For static or dynamic SQL
An application program can specify overriding CCSIDs for individual host variables in DECLARE
VARIABLE statements.
An application program that uses an SQLDA can specify an overriding CCSID for the returned data in
the SQLDA. When the application program executes a FETCH statement, you receive the data in the
CCSID that is specified in the SQLDA.
Related tasks
Setting the CCSID for host variables
All Db2 string data, other than binary data, has an encoding scheme and a coded character set ID (CCSID)
associated with it. You can associate an encoding scheme and a CCSID with individual host variables. Any
data in those host variable is then associated with that encoding scheme and CCSID.
Related reference
BIND and REBIND options for packages, plans, and services (Db2 Commands)
IBM MQ messages
IBM MQ uses messages to pass information between applications.
Messages consist of the following parts:
• The message attributes, which identify the message and its properties.
• The message data, which is the application data that is carried in the message.
Related concepts
Db2 MQ functions and Db2 MQ XML stored procedures
You can use the Db2 MQ functions and stored procedures to send messages to a message queue or to
receive messages from the message queue.
778 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
service
Defines where the message is going to or coming from. The parameters for managing a queue are
defined in the service, which is typically defined by a system administrator. The complexity of the
parameters in the service is hidden from the application program.
policy
Defines how the message is handled. Policies control such items as:
• The attributes of the message, for example, the priority.
• Options for send and receive operations, for example, whether an operation is part of a unit of work.
The default service and policy are set as part of defining the WebSphere MQ configuration for a particular
installation of Db2. (This action is typically performed by a system administrator.) Db2 provides the
default service Db2.DEFAULT.SERVICE and the default policy Db2.DEFAULT.POLICY.
Related tasks
Additional steps for enabling IBM MQ user-defined functions (Db2 Installation and Migration)
Related reference
IBM MQ home
780 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
The Db2 MQ functions include scalar functions, table functions, and XML-specific functions. For each of
these functions, you can call a version that uses the MQI. The function signatures are the same. However,
the qualifying schema names are different. To call an MQI-based function, specify the schema name
DB2MQ.
Requirement: Before you can call the version of these functions that uses MQI , you need to populate the
Db2 MQ tables.
The following table describes the Db2 MQ scalar functions.
Notes:
1. You can send or receive messages in VARCHAR variables or CLOB variables. The maximum length for a
message in a VARCHAR variable is 32 KB. The maximum length for a message in a CLOB variable is 2 MB.
The following table describes the MQ table functions that Db2 can use.
Notes:
1. You can send or receive messages in VARCHAR variables or CLOB variables. The maximum length for a
message in a VARCHAR variable is 32 KB. The maximum length for a message in a CLOB variable is 2 MB.
2. The first column of the result table of a Db2 MQ table function contains the message.
Related tasks
Additional steps for enabling IBM MQ user-defined functions (Db2 Installation and Migration)
Related reference
Procedures that are supplied with Db2 (Db2 SQL)
MQREADALL (Db2 SQL)
MQREADALLCLOB (Db2 SQL)
MQRECEIVEALL (Db2 SQL)
MQRECEIVEALLCLOB (Db2 SQL)
The Message Queue Interface overview
782 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Generating XML documents from existing tables and sending them to an MQ
message queue
You can send data from a Db2 table to the MQ message queue. First put the data in an XML document and
then send that document to the message queue.
Procedure
To generate XML documents from existing tables and send them to an MQ message queue:
1. Compose an XML document by using the Db2 XML publishing functions.
2. Cast the XML document to type VARCHAR or CLOB.
3. Send the document to an MQ message queue by using the appropriate Db2 MQ function.
Related concepts
Db2 MQ functions and Db2 MQ XML stored procedures
You can use the Db2 MQ functions and stored procedures to send messages to a message queue or to
receive messages from the message queue.
Functions for constructing XML values (Db2 Programming for XML)
Procedure
To shred XML documents from an MQ message queue:
1. Retrieve the XML document from an MQ message queue by using the appropriate MQ function.
2. Shred the retrieved message to Db2 tables by using the XML decomposition stored procedure
(XDBDECOMPXML).
Related concepts
Db2 MQ functions and Db2 MQ XML stored procedures
You can use the Db2 MQ functions and stored procedures to send messages to a message queue or to
receive messages from the message queue.
Db2 MQ tables
The Db2 MQ tables contain service and policy definitions that are used by the Message Queue Interface
(MQI) based Db2 MQ functions. You must populate the Db2 MQ tables before you can use these MQI-
based functions.
The Db2 MQ tables are SYSIBM.MQSERVICE_TABLE and SYSIBM.MQPOLICY_TABLE. These tables are
user-managed. You need to create them during the installation or migration process. Installation job
DSNTIJRT creates these tables with one default row in each table.
If you previously used the AMI-based Db2 MQ functions, you used AMI configuration files instead of these
tables. To use the MQI-based Db2 MQ functions, you need to move the data from those configuration files
to the Db2 tables SYSIBM.MQSERVICE_TABLE and SYSIBM.MQPOLICY_TABLE .
The following table describes the columns for SYSIBM.MQSERVICE_TABLE.
784 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 128. SYSIBM.MQPOLICY_TABLE column descriptions (continued)
Column name Description
SEND_PRIORITY This column contains the priority of the message.
This column corresponds to the Priority field in the
message descriptor structure (MQMD). MQ functions
use the value in this column to set the Priority field.
The default value for this column is -1, which
sets the Priority field in the MQMD to the value
MQQPRI_PRIORITY_AS_Q_DEF.
786 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 128. SYSIBM.MQPOLICY_TABLE column descriptions (continued)
Column name Description
SEND_EXCEPTION_ACTION This column specifies what to do with the original
message when it cannot be delivered to the
destination queue.
This column corresponds to the Report field in the
message descriptor structure (MQMD). MQ functions
use the value in this column to set the Report field.
This column can have one of the following values:
Q
Sets the MQRO_DEAD_LETTER_Q option in the
Report field in the MQMD. This value is the default.
D
Sets the MQRO_DISCARD_MSG option in the
Report field in the MQMD.
P
Sets the MQRO_PASS_DISCARD_AND_EXPIRY
option in the Report field in the MQMD.
788 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 128. SYSIBM.MQPOLICY_TABLE column descriptions (continued)
Column name Description
SEND_REPORT_EXPIRY This column specifies whether the queue manager is
to send an expiration report message if a message is
discarded before it is delivered to an application, and if
so, what that message is to contain.
This column corresponds to the Report field in the
message descriptor structure (MQMD). MQ functions
use the value in this column to set the Report field.
This column can have one of the following values:
N
Specifies that an expiration report message is not
to be sent. No options in the Report field are
set.This value is the default.
C
Sets the MQRO_EXPIRATION option in the Report
field in the MQMD.
D
Sets the MQRO_EXPIRATION_WITH_DATA option
in the Report field in the MQMD.
F
Sets the MQRO_EXPIRATION_WITH_FULL_DATA
option in the Report field in the MQMD.
790 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 128. SYSIBM.MQPOLICY_TABLE column descriptions (continued)
Column name Description
RCV_WAIT_INTERVAL This column contains the time, in milliseconds, that
Db2 is to wait for messages to arrive in the queue.
This column corresponds to the WaitInterval field
in the get message options structure (MQGMO). MQ
functions use the value in this column to set the
WaitInterval field.
The default is 10.
Related reference
Core WLM environments for Db2-supplied routines (Db2 Installation and Migration)
Developing applications reference
792 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Information is received in the form of messages from one or more sources. An information source
can be any application. The data is received from queues and stored in database tables for additional
processing.
• Workload distribution
Work requests are posted to a queue that is shared by multiple instances of the same application. When
an application instance is ready to perform some work, it receives a message that contains a work
request from the head of the queue. Multiple instances of the application can share the workload that is
represented by a single queue of pooled requests.
• Application signaling
In a situation where several processes collaborate, messages are often used to coordinate their efforts.
These messages might contain commands or requests for work that is to be performed. For more
information about this technique, see “Application to application connectivity with IBM MQ” on page
795.
The following scenario extends basic messaging to incorporate remote messaging. Assume that machine
A sends a message to machine B.
1. The Db2 client executes an MQSEND function call, specifying a target service that has been defined to
be a remote queue on machine B.
2. The MQ functions perform the work to send the message. The WebSphere MQ server on machine A
accepts the message and guarantees that it will deliver it to the destination that is defined by the
service and the current MQ configuration of machine A. The server determines that the destination is a
queue on machine B. The server then attempts to deliver the message to the WebSphere MQ server on
machine B, trying again as needed.
3. The IBM MQ server on machine B accepts the message from the server on machine A and places it in
the destination queue on machine B.
4. A IBM MQ client on machine B requests the message at the head of the queue.
Procedure
To send messages with IBM MQ, use MQSEND.
Message content can be any combination of SQL statements, expressions, functions, and user-specified
data. Because this MQSEND function uses two-phase commit, the COMMIT statement ensures that the
message is added to the MQ queue.
Examples
If you send more than one column of information, separate the columns with the characters || ' ' ||.
MQSEND (LASTNAME || ' ' || FIRSTNAME)
The following examples use the DB2MQ schema for two-phase commit, with the default service
Db2.DEFAULT.SERVICE and the default policy Db2.DEFAULT.POLICY.
The following SQL SELECT statement sends a message that consists of the string "Testing msg":
Related reference
MQSEND (Db2 SQL)
Examples
The following examples use the DB2MQ2N schema for two-phase commit, with the default service
Db2.DEFAULT.SERVICE and the default policy Db2.DEFAULT.POLICY.
Example
The following SQL SELECT statement reads the message at the head of the queue that is specified by
the default service and policy:
SELECT DB2MQ2N.MQREAD()
FROM SYSIBM.SYSDUMMY1;
The MQREAD function is invoked once because SYSIBM.SYSDUMMY1 has only one row. The SELECT
statement returns a VARCHAR(4000) string. If no messages are available to be read, a null value is
returned. Because MQREAD does not change the queue, you do not need to use a COMMIT statement.
Example
The following SQL SELECT statement causes the contents of a queue to be materialized as a Db2
table:
SELECT T.*
FROM TABLE(DB2MQ2N.MQREADALL()) T;
The result table T of the table function consists of all the messages in the queue, which is defined
by the default service, and the metadata about those messages. The first column of the materialized
result table is the message itself, and the remaining columns contain the metadata. The SELECT
794 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
statement returns both the messages and the metadata.To return only the messages, issue the
following statement:
SELECT T.MSG
FROM TABLE(DB2MQ2N.MQREADALL()) T;
The result table T of the table function consists of all the messages in the queue, which is defined by
the default service, and the metadata about those messages. This SELECT statement returns only the
messages.
Example
The following SQL SELECT statement receives (removes) the message at the head of the queue:
SELECT DB2MQ2N.MQRECEIVE()
FROM SYSIBM.SYSDUMMY1;
COMMIT;
The MQRECEIVE function is invoked once because SYSIBM.SYSDUMMY1 has only one row. The
SELECT statement returns a VARCHAR(4000) string. Because this MQRECEIVE function uses two-
phase commit, the COMMIT statement ensures that the message is removed from the queue. If no
messages are available to be retrieved, a null value is returned, and the queue does not change.
Example
Assume that you have a MESSAGES table with a single VARCHAR(2000) column. The following SQL
INSERT statement inserts all of the messages from the default service queue into the MESSAGES
table in your Db2 database:
The result table T of the table function consists of all the messages in the default service queue and
the metadata about those messages. The SELECT statement returns only the messages. The INSERT
statement stores the messages into a table in your database.
The MQSEND function is invoked once because SYSIBM.SYSDUMMY1 has only one row. Because this
MQSEND uses single-phase commit, IBM MQ adds the message to the queue, and you do not need to
use a COMMIT statement.
Example
The following SQL SELECT statement receives the first message that matches the identifier CORRID1
from the queue that is specified by the service MYSERVICE, using the policy MYPOLICY:
The SELECT statement returns a VARCHAR(4000) string. If no messages are available with this
correlation identifier, a null value is returned, and the queue does not change.
796 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
it is still possible for the client to receive the reply. Or, if the client is on a mobile computer and becomes
disconnected from the database, and if a response is sent, the client can still receive the reply.
• The content of the messages in the database contain information about when to process particular
requests. The messages in the database use priorities and the request contents to determine how to
schedule the requests.
• An asynchronous message listener can delegate a request to a different node. It can forward the
request to a second computer to complete the processing. When the request is complete, the second
computer returns a response directly to the endpoint that is specified in the message.
• An asynchronous listener can respond to a message from a supplied client, or from a user-defined
application. The number of environments that can act as a database client is greatly expanded. Clients
such as factory automation equipment, pervasive devices, or embedded controllers can communicate
with Db2 either directly through IBM MQ or through some gateway that supports WebSphere MQ.
Transaction support
There is support for both one-phase and two-phase commit environments. A one-phase commit
environment is where DB interactions and MQ interactions are independent. A two-phase commit
environment is where DB interactions and MQ interactions are combined in a single unit of work.
'db2mqln1' is the name of the executable for one phase and 'db2mqln2' is the name of the executable for
two phase.
CREATE schema.proc(
IN INMSG inMsgType,
OUT OUTMSG outMsgType)...
The data type for INMSG and the data type for OUTMSG can be VARCHAR, VARBINARY, CLOB, or
BLOB, of any length, and are determined at startup. The input data type and output data type can
be different data types. If an incoming message is a request and has a specified reply-to queue, the
message in OUTMSG is sent to the specified queue. The incoming message can be one of the following
message types:
• Datagram
• Datagram with report requested
• Request message with reply
• Request message with reply and report requested
Stored procedure interface with three parameters
This stored procedure interface for MQListener has parameters with the following information:
• An incoming message as input
• A reply, which might be NULL, as output
• A message header, which can be input or output
For example:
CREATE schema.proc(
IN INMSG inMsgType,
OUT OUTMSG outMsgType,
INOUT MSGHEADER msgHeaderType)...
The data type for INMSG and the data type for OUTMSG can be VARCHAR, VARBINARY, CLOB, or
BLOB, of any length, and are determined at startup. The input data type and output data type can
be different data types. If an incoming message is a request and has a specified reply-to queue, the
message in OUTMSG is sent to the specified queue. The incoming message can be one of the following
message types:
• Datagram
• Datagram with report requested
• Request message with reply
• Request message with reply and report requested
The data type for MSGHEADER can be VARBINARY or BLOB. The minimum length of MSGHEADER
is 324, which is the size of the message queuing message descriptor (MQMD) structure for IBM MQ
messages.
MQListener passes the message header to the stored procedure in the MSGHEADER parameter. The
stored procedure can get the message descriptor properties from the MSGHEADER parameter. If the
message is a request message, the stored procedure can specify the properties for the reply queue
and reply queue manager in the MSGHEADER parameter. The output message in OUTMSG is sent to
that specified queue.
798 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Configuring MQListener in Db2 for z/OS
Before you can use MQListener, you must configure your database environment so that your applications
can use messaging with database operations. You must also configure IBM MQ for MQListener.
Procedure
To configure the environment for MQListener and to develop a simple application that receives a message,
inserts the message in a table, and creates a simple response message, use these steps:
1. Configure MQListener to run in the Db2 environment, so that your applications can use messaging with
database operations, by completing the following steps:
a) In z/OS UNIX System Services, the default path for MQListener in is /usr/lpp/db2c10/mql. The
mqlsn.tar.Z tar file forMQListener is located in this path. If MQListener is not installed in the
default path, replace all occurrences of the default path in the samples DSNTEJML, DSNTEJSP and
DSNTIJML with the path name where MQListener is installed before you run DSNTIJML.
b) Customize and run installation job DSNTIJML. It completes the following actions:
i) Extracts the necessary files and libraries to z/OS UNIX System Services under the path where
MQListener is installed.
ii) Creates the MQListener configuration table (SYSMQL.LISTENERS) in the default database
DSNDB04.
iii) Binds the DBRMs to the plan DB2MQLSN.
c) Follow the instructions in the README file in the MQListener installation path to complete the
configuration process.
Applying PTFs:
When applying PTFs for MQListener, run job DSNTJESP to extract the tar file for the MQListener library
files in z/OS UNIX System Services.
2. Configure IBM MQ for MQListener.
You can run a simple MQListener application with a simple IBM MQ configuration. More complex
applications might need a more complex configuration. Configure at least two kinds of IBM MQ
entities: the queue manager and some local queues. Configure these entities for use in such instances
as transaction management, deadletter queue, backout queue, and backout retry threshold.
a) Create IBM MQ QueueManager. Define the IBM MQ subsystem to z/OS and then issue the following
command from a z/OS console to start the queue manager, where command-prefix is the command
prefix for the IBM MQ subsystem.
//*
//* ADMIN_Q : Admin queue
//* BACKOUT_Q : Backout queue
//* IN_Q : Input queue having a backout queue with threshold=3
//* REPLY_Q : output queue or reply queue
//* DEADLLETTER_Q: Dead letter queue
//*
//DSNTECU EXEC PGM=CSQUTIL,PARM='MQND'
//STEPLIB DD DSN=MQS.SCSQANLE,DISP=SHR
// DD DSN=MQS.SCSQAUTH,DISP=SHR
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
COMMAND DDNAME(CREATEQ)
/*
//CREATEQ DD *
DEFINE QLOCAL('ADMIN_Q') REPLACE +
DESCR('INPUT-OUTPUT') +
PUT(ENABLED) +
DEFPRTY(0) +
DEFPSIST(NO) +
SHARE +
DEFSOPT(SHARED) +
GET(ENABLED)
DEFINE QLOCAL('BACKOUT_Q') REPLACE +
DESCR('INPUT-OUTPUT') +
PUT(ENABLED) +
DEFPRTY(0) +
DEFPSIST(NO) +
SHARE +
DEFSOPT(SHARED) +
GET(ENABLED)
DEFINE QLOCAL('REPLY_Q') REPLACE +
DESCR('INPUT-OUTPUT') +
PUT(ENABLED) +
DEFPRTY(0) +
DEFPSIST(NO) +
SHARE +
DEFSOPT(SHARED) +
GET(ENABLED)
DEFINE QLOCAL('IN_Q') REPLACE +
DESCR('INPUT-OUTPUT') +
PUT(ENABLED) +
DEFPRTY(0) +
DEFPSIST(NO) +
SHARE +
DEFSOPT(SHARED) +
GET(ENABLED) +
BOQNAME('BACKOUT_Q') +
BOTHRESH(3)
800 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
DEFINE QLOCAL('DEADLETTER_Q') REPLACE +
DESCR('INPUT-OUTPUT') +
PUT(ENABLED) +
DEFPRTY(0) +
DEFPSIST(NO) +
SHARE +
DEFSOPT(SHARED) +
GET(ENABLED)
ALTER QMGR DEADQ ('DEADLETTER_Q') REPLACE
/*
3. Configure MQListener tasks. For more information, see “Configuring MQListener tasks” on page 802.
4. Create a stored procedure that MQListener uses to store messages in a table. See “Creating a sample
stored procedure to use with MQListener” on page 805 for details.
5. Run a simple MQListener application.
export MQLSNLWR=file-size,file-name
802 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
-adminQMgr
The name of the IBM MQ subsystem that contains the queues that are to be used for
administrative tasks. If -adminQMgr is not specified, the configured default queue manager is
used.
-config
A name that identifies a group of tasks that run together. If -config is not specified, the default
configuration is run.
-queueManager
The name of the IBM MQ subsystem that contains the queues that are to be used. If
-queueManager is not specified, is not specified, the default queue manager is used.
-inputQueue
The name of the queue in the IBM MQ subsystem that is to be monitored for incoming messages.
The combination of the -inputQueue value and the -queueManager value must be unique within a
configuration.
-numInstances
The number of duplicate instances of a single task that are to run in a configuration.
-numMessagesCommit
The number of messages that are received before MQListener issues a COMMIT. The default is 1. This
option is supported only for db2mqln2.
-procName
The name of the stored procedure that MQListener calls when it detects that a message is received.
-procSchema
The schema name of the stored procedure that MQListener calls when it detects that a message is
received.
-ssID
The subsystem where the MQListener daemon runs. Configuration information is stored in this
subsystem.
-timeRestart
If a stored procedure that is specified by -procSchema and -procName fails at MQListener startup
time, the number of seconds that threads that are running with that stored procedure suspend before
repeating the setup process. MQListener continues startup for threads that do not use that stored
procedure. This value must be an integer between 0 and 7200. 0 is the default.
-restartDB2
Whether MQListener automatically reconnects and resumes processing after Db2 is stopped and
restarted.
'Y'
MQListener automatically reconnects and resumes processing after Db2 is stopped and restarted.
'N'
MQListener does not automatically reconnect after Db2 is stopped and restarted. 'N' is the default
value.
The syntax of the commands follows. In the command syntax, mqlistener-command is db2mqln1 or
db2mqln2.
• To add an MQListener configuration, issue the mqlistener-command add command:
mqlistener-command add
-ssID subsystem-name
-config configuration-name
-queueManager queuemanager-name
-inputQueue inputqueue-name
-procName stored-procedure-name
-procSchema stored-procedure-schema name
-numInstances number-of-instances
mqlistener-command show
-ssID subsystem-name
-config configuration-name
To display information about all the configurations, issue the mqlistener-command show command:
mqlistener-command show
-ssID subsystem-name
-config all
mqlistener-command remove
-ssID subsystem-name
-config configuration-name
-queueManager queuemanager-name
-inputQueue inputqueue-name
mqlistener-command run
-ssID subsystem-name
-config configuration-name
-adminQueue adminqueue-name
-adminQMgr adminqueuemanager-name
-numMessagesCommit number-of-messages-before-commit
-timeRestart number-of-seconds-to-suspend-before-restart
-restartDB2 y-or-n
mqlistener-command admin
-adminQueue adminqueue-name
-adminQMgr adminqueuemanager-name
-adminCommand shutdown
• To get help with the command and the valid parameters, issue the mqlistener-command help
command:
mqlistener-command help
• To get help for a particular parameter, issue the mqlistener-command help command, where command
is a specific parameter:
Restriction:
• Use the same queue manager for the request queue and the reply queue.
• MQListener does not support logical messages that are composed of multiple physical messages.
MQListener processes physical messages independently.
804 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Creating a sample stored procedure to use with MQListener
You can create a sample stored procedure, APROC, that can be used by MQListener to store a message in
a table. The stored procedure returns the string OK if the message is successfully inserted into the table.
Procedure
The following steps create Db2 objects that you can use with MQListener applications:
1. Create a table using SPUFI, DSNTEP2, or the command line processor in the subsystem where you
want to run MQListener:
CREATE TABLE PROCTABLE (MSG VARCHAR(25) CHECK (MSG NOT LIKE 'FAIL%'));
The table contains a check constraint so that messages that start with the characters FAIL cannot be
inserted into the table. The check constraint is used to demonstrate the behavior of MQListener when
the stored procedure fails.
2. Create the following SQL procedure, and define it to the same Db2 subsystem.
3. Add the following configuration, named ACFG, to the configuration table by issuing this command:
db2mqln2 add
-ssID DB2A
-config ACFG
-queueManager CSQ1
-inputQueue DB2MQ_DEFAULT_Q
-procName APROC
-procSchema TEST
4. Run the MQListener daemon for two-phase commit for configuration ACFG. To run MQListener with all
of the tasks that are specified in the configuration, issue the following command:
5. Send a request to the input queue, 'DB2MQ_DEFAULT_Q ', with the message 'another sample message'.
6. Query table PROCTABLE to verify that the sample message was inserted:
7. Display the number of messages that remain on the input queue, to verify that the message has been
removed. To do that issue the following command from a z/OS console:
8. Look at the ReplytoQ name that you specified, to verify that the string 'OK' is generated by the stored
procedure.
• The stored procedure was called unsuccessfully the number of times that is specified
as the backout threshold.
• The name of the backout queue is the same as the deadletter queue.
This reason code applies only to two-phase commit environments.
MQRC_TRUNCATED_ The size of the MQ message is greater than the input parameter of the stored procedure
MSG__FAILED that is to be invoked. In one-phase commit environments, this oversized message
is sent to the dead letter queue. In two-phase commit environments, this oversized
message is sent to the deadletter queue only when the message cannot be delivered to
the backout queue.
806 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Note:
1. To specify that the receiver application generate exception reports if errors occur, set the report field in
the MQMD structure that was used when sending the message to one of the following values:
• MQRO_EXCEPTION
• MQRO_EXCEPTION_WITH_DATA
• MQRO_EXCEPTION_WITH_FULL_DATA
Related reference
IBM MQ home
MQListener examples
The application receives a message, inserts the message into a table, and generates a simple response
message.
To simulate a processing failure, the application includes a check constraint on the table that contains the
message. The constraint prevents any string that begins with the characters 'fail' from being inserted into
the table. If you attempt to insert a message that violates the check constraint, the example application
returns an error message and re-queues the failing message to the backout queue.
In this example, the following assumptions are made:
• MQListener is installed and configured for subsystem DB7A.
• MQND is the name of IBM MQ subsystem that is defined. The Queue Manager is running, and the
following local queues are defined in the DB7A subsystem:
ADMIN_Q : Admin queue
BACKOUT_Q : Backout queue
IN_Q : Input queue that has a backout queue withthreshold = 3
REPLY_Q : Output queue or Reply queue
DEADLLETTER_Q : Dead letter queue
• The person who is running the MQListener daemon has execute permission on the DB2MQLSN plan.
Before you run the MQListener daemon, add the following configuration, named ACFG, to the
configuration table by issuing the following command:
db2mqln2 add
-ssID DB7A
-config ACFG
-queueManager MQND
-inputQueue IN_Q
-procName APROC
-procSchema TEST
Run the MQListener daemon for two-phase commit for configuration ACFG by issuing the following
command:
db2mqln2 run
-ssID DB7A
-config ACFG
-adminQueue ADMIN_Q
-adminQMgr MQND
-numMessagesCommit 1
-timeRestart 60
The following examples show how to use MQListener to send a simple message and then inspect the
results of the message in the IBM MQ queue manager and the database. The examples include queries to
determine if the input queue contains a message or to determine if a record is placed in the table by the
stored procedure.
MQListener example 1: Running a simple application:
1. Start with a clean database table by issuing the following SQL statement:
2. Send a datagram to the input queue, 'IN_Q', with the message as 'sample message'. Refer to
WebSphere MQ sample CSQ4BCK1 to send a message to the queue. Specify the MsgType option
for 'Message Descriptor' as 'MQMT_DATAGRAM'.
3. Query the table by using the following statement to verify that the sample message is inserted:
4. Display the number of messages that remain on the input queue to verify that the message has been
removed. Issue the following command from a z/OS console:
MQListener example 2: Sending requests to the input queue and inspecting the reply:
1. Start with a clean database table by issuing the following SQL statement:
2. Send a request to the input queue, 'IN_Q', with the message as 'another sample message'. Refer to
IBM MQ sample CSQ4BCK1 to send a message to the queue. Specify the MsgType option for 'Message
Descriptor' as 'MQMT_REQUEST' and the queue name for ReplytoQ option.
3. Query the table by using the following statement to verify that the sample message is inserted:
4. Display the number of messages that remain on the input queue to verify that the message has been
removed. Issue the following command from a z/OS console:
5. Look at the ReplytoQ name that you specified when you sent the request message for the reply by
using the IBM MQ sample program CSQ4BCJ1. Verify that the string 'OK' is generated by the stored
procedure.
MQListener example 3: Testing an unsuccessful insert operation: If you send a message that starts
with the string 'fail', the constraint in the table definition is violated, and the stored procedure fails.
1. Start with a clean database table by issuing the following SQL statement:
2. Send a request to the input queue, 'IN_Q', with the message as 'failing sample message'. Refer to IBM
MQ sample CSQ4BCK1 to send a message to the queue. Specify the MsgType option for 'Message
Descriptor' as 'MQMT_REQUEST' and the queue name for ReplytoQ option.
3. Query the table by using the following statement to verify that the sample message is not inserted:
4. Display the number of messages that remain on the input queue to verify that the message has been
removed. Issue the following command from a z/OS console:
5. Look at the Backout queue and find the original message by using the WebSphere MQ sample program
CSQ4BCJ1.
Note: In this example, if a request message with added options for 'exception report' is sent (the Report
option is specified for 'Message Descriptor'), an exception report is sent to the reply queue and the
original message is sent to the deadletter queue.
808 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Chapter 7. Db2 as a web services consumer and
provider
Web services are a set of resources and components that applications can use over HTTP. You can use
Db2 as a web services provider and a web services consumer.
Example: The following example is the result of the preceding example. This example shows the HTTP
response header with the SOAP response envelope. The result shows that the temperature is 85 degrees
Fahrenheit in Barcelona.
HTTP/1.1 200 OK
Date: Wed, 31 Jul 2002 22:06:41 GMT
Server: Enhydra-MultiServer/3.5.2
Status: 200
Content-Type: text/xml; charset=utf-8
Servlet-Engine: Lutris Enhydra Application Server/3.5.2
(JSP 1.1; Servlet 2.2; Java 1.3.1_04;
Linux 2.4.7-10smp i386; java.vendor=Sun Microsystems Inc.)
Content-Length: 467
Set-Cookie:JSESSIONID=JLEcR34rBc2GTIkn-0F51ZDk;Path=/soap
X-Cache: MISS from www.xmethods.net
Keep-Alive: timeout=15, max=10
Connection: Keep-Alive
Example: The following example shows how to insert the result from a web service into a table
810 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
The SOAPHTTPNV and SOAPHTTPNC user-defined functions
Db2 provides SOAPHTTPNV and SOAPHTTPNC user-defined functions that allow you to work with
SOAP and consume web services in SQL statements. The user-defined functions are two varieties of
SOAPHTTPNV for VARCHAR data and two varieties of SOAPHTTPNC for CLOB data.
The user-defined functions perform the following actions:
1. Post the input SOAP request to the service endpoint
2. Receive and return the SOAP response
SOAPHTTPNV and SOAPHTTPNC allow you to specify a complete SOAP message as input and return
complete SOAP messages from the specified web service as a CLOB or VARCHAR representation of the
returned XML data. . SOAPHTTPNV returns VARCHAR(32672) data and SOAPHTTPNC returns CLOB(1M)
data. Both functions accept either VARCHAR(32672) or CLOB(1M) as the input body.
SOAPHTTPNV and SOAPHTTPNC user-defined functions can support SOAP 1.1 or SOAP 1.2. Check with
your system administrator to determine which levels of SOAP are supported by the user-defined functions
in your environment.
Example
The following example shows how to insert the complete result from a web service into a table using
SOAPHTTPNC.
Related tasks
Additional steps for enabling web service user-defined functions (Db2 Installation and Migration)
Table 131. SQLSTATE values for SOAPHTTPV and SOAPHTTPC user-defined functions
SQLSTATE Description
38301 An unexpected NULL value was pass as input to the function.
38302 The function was unable to allocate space.
38304 An unknown protocol was specified ion the endpoint URL.
38305 An invalid URL was specified on the endpoint URL.
38306 An error occurred while attempting to create a TCP/IP socket.
38307 An error occurred while attempting to bind a TCP/IP socket.
Table 132. SQLSTATE values for SOAPHTTPNV and SOAPHTTPNC user-defined functions
SQLSTATE Description
38350 An unexpected NULL value was specified for the endpoint, action, or SOAP input.
38351 A dynamic memory allocation error.
38352 An unknown or unsupported transport protocol.
38353 An invalid URL was specified.
38354 An error occurred while resolving the hostname.
38355 A memory exception for socket.
38356 An error occurred during socket connect.
38357 An error occurred while setting socket options.
38358 An error occurred during input/output control (ioctl) to verify HTTPS enablement.
38359 An error occurred while reading from the socket.
812 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 132. SQLSTATE values for SOAPHTTPNV and SOAPHTTPNC user-defined functions (continued)
SQLSTATE Description
38360 An error occurred due to socket timeout.
38361 No response from the specified host.
38362 An error occurred due to an unexpected HTTP return or content type
38363 The TCP/IP stack was not enabled for HTTPS.
Related tasks
Additional steps for enabling web service user-defined functions (Db2 Installation and Migration)
The APPLCOMPAT bind option value for the CREATE PROCEDURE statement is then set to V11R1 or higher
and result of the statement is then successful.
Related concepts
Function levels and related levels in Db2 12 (Db2 for z/OS What's New?)
Related tasks
Controlling Db2 application compatibility (Db2 for z/OS What's New?)
Related reference
APPLCOMPAT bind option (Db2 Commands)
CURRENT APPLICATION COMPATIBILITY (Db2 SQL)
APPL COMPAT LEVEL field (APPLCOMPAT subsystem parameter) (Db2 Installation and Migration)
SYSPACKAGE catalog table (Db2 SQL)
SET CURRENT APPLICATION COMPATIBILITY (Db2 SQL)
-ACTIVATE (Db2) (Db2 Commands)
816 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
V12R1Mnnn application compatibility levels
In Db2 12, you can use the application compatibility level to control the adoption of new SQL capabilities
and enhancements of particular function levels.
You can use the application compatibility level of applications, and objects such as routines or triggers, to
control the adoption and use of new and changed SQL capabilities that are introduced in function levels.
Generally, applications, and routines or triggers, cannot use new or changed SQL capabilities unless the
effective application compatibility level is equivalent to or higher than the function level that introduced
the changes. The application compatibility level applies to most SQL statements, including data definition
statements (such as CREATE and ALTER statements) and data control statements (such as GRANT and
REVOKE statements).
The corresponding function level or higher must be activated when you bind packages at an application
compatibility level. However, if you activate a lower function level (or * function level), applications can
continue to run with the higher application compatibility level. To prevent the continued use of SQL
capabilities introduced in the higher function level, you must also modify the application and change the
effective application compatibility level to the lower level.
For IBM data server clients or drivers that need to exploit Db2 for z/OS capabilities that are delivered with
function level V12R1M501 or greater, you need to take additional steps. See “V12R1Mnnn application
compatibility levels for data server clients and drivers” on page 817 for details.
Tip: Do not raise the default application compatibility level of the Db2 subsystem immediately after
migrating or activating a new function level. Instead, wait until applications have been verified to work
correctly at the higher function level, and any incompatibilities have been resolved. For details, see
“Enabling default application compatibility with function level 500 or higher” on page 830.
Application compatibility levels are specified in commands and message output by nine-character strings
that correspond to the Db2 version, release, and modification value of the corresponding function level.
See the activation details for each function level for a summary the new features that are controlled by
the corresponding application compatibility level.
For example, V12R1M510 specifies compatibility with the highest available Db2 12 function level. The
equivalent function level or higher must be activated. For a list of supported Db2 12 function levels, see
Db2 12 function levels (Db2 for z/OS What's New?).
Related reference
APPLCOMPAT bind option (Db2 Commands)
APPL COMPAT LEVEL field (APPLCOMPAT subsystem parameter) (Db2 Installation and Migration)
CURRENT APPLICATION COMPATIBILITY (Db2 SQL)
Procedure
1. Set the Db2 for z/OS server application compatibility (APPLCOMPAT) level.
a) For client applications that contain static SQL statements, rebind the static application packages
with the new APPLCOMPAT value, on the client and on the server.
b) For client applications that contain only dynamic SQL statements, bind or rebind the client or driver
packages with the new APPLCOMPAT value, on the server.
Tip: Binding package copies and keeping the original driver packages lets you access new
capabilities for applications that need them, while ensuring stability for applications that should
not be exposed to incompatibilities.
For drivers only, you can use jobs that are provided with Db2 for z/OS, in data set prefix.SDSNSAMP,
to bind or rebind the driver packages on the server. To run those jobs, follow these steps:
i) Customize jobs DSNTIJLC and DSNTIJLR, using the instructions in the job prologs.
ii) If there is a possibility that you still need to run applications under a driver that is at the old
application compatibility level, run DSNTIJLC to bind copies of the driver packages at the new
application compatibility level, while leaving the packages in the NULLID collection at the old
application compatibility level. In most cases, you should do this.
If you are sure that you do not need to run applications under a driver at the old application
compatibility level, run job DSNTIJLR to rebind the client or driver packages at the new
application compatibility level.
iii) If you bound copies of the driver packages for the new function level, switch the drivers to the
new function level by modifying the property that controls the current package set to match the
collection ID of the new package copies.
• For CLI or ODBC drivers, change the CLI/ODBC CurrentPackageSet configuration keyword
value.
818 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
• For the IBM Data Server Driver for JDBC and SQLJ, change the
DB2BaseDataSource.currentPackageSet Connection or DataSource property value.
2. Set the client application compatibility value to control the capabilities of client applications when a
client or driver contains changes that enable new server capabilities. If you set the client application
compatibility level, its value must be less than or equal to the server application compatibility level.
Take one of the following actions to set the client application compatibility value.
• For CLI or ODBC drivers or IBM Data Server clients, change the CLI/ODBC ClientApplCompat
configuration keyword value.
Do this by adding a line similar to this example to the <databases> section or the <dsn> section in
the db2dsdriver.cfg file.
DSNTIJLC
Migrate Db2 Connect packages to support a new function level.
//******************************************************************
//* JOB NAME = DSNTIJLC
//*
//* DESCRIPTIVE NAME = INSTALLATION JOB STREAM
//*
//* Licensed Materials - Property of IBM
//* 5650-DB2
//* (C) COPYRIGHT 2016 IBM Corp.All Rights Reserved.
//*
//* STATUS = Version 12
//*
//* FUNCTION = Migrate DB2 Connect packages to support a new
//* function level.
//*
//* PSEUDOCODE =
//* DSNTIRU STEP Bind Copy the IBM JDBC and CLI standard
//* set of packages to a new collection in
//* order to override the APPLCOMPAT package
//* option.
//*
//* NOTES =
//* (1) This job includes an in-stream data set having
//* DB2 bind statements that contain substitution
//* symbols. For example:
//* BIND PACKAGE (&TGTCOLID) +
//* COPY(&SRCCOLID..SYSLH100) +
//* APPLCOMPAT(&APPLCMPT)
//* where
//* &TGTCOLID is the name of the collection-ID to
820 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
COPY(&SRCCOLID..SYSLH400) +
APPLCOMPAT(&APPLCMPT)
BIND PACKAGE (&TGTCOLID) +
COPY(&SRCCOLID..SYSLH401) +
APPLCOMPAT(&APPLCMPT)
BIND PACKAGE (&TGTCOLID) +
COPY(&SRCCOLID..SYSLH402) +
APPLCOMPAT(&APPLCMPT)
BIND PACKAGE (&TGTCOLID) +
COPY(&SRCCOLID..SYSLN100) +
APPLCOMPAT(&APPLCMPT)
BIND PACKAGE (&TGTCOLID) +
COPY(&SRCCOLID..SYSLN101) +
APPLCOMPAT(&APPLCMPT)
BIND PACKAGE (&TGTCOLID) +
COPY(&SRCCOLID..SYSLN102) +
APPLCOMPAT(&APPLCMPT)
BIND PACKAGE (&TGTCOLID) +
COPY(&SRCCOLID..SYSLN200) +
APPLCOMPAT(&APPLCMPT)
BIND PACKAGE (&TGTCOLID) +
COPY(&SRCCOLID..SYSLN201) +
APPLCOMPAT(&APPLCMPT)
BIND PACKAGE (&TGTCOLID) +
COPY(&SRCCOLID..SYSLN202) +
APPLCOMPAT(&APPLCMPT)
BIND PACKAGE (&TGTCOLID) +
COPY(&SRCCOLID..SYSLN300) +
APPLCOMPAT(&APPLCMPT)
BIND PACKAGE (&TGTCOLID) +
COPY(&SRCCOLID..SYSLN301) +
APPLCOMPAT(&APPLCMPT)
BIND PACKAGE (&TGTCOLID) +
COPY(&SRCCOLID..SYSLN302) +
APPLCOMPAT(&APPLCMPT)
BIND PACKAGE (&TGTCOLID) +
COPY(&SRCCOLID..SYSLN400) +
APPLCOMPAT(&APPLCMPT)
BIND PACKAGE (&TGTCOLID) +
COPY(&SRCCOLID..SYSLN401) +
APPLCOMPAT(&APPLCMPT)
BIND PACKAGE (&TGTCOLID) +
COPY(&SRCCOLID..SYSLN402) +
APPLCOMPAT(&APPLCMPT)
BIND PACKAGE (&TGTCOLID) +
COPY(&SRCCOLID..SYSSH100) +
APPLCOMPAT(&APPLCMPT)
BIND PACKAGE (&TGTCOLID) +
COPY(&SRCCOLID..SYSSH101) +
APPLCOMPAT(&APPLCMPT)
BIND PACKAGE (&TGTCOLID) +
COPY(&SRCCOLID..SYSSH102) +
APPLCOMPAT(&APPLCMPT)
BIND PACKAGE (&TGTCOLID) +
COPY(&SRCCOLID..SYSSH200) +
APPLCOMPAT(&APPLCMPT)
BIND PACKAGE (&TGTCOLID) +
COPY(&SRCCOLID..SYSSH201) +
APPLCOMPAT(&APPLCMPT)
BIND PACKAGE (&TGTCOLID) +
COPY(&SRCCOLID..SYSSH202) +
APPLCOMPAT(&APPLCMPT)
BIND PACKAGE (&TGTCOLID) +
COPY(&SRCCOLID..SYSSH300) +
APPLCOMPAT(&APPLCMPT)
BIND PACKAGE (&TGTCOLID) +
COPY(&SRCCOLID..SYSSH301) +
APPLCOMPAT(&APPLCMPT)
BIND PACKAGE (&TGTCOLID) +
COPY(&SRCCOLID..SYSSH302) +
APPLCOMPAT(&APPLCMPT)
BIND PACKAGE (&TGTCOLID) +
COPY(&SRCCOLID..SYSSH400) +
APPLCOMPAT(&APPLCMPT)
BIND PACKAGE (&TGTCOLID) +
COPY(&SRCCOLID..SYSSH401) +
APPLCOMPAT(&APPLCMPT)
BIND PACKAGE (&TGTCOLID) +
COPY(&SRCCOLID..SYSSH402) +
APPLCOMPAT(&APPLCMPT)
BIND PACKAGE (&TGTCOLID) +
COPY(&SRCCOLID..SYSSN100) +
DSNTIJLR
Migrate Db2 Connect packages to support a new function level.
//******************************************************************
//* JOB NAME = DSNTIJLR
//*
//* DESCRIPTIVE NAME = INSTALLATION JOB STREAM
//*
//* Licensed Materials - Property of IBM
//* 5650-DB2
//* (C) COPYRIGHT 2016 IBM Corp.All Rights Reserved.
//*
//* STATUS = Version 12
//*
//* FUNCTION = Migrate DB2 Connect packages to support a new
//* function level.
//*
//* PSEUDOCODE =
//* DSNTIRU STEP Rebind the IBM JDBC and CLI standard
//* set of packages to a new collection in
//* order to override the APPLCOMPAT package
//* option.
//*
//* NOTES =
//* (1) This job includes an in-stream data set having
//* DB2 bind statements that contain substitution
//* symbols. For example:
//* REBIND PACKAGE (&SRCCOLID..SYSLH100) +
//* APPLCOMPAT(&APPLCMPT)
//* where
//* &SRCCOLID is the name of the collection-ID
//* owning the package to be rebound.
//* The DB2-supplied setting is
//* 'NULLID_V12R1M500'. Use the SET
//* SRCCOLID statement in job step
//* DSNTIRU to specify a different
//* setting.
//* &APPLCMPT is the DB2 application compatibility
822 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
//* level. The DB2-supplied setting is
//* 'V12R1M500'. Use the SET APPLCMPT
//* statement in job step DSNTIRU to
//* specify a different setting.
//*
//* Attention JES3 users: Symbolic substitution within
//* in-stream data sets in JES3 requires z/OS 2.2 or
//* above. In order to run this job on JES2 using z/OS
//* 2.1, you need to make the following manual changes:
//* (a) Remove the EXPORT SYMLIST and all SET statements
//* (b) Change all occurrences of &SRCCOLID to the name
//* of the collection-ID owning the package to be
//* rebound
//* (c) Change all occurrences of &APPLCMPT to the DB2
//* application compatibility setting.
//*
//* (2) Before running this job, customize it as follows:
//* (a) Add a valid job card.
//* (b) Locate and change all occurrences of the
//* following strings as indicated:
//* - '!DSN!' to the name of the DB2 subsystem.
//* - 'DSN!!0' to the prefix of the DB2 target
//* libraries for the DB2 subsystem.
//* (c) Set SRCCOLID and APPLCMPT as described above.
//*
//* CHANGE LOG =
//* 11/08/2016 Job created S28617 PI74456
//*
//JOBLIB DD DISP=SHR,
// DSN=DSN!!0.SDSNLOAD
//*
//* Symbolic substitution requires z/OS 2.2, or z/OS 2.1 with JES2.
// EXPORT SYMLIST=(SRCCOLID,APPLCMPT)
// SET SRCCOLID='NULLID_V12R1M500'
// SET APPLCMPT='V12R1M500'
//DSNTIRU EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSTSIN DD *,SYMBOLS=JCLONLY
DSN SYSTEM(DB2A)
REBIND PACKAGE (&SRCCOLID..SYSLH100) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSLH101) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSLH102) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSLH200) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSLH201) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSLH202) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSLH300) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSLH301) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSLH302) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSLH400) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSLH401) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSLH402) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSLN100) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSLN101) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSLN102) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSLN200) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSLN201) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSLN202) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSLN300) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSLN301) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSLN302) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSLN400) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSLN401) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSLN402) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSSH100) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSSH101) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSSH102) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSSH200) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSSH201) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSSH202) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSSH300) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSSH301) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSSH302) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSSH400) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSSH401) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSSH402) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSSN100) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSSN101) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSSN102) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSSN200) APPLCOMPAT(&APPLCMPT)
REBIND PACKAGE (&SRCCOLID..SYSSN201) APPLCOMPAT(&APPLCMPT)
Using profile tables to control which Db2 for z/OS application compatibility
levels to use for specific data server client applications
Profiles can be used to control which client applications use features that are associated with a specific
Db2 for z/OS application compatibility level. This capability allows client applications that do not need to
use new features to continue to connect to a Db2 for z/OS server at an earlier application compatibility
level.
Procedure
1. On the client operating system, bind the client driver packages into two collections:
• One collection with the default collection name NULLID, and with the APPLCOMPAT option set to
V12R1M500. If you have already bound the client driver packages into collection NULLID with
APPLCOMPAT set to V12R1M500, you do not need to bind them again.
• Another collection with a different name, such as NULLID_NF, and with the APPLCOMPAT option set
to V12R1M501.
• For the IBM Data Server Driver for JDBC and SQLJ, follow these steps to bind the driver packages:
– If you have not already done so, invoke the DB2Binder utility with a control statement like this
one to create a collection with the default name NULLID, and with application compatibility set to
V12R1M500:
– Invoke the DB2Binder utility with a control statement like this one to create a collection named
NULLID_NF, with application compatibility set to V12R1M501:
• For the IBM Data Server Driver for ODBC and CLI, follow these steps to bind the driver packages:
– If CLI/ODBC configuration keyword OnlyUseBigPackages=1, you do not need to bind the driver
packages.
– If CLI/ODBC configuration keyword OnlyUseBigPackages=0, you need to bind small packages
with application compatibility set to V12R1M501:
824 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
2. In Db2 for z/OS, create a profile for client application ACCTG_APP501 by inserting rows into tables
SYSIBM.DSN_PROFILE_TABLE and SYSIBM.DSN_PROFILE_ATTRIBUTES. The profile directs Db2 to
use the driver with packages in collection NULLID_NF when application ACCTG_APP501 runs. Because
the driver packages in the NULLID_NF collection are bound with option APPLCOMPAT V12R1M501,
ACCTG_APP501 can use capabilities that are available at application compatibility level V12R1M501.
Important: Although PKGNAME can be used as a filtering category for profile table rows that use
the 'SPECIAL_REGISTER' value for KEYWORDS, when client drivers are used, you should not use
PKGNAME alone or in combination with COLLID.
3. On Db2 for z/OS, issue the -START PROFILE command to load the updated profile tables into memory.
Results
Application ACCTG_APP501 can now successfully connect to Db2 for z/OS and use data server driver
packages in collection NULLID_NF. All other applications can connect to Db2 for z/OS and use data server
driver packages in collection NULLID.
You can verify the application compatibility level and collection that are being used for your client
application by adding code to execute a query like this to your application.
For example, you might add code like this to a Java application:
For application ACCTG_APP501, the query should return a value of V12R1M501 for the current
application compatibility, and NULLID_NF for the collection name.
Related concepts
Binding database utilities on Db2 Connect
Related tasks
V12R1Mnnn application compatibility levels for data server clients and drivers
IBM data server clients and drivers that use Db2 for z/OS capabilities with a function level requirement of
greater than V12R1M500 require extra program preparation steps.
Setting special registers by using profile tables (Db2 Administration Guide)
Related reference
DB2Binder utility (Db2 Application Programming for Java)
OnlyUseBigPackages CLI/ODBC and IBM data server driver configuration keyword
You can run package level accounting or monitor traces with IFCID 0239 and review field
QPACINCOMPAT, which indicates an SQL incompatible change. If a trace is started for IFCID 0376, and
application compatibility is set for a previous version, details about features and functions that have a
change in behavior are written in field QW0376FN.
A migrated Db2 12 environment behaves with V11R1 application compatibility until function level 500 or
higher is activated.
The following table shows many of the features and functions that are controlled by application
compatibility, and the results if you specify V11R1. If a behavior difference is traced, then the IFCID
trace function code is shown.
Related concepts
Application and SQL release incompatibilities (Db2 for z/OS What's New?)
You can run package level accounting or monitor traces with IFCID 0239 and review field
QPACINCOMPAT, which indicates an SQL incompatible change. If a trace is started for IFCID 0376, and
application compatibility is set for a previous version, details about features and functions that have a
change in behavior are written in field QW0376FN.
826 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
A migrated Db2 12 environment behaves with V11R1 application compatibility until function level 500 or
higher is activated. Application and SQL incompatibilities are described in the migration information for
each version.
The following table shows many of the features and functions that are controlled by application
compatibility, and the results if you specify V10R1. If a behavior difference is traced, then the IFCID
trace function code is shown.
828 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 134. Behavior of V10R1 application compatibility (continued)
Result with V10R1 application IFCID 0376 trace
Feature or Function compatibility function code
An SQL statement contains the GROUP BY SQLCODE -20478
clause and references a column that is defined
with a column mask
An SQL statement contains the set operator SQLCODE -20478
UNION ALL or UNION DISTINCT and references
a column that is defined with a column mask
A reference to an alias for a sequence object SQLCODE -4743
A reference to an unqualified sequence that is SQLCODE -204
not resolved to a public alias
A SELECT with a table function reference that SQLCODE -4743
includes a typed correlation clause
A CALL statement that specifies an autonomous SQLCODE -4743
procedure
The following datetime assignments: SQLCODE -180
• A valid string representation of a timestamp
to a date column
• A valid string representation of a timestamp
to a time column
• A valid string representation of a date to a
timestamp column
Notes:
1. To find details about the incompatible parameters, examine the contents of fields QW0376SC_Var,
QW0376PR_Var, and QW0376INC_Var. See the DSNWMSGS file for more information.
Related concepts
Application and SQL release incompatibilities (Db2 for z/OS What's New?)
V11R1 application compatibility level
When you set the application compatibility level to V11R1, applications that attempt to use functions and
features that are introduced in Db2 12 or later might behave differently or receive an error.
Procedure
1. Start a trace that includes IFCID 0239 to capture package information.
For example, issue the following START TRACE command: GUPI
GUPI
GUPI
What to do next
When the application runs at the old level with no application incompatibilities, rebind the package with
the APPLCOMPAT value for the new function level.
Related concepts
Performance trace (Db2 Performance)
Related reference
-START TRACE (Db2) (Db2 Commands)
Trace field descriptions (Db2 Performance)
Procedure
To enable default application compatibility with the current function level:
830 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
1. Change the APPLCOMPAT subsystem parameter setting. Set the value to V12R1M500 or the equivalent
higher active function-level value.
You can complete this step as described in Updating subsystem parameter and application default
values (Db2 Installation and Migration), or by modifying your customized copy of the DSNTIJUZ job.
The format is VvvRrMmmm, where vv is the version, r is the release, and mmm is the modification
level. For example, V12R1M510 identifies function level 510. For a list of all available function levels
in Db2 12, see Db2 12 function levels (Db2 for z/OS What's New?). See the activation details for each
function level for a summary the new features that are controlled by the corresponding application
compatibility level.
2. Run the first two job steps of DSNTIJUZ to rebuild your subsystem parameter (DSNZPxxx) module.
3. Use the -SET SYSPARM command or restart Db2.
Results
Future bind and rebind operations set the application compatibility level of the package to the
APPLCOMPAT subsystem parameter value, if the APPLCOMPAT bind option is not specified. Packages
that are bound or rebound at the higher level can begin use of SQL capabilities introduced at that level.
Related concepts
Application compatibility levels in Db2
The application compatibility level of your applications controls the adoption and use of new capabilities
and enhancements, and the impact of incompatible changes. The advantage is that you can complete the
Db2 12 migration process without the need to update your applications immediately.
Related tasks
Adopting new capabilities in Db2 12 continuous delivery (Db2 for z/OS What's New?)
Activating Db2 12 new function at migration (Db2 Installation and Migration)
Related reference
APPL COMPAT LEVEL field (APPLCOMPAT subsystem parameter) (Db2 Installation and Migration)
APPLCOMPAT bind option (Db2 Commands)
Precompile
DBRM
Coprocessor Language
Bind
Compile
Package
Object program
Link edit
Load module
Figure 41. Overview of the program preparation process for applications that contain embedded SQL.
The Db2 coprocessor can combine the precompile and compile steps for certain languages.
Db2 precompiler
After you process SQL statements in your source program by using the Db2 precompiler, you create a
load module, possibly one or more packages, and an application plan. Creating a load module involves
compiling the modified source code that is produced by the precompiler into an object program,
and link-editing the object program to create a load module. Creating a package or an application
plan, a process unique to Db2, involves binding one or more DBRMs, which are created by the Db2
precompiler, by using the BIND PACKAGE command. For more information, see “Processing SQL
statements by using the Db2 precompiler” on page 843.
Procedure
• Complete the tasks by using one of the methods described below:
a) “Processing SQL statements for program preparation” on page 838
b) “Compiling and link-editing an application” on page 865
c) “Binding application packages and plans” on page 866
d) Chapter 10, “Running an application on Db2 for z/OS,” on page 935
Binding a package is not necessary in all cases. These instructions assume that you bind some of your
DBRMs into packages and include a package list in your plan.
If you use CICS, you might need to complete additional steps. For more information, see:
– “Translating command-level statements in a CICS program” on page 852
– “Example of calling applications in a command procedure” on page 947
You can use the following methods to complete the program preparation tasks:
• Preparing applications by using JCL procedures
834 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
A number of methods are available for preparing an application to run. You can:
- Use Db2 interactive (DB2I) panels, which lead you step by step through the preparation process.
- Submit a background job using JCL (which the program preparation panels can create for you).
- Start the DSNH CLIST in TSO foreground or background.
- Use TSO prompters and the DSN command processor.
- Use JCL procedures added to your SYS1.PROCLIB (or equivalent) at Db2 installation time.
- You can invoke the coprocessor from UNIX System Services. If the DBRM is generated in a HFS
file, you can also use the command line processor to bind the resulting DBRM. Optionally, you can
also copy the DBRM into a partitioned data set member by using the oput and oget commands
and then bind it by using conventional JCL.
This topic describes how to use JCL procedures to prepare a program. For information about using
the DB2I panels, see Chapter 9, “Preparing an application to run on Db2 for z/OS,” on page 833.
• Preparing applications by the Db2 Program Preparation panels
If you develop programs using TSO and ISPF, you can prepare them to run by using the Db2
Program Preparation panels. These panels guide you step by step through the process of preparing
your application to run. Other ways of preparing a program to run are available, but using Db2
Interactive (DB2I) is the easiest because it leads you automatically from task to task.
Important: If your C++ program satisfies both of the following conditions, you must use a JCL
procedure to prepare it:
- The program consists of more than one data set or member.
- More than one data set or member contains SQL statements.
To prepare an application by using the Db2 Program Preparation panels:
1. If you want to display or suppress message IDs during program preparation, specify one of the
following commands on the ISPF command line:
TSO PROFILE MSGID
Message IDs are displayed
TSO PROFILE NOMSGID
Message IDs are supressed
2. Open the DB2I Primary Option Menu.
3. Select the option that corresponds to the Program Preparation panel.
4. Complete the Program Preparation panel and any subsequent panels. After you complete each
panel, DB2I automatically displays the next appropriate panel.
• Preparation guidelines for DL/I batch programs
Use the following guidelines when you prepare a program to access Db2 and DL/I in a batch
program:
- “Processing SQL statements by using the Db2 precompiler” on page 843
- “Binding a batch program” on page 879
- “Compiling and link-editing an application” on page 865
- “Loading and running a batch program” on page 941
Related concepts
The Db2 command line processor (Db2 Commands)
TSO attachment facility (Introduction to Db2 for z/OS)
Related reference
The DB2I primary option menu (Introduction to Db2 for z/OS)
DSNH (TSO CLIST) (Db2 Commands)
Procedure
As DB2I leads you through a series a panels, enter the default values that you want on the following
panels when they are displayed.
836 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 135. DB2I panels to use to set default values (continued)
If you want to set the following default values... Use this panel
The following package and plan characteristics Defaults for Bind Package panel
• isolation level Defaults for Bind Plan panel
• whether to check authorization at run time or at bind time
• when to release locks on resources
• whether to obtain EXPLAIN information about how SQL
statements in the plan or package execute
• whether you need data currency for ambiguous cursors opened
at remote locations
• whether to use parallel processing
• whether Db2 determines access paths at bind time and again at
execution time
• whether to defer preparation of dynamic SQL statements
• whether Db2 keeps dynamic SQL statements after commit
points
• the application encoding scheme
• whether you want to use optimization hints to determine access
paths
• when Db2 writes the changes for updated group buffer pool-
dependent pages
• whether run time (RUN) or bind time (BIND) rules apply to
dynamic SQL statements at run time
• whether to continue to create a package after finding SQL errors
(packages only)
• when to acquire locks on resources (plans only)
• whether a CONNECT (Type 2) statement executes according to
Db2 rules (Db2) or the SQL standard (STD). (plans only)
• which remote connections end during a commit or a rollback
(plans only)
Related reference
DB2I Defaults Panel 1
DB2I Defaults Panel 1 lets you change many of the system default values that were set at Db2 installation
time.
DB2I Defaults Panel 2
After you press Enter on the DB2I Defaults Panel 1, the DB2I Defaults Panel 2 is displayed. If you chose
IBMCOB as the language on the DB2I Defaults Panel 1, three fields are displayed. Otherwise, only the first
field is displayed.
Defaults for Bind Package and Defaults for Rebind Package panels
These DB2I panels lets you change your defaults for BIND PACKAGE and REBIND PACKAGE options.
Defaults for Bind Plan and Defaults for Rebind Plan panels
Procedure
To process SQL statements in application programs, use one of the following methods:
• Invoke the Db2 coprocessor for the host language that you are using as you compile your program. You
can use the Db2 coprocessor with C, C++, COBOL, and PL/I host compilers.
To invoke the Db2 coprocessor, specify the SQL compiler option followed by its suboptions, which are
those options that are defined for the Db2 precompiler. Some Db2 precompiler options are ignored.
You can also invoke the Db2 coprocessor from UNIX System Services on z/OS to generate a DBRM in
either a partitioned data set or an HFS file.
For more information, see “Processing SQL statements by using the Db2 coprocessor” on page 839.
• Use the Db2 precompiler before you compile your program. For more information, see “Processing SQL
statements by using the Db2 precompiler” on page 843
For assembler or Fortran applications, use the Db2 precompiler to prepare the SQL statements.
Results
The main output from the Db2 coprocessor or Db2 precompiler is a database request module (DBRM).
However, the Db2 coprocessor or Db2 precompiler also produces modified source statements, a list of
source statements, a list of statements that refer to host names and columns, and diagnostics. For more
information, see “Output from the Db2 precompiler” on page 849.
838 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
What to do next
If the application contains CICS® commands, you must translate the program before you compile it. For
more information, see “Translating command-level statements in a CICS program” on page 852.
Related concepts
Using the Db2 C/C++ precompiler (XL C/C++ Programming Guide)
Db2 coprocessor (Enterprise COBOL for z/OS Programming Guide)
Output from the Db2 precompiler
The main output from the Db2 precompiler is a database request module (DBRM). However, the Db2
precompiler also produces modified source statements, a list of source statements, a list of statements
that refer to host names and columns, and diagnostics.
Differences between the Db2 coprocessor and the Db2 precompiler
The Db2 coprocessor and the Db2 precompiler have architectural differences. You cannot switch from one
to the other without considering those differences and adjusting your program accordingly.
Program directories for Db2 12 (Db2 for z/OS in IBM Documentation)
Related tasks
Translating command-level statements in a CICS program
You can translate CICS applications with the CICS command language translator as a part of the program
preparation process. CICS command language translators are available only for assembler, C, COBOL, and
PL/I languages.
Related reference
Enterprise COBOL for z/OS
Precompile
DBRM
Coprocessor Language
Bind
Compile
Package
Object program
Link edit
Load module
Figure 42. Overview of the program preparation process for applications that contain embedded SQL. The
Db2 coprocessor can combine the precompile and compile steps for certain languages.
Exception: For PL/I, the Db2 coprocessor is called from the PL/I preprocessor instead of the compiler.
The Db2 coprocessor is the recommended method for processing SQL statements in application
programs. Compared to the Db2 precompiler, the Db2 coprocessor has fewer restrictions on SQL
programs, and more fully supports the latest SQL and programming language enhancements.
For example, when you process SQL statements with the Db2 coprocessor, you can do the following
things in your program:
• Use fully qualified names for structured host variables.
• Include SQL statements at any level of a nested program, instead of in only the top-level source file.
(Although you can include SQL statements at any level of a nested program, you must compile the entire
program as one unit.)
• Use nested SQL INCLUDE statements.
• For C or C++ programs only, write applications with variable length format.
• For C or C++ programs only, use codepage-dependent characters, such as left and right brackets,
without using tri-graph notation when the programs use different code pages.
Procedure
To process SQL statements by using the Db2 coprocessor, take one of the following actions:
• Submit a JCL job to process that SQL statement. Include the following information:
– Specify the SQL compiler option when you compile your program:
The SQL compiler option indicates that you want the compiler to invoke the Db2 coprocessor.
Specify a list of SQL processing options in parentheses after the SQL keyword. Table 139 on page
854 lists the options that you can specify.
840 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
For COBOL and PL/I, enclose the list of SQL processing options in single or double quotation
marks. For PL/I, separate options in the list by a comma, blank, or both, as shown in the following
examples:
LIMITS(FIXEDBIN(63), FIXEDDEC(31))
– If needed, increase the user's region size so that it can accommodate more memory for the Db2
coprocessor.
– Include DD statements for the following data sets in the JCL for your compile step:
Db2 load library (prefix.SDSNLOAD)
The Db2 coprocessor calls Db2modules to process the SQL statements. You therefore need to
include the name of the Db2 load library data set in the STEPLIB concatenation for the compiler
step.
DBRM library
The Db2 coprocessor produces a DBRM. DBRMs and the DBRM library are described in “Output
from the Db2 coprocessor” on page 842. You need to include a DBRMLIB DD statement that
specifies the DBRM library data set.
Library for SQL INCLUDE statements
If your program contains SQL INCLUDE member-name statements that specify secondary input
to the source program, you need to also specify the data set for member-name. Include the
name of the data set that contains member-name in the SYSLIB concatenation for the compiler
step.
• Invoke the Db2 coprocessor from z/OS UNIX System Services.
If you invoke the Db2 coprocessor from z/OS UNIX System Services, you can choose to have the DBRM
generated in a partitioned data set or an HFS file.
When you invoke the Db2 coprocessor, specify the SQL compiler option. The SQL compiler option
indicates that you want the compiler to invoke the Db2 coprocessor. Specify a list of SQL processing
options in parentheses after the SQL keyword. For the list of options that you can specify, see SQL
processing options.
The file name for the DBRM is determined as described in DRBMLIB. For host languages other than C
and C++, the DBRMLIB option is not supported and the file name is always generated. For C and C++,
you can specify one of the following items:
– The name of a partitioned data set. The following example invokes the C/C++ Db2 coprocessor to
compile (with the c89 compiler) a sample C program and requests that the resulting DBRM is stored
in the test member of the userid.dbrmlib.data data set:
– The name of an HFS file. The name can be qualified, partially qualified, or unqualified. The file
path can contain a maximum of 1024 characters, and the file name can contain a maximum of 255
characters. The first 8 characters of the file name, not including the file extension, must be unique
within the file system.
For example, assume that your directory structure is /u/USR001/c/example and that your current
working directory is /u/USR001/c. The following table shows examples of how to specify the HFS
file names with the DBRMLIB option and how the file names are resolved.
The following example invokes the Db2 coprocessorto compile (with the c89 compiler) a sample C
program and requests that the resulting DBRM is stored in the file test.dbrm in the tmp directory:
The following example invokes the Db2 coprocessor to compile a sample COBOL program with the
Enterprise COBOL for z/OS 6.2 or later compilers:
The following example invokes the Db2 coprocessor to compile a sample PL/I program from Enterprise
PL/I for z/OS 5.2 or later compilers:
If you request that the DBRM be generated in an HFS file, you can bind the resulting DBRM by using
the command line processor BIND command. For more information about using the command line
processor BIND command, see “Binding a DBRM that is in an HFS file to a package or collection” on
page 868. Optionally, you can also copy the DBRM into a partitioned data set member by using the
oput and oget commands and then bind the DBRM by using conventional JCL.
Results
The main output from the Db2 coprocessor is a database request module (DBRM). However, the Db2
coprocessor also produces modified source statements, a list of source statements, a list of statements
that refer to host names and columns, and diagnostics. For more information, see “Output from the Db2
coprocessor” on page 842.
Support for compiling a COBOL program that includes SQL from an assembler
program
The COBOL compiler provides a facility that enables you to invoke the COBOL compiler by using an
assembler program.
If you intend to use the Db2 coprocessor and start the COBOL compiler from an assembler program as
part of your Db2 application preparation, you can use the SQL compiler option and provide the alternate
DBRMLIB DD name the same way that you can specify other alternate DD names. The Db2 coprocessor
creates the DBRM member according to your DBRM PDS library and the DBRM member that you specified
using the alternate DBRMLIB DD name.
Related reference
Starting the compiler from an assembler program
842 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
programs, and more fully supports the latest SQL and programming language enhancements. See
“Processing SQL statements by using the Db2 coprocessor” on page 839.
The Db2 coprocessor produces a database request module (DBRM). The DBRM is a data set that contains
the SQL statements and host variable information that is extracted from the source program, along with
information that identifies the program and ties the DBRM to the translated source statements. The DBRM
becomes the input to the bind process.
The data set requires space to hold all the SQL statements plus space for each host variable name and
some header information. The header information alone requires approximately two records for each
DBRM, 20 bytes for each SQL record, and 6 bytes for each host variable.
For an exact format of the DBRM, see the DBRM mapping macros, DSNXDBRM and DSNXNBRM, in library
prefix.SDSNMACS. The DCB attributes of the data set are RECFM FB, LRECL 80. The precompiler sets
the characteristics. You can use IEBCOPY, IEHPROGM, TSOCOPY and DELETE commands, or other PDS
management tools for maintaining these data sets.
Important: Do not modify the contents of the DBRM. If you do, unpredictable results can occur. Db2 does
not support modified DBRMs.
All other character fields in a DBRM use EBCDIC. The current release marker (DBRMMRIC) in the header
of a DBRM is marked according to the release of the precompiler, regardless of the value of NEWFUN.
In a DBRM, the SQL statements and the list of host variable names use the UTF-8 character encoding
scheme.
Precompiler
Precompile
Modified DBRM
source
Bind package
Compile or
assemble
Object Package
program
Bind plan
Link edit
Load Plan
module
Before you run the Db2 precompiler, use DCLGEN to obtain accurate SQL DECLARE TABLE statements.
Db2 precompiler checks table and column references against SQL DECLARE TABLE statements in the
program, not the actual tables and columns.
Db2 does not need to be active when you precompile your program.
You do not need to precompile the program on the same Db2 subsystem on which you bind the DBRM and
run the program. You can bind a DBRM and run it on a Db2 subsystem at the previous release level, if the
original program does not use any properties of Db2 that are unique to the current release. You can also
run applications on the current release that were previously bound on subsystems at the previous release
level.
Procedure
To process SQL statements by using the Db2 precompiler:
1. Ensure that your program is ready to be processed by the Db2 precompiler by performing the following
actions.
For information about the criteria for programs that are passed to the Db2 precompiler, see “Input to
the Db2 precompiler” on page 847.
2. If you plan to run multiple precompilation jobs and are not using the DFSMSdfp partitioned data
set extended (PDSE), change the Db2 language preparation procedures (DSNHCOB, DSNHCOB2,
DSNHICOB, DSNHFOR, DSNHC, DSNHPLI, DSNHASM, DSNHSQL) to specify the DISP=OLD parameter
instead of the DISP=SHR parameter.
844 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
The Db2 language preparation procedures in job DSNTIJMV use the DISP=OLD parameter to enforce
data integrity. However, the installation process converts the DISP=OLD parameter for the DBRM
library data set to DISP=SHR, which can cause data integrity problems when you run multiple
precompilation jobs.
3. Start the precompile process by using one of the following methods:
• DB2I panels. Use the Precompile panel or the Db2 Program Preparation panels. For details, see
“DB2I panels that are used for program preparation” on page 902.
• The DSNH command procedure (a TSO CLIST). For details, see DSNH (TSO CLIST) (Db2
Commands).
• JCL procedures that are supplied with Db2. For details, see “Db2-supplied JCL procedures for
preparing an application” on page 899.
Recommendation: Specify the SOURCE and XREF precompiler options to get complete diagnostic
output from the Db2 precompiler. This output is useful if you need to precompile and compile program
source statements several times before they are error-free and ready to link-edit.
Results
The main output from the Db2 precompiler is a database request module (DBRM). However, the Db2
precompiler also produces modified source statements, a list of source statements, a list of statements
that refer to host names and columns, and diagnostics. For more information, see “Output from the Db2
precompiler” on page 849.
What to do next
Preparing a program with object-oriented extensions by using JCL
If your C++ or Enterprise COBOL for z/OS program satisfies both of these conditions, you need special
JCL to prepare it:
• The program consists of more than one data set or member.
• More than one data set or member contains SQL statements.
You must precompile the contents of each data set or member separately, but the prelinker must
receive all of the compiler output together.
JCL procedure DSNHCPP2, which is in member DSNTIJMV of data set DSN1210.SDSNSAMP, shows
you one way to do this for C++.
Precompiling a batch program
When you add SQL statements to an application program, you must precompile the application
program and bind the resulting DBRM into a package, as described in Chapter 9, “Preparing an
application to run on Db2 for z/OS,” on page 833.
Related concepts
DCLGEN (declarations generator)
Your program should declare the tables and views that it accesses. The Db2 declarations generator,
DCLGEN, produces these DECLARE statements for C, COBOL, and PL/I programs, so that you do not need
to code the statements yourself. DCLGEN also generates corresponding host variable structures.
Output from the Db2 precompiler
The main output from the Db2 precompiler is a database request module (DBRM). However, the Db2
precompiler also produces modified source statements, a list of source statements, a list of statements
that refer to host names and columns, and diagnostics.
Related reference
DSNH (TSO CLIST) (Db2 Commands)
Table 137. DD statements and data sets that the Db2 precompiler uses
DD statement Data set description Required?
DBRMLIB Output data set, which contains the SQL Yes
statements and host variable information that
the Db2 precompiler extracted from the source
program. It is called Database Request Module
(DBRM). This data set becomes the input to the
Db2 bind process. The DCB attributes of the
data set are RECFM FB, LRECL 80. DBRMLIB
has to be a PDS and a member name must be
specified. You can use IEBCOPY, IEHPROGM,
TSO commands, COPY and DELETE, or PDS
management tools for maintaining the data set.
STEPLIB Step library for the job step. In this DD No, but recommended
statement, you can specify the name of
the library for the precompiler load module,
DSNHPC, and the name of the library for your
Db2 application programming defaults member,
DSNHDECP.
Recommendation: Always use the STEPLIB DD
statement to specify the library where your
Db2 DSNHDECP module resides to ensure that
the proper application defaults are used by the
Db2 precompiler. The library that contains your
Db2 DSNHDECP module needs to be allocated
ahead of the prefix.SDSNLOAD library.
846 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 137. DD statements and data sets that the Db2 precompiler uses (continued)
DD statement Data set description Required?
SYSLIB INCLUDE library, which contains additional No
SQL and host language statements. The
Db2 precompiler includes the member or
members that are referenced by SQL INCLUDE
statements in the SYSIN input from this DD
statement. Multiple data sets can be specified,
but they must be partitioned data sets with
attributes RECFM F or FB, LRECL 80. SQL
INCLUDE statements cannot be nested.
SYSPRINT Output data set, which contains the output Yes
listing from the Db2 precompiler. This data set
must have an LRECL of 133 and a RECFM of
FBA. SYSPRINT must be a sequential data set
SYSTERM Terminal output file, which contains diagnostic No
messages from the Db2 precompiler. The DCB
attributes of the data set are determined by the
z/OS system. SYSTERM must be a sequential
data set.
SYSUT1 and SYSUT2 Internal work files that the precompiler uses No, unless you need
to store temporary information as it converts to override the default
embedded SQL statements to host language SPACE parameter values.
statements. Precompilation of assembler and
PL/I source code uses only the SYSUT1 data
set. The default SPACE parameter values in the
Db2-supplied program preparation procedures
(DSNHASM, DSNHC, DSNHCPP, DSNHCPP2,
DSNHICOB, DSNHPLI, and DSNHFOR) are
adequate in most cases. If your application
program contains a large number of embedded
SQL statements, you might need to increase
those values.
Related reference
SPACE Parameter (MVS JCL Reference)
848 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 138. DDNAME list entries (continued)
Entry Standard ddname Usage
4 SYSLIB Library input
5 SYSIN Source input
6 SYSPRINT Diagnostic listing
7 Not applicable
8 SYSUT1 Work data
9 SYSUT2 Work data
10 Not applicable
11 Not applicable
12 SYSTERM Diagnostic listing
13 Not applicable
14 SYSCIN Changed source output
15 Not applicable
16 DBRMLIB DBRM output
850 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
The Db2 precompiler scans a program and copies all of the SQL statements and host variable information
into a database request module (DBRM ). The Db2 precompiler also returns source code that has been
modified so that the SQL statements do not cause errors when you compile the program.
EXEC SQL
INSERT INTO T1 VALUES (:hv1, :hv2)
END-EXEC.
Db2 coprocessor: In the modified source from the Db2 coprocessor with the National Character
Support for COBOL, hv1 and hv2 are represented to Db2 in the following way, with CCSIDs: (Assume
that the source CCSID is 1140.)
for hv1 and hv2, the value for CCSID is set to '1140' ('474'x) in input SQLDA
of the INSERT statement.
To ensure that no discrepancy exists between the column with FOR BIT DATA and the host variable
with CCSID 1140, add the following statement for :hv1 or use the Db2 precompiler:
for hv1 declared with for bit data. The value in SQL---AVAR-NAME-DATA is
set to 'FFFF'x for CCSID instead of '474x'.
Db2 precompiler: In the modified source from the Db2 precompiler, hv1 and hv2 are represented to
Db2 through SQLDA in the following way, without CCSIDs:
– PL/I
Db2 coprocessor:
You can specify whether CCSIDs are to be associated with host variables by using the following
PL/I SQL preprocessor options:
CCSID0
Specifies that the PL/I SQL preprocessor is not to set the CCSIDs for all host variables unless
they are defined with the SQL DECLARE :hv VARIABLE statement.
NOCCSID0
Specifies that the PL/I SQL preprocessor is to set the CCSIDs for all host variables.
Related concepts
z/OS Unicode Services User’s Guide and Reference
Related reference
Descriptions of SQL processing options
You can specify any SQL processing options regardless of whether you use the Db2 precompiler or the
Db2 coprocessor. However, the Db2 coprocessor might ignore certain options because host language
compiler options exist that provide the same information.
Enterprise COBOL for z/OS
SQL preprocessor options (PL/I) (Enterprise PL/I for z/OS Programming Guide:)
Procedure
Prepare your CICS program in either of these sequences:
Sequence Remarks
852 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Sequence Remarks
b. CICS Command Language translator options automatically, rather than needing to provide a
Translator. separate option string.
a. CICS command language This sequence results in a warning message from the CICS translator
translator for each EXEC SQL statement that it encounters. The warning
messages have no effect on the result. If you are using double-
b. Db2 precompiler byte character sets (DBCS), precompiling is recommended before
translating, as described previously.
Use the Db2 precompiler before the CICS translator to prevent the precompiler from mistaking CICS
translator output for graphic data.
If your source program is in COBOL, you must specify a string delimiter that is the same for the Db2
precompiler, COBOL compiler, and CICS translator. The defaults for the Db2 precompiler and COBOL
compiler are not compatible with the default for the CICS translator.
If the SQL statements in your source program refer to host variables that a pointer stored in the
CICS TWA addresses, you must make the host variables addressable to the TWA before you execute
those statements. For example, a COBOL application can issue the following statement to establish
addressability to the TWA:
You can run CICS applications only from CICS address spaces. This restriction applies to the RUN option
on the second program DSN command processor. All of those possibilities occur in TSO.
To prepare an application program, you can append JCL from a job that is created by the Db2 Program
Preparation panels to the JCL for the CICS command language translator. To run the prepared program
under CICS, you might need to define programs and transactions to CICS. Your system programmer must
make the appropriate CICS resource or table entries.
prefix.SDSNSAMP contains examples of the JCL that is used to prepare and run a CICS program that
includes SQL statements. The set of JCL includes:
• PL/I macro phase
• Db2 precompiling
• CICS Command Language Translation
• Compiling of the host language source statements
• Link-editing of the compiler output
• Binding of the DBRM
• Running of the prepared application.
Related reference
Sample applications in CICS
A set of Db2 sample applications run in the CICS environment.
Related information
Resource definition (CICS Transaction Server for z/OS)
Db2 coprocessor
If you are using the Db2 coprocessor, specify SQL processing options in one of the following ways:
• For C or C++, specify the options as the argument of the SQL compiler option.
• For COBOL, specify the options as the argument of the SQL compiler option.
• For PL/I, specify the options as the argument of the PP(SQL('option,...')) compiler option.
For examples of how to specify the Db2 coprocessoroptions, see “Processing SQL statements by using
the Db2 coprocessor” on page 839
Db2 precompiler
If you are using the Db2 precompiler, specify SQL processing options in one of the following ways:
• With DSNH operands
• With the PARM option of the EXEC JCL statement
• On DB2I panels
Db2 assigns default values for any SQL processing options for which you do not explicitly specify a
value. Those defaults are the values that are specified on the APPLICATION PROGRAMMING DEFAULTS
installation panels.
APOSTSQL Recognizes the apostrophe (') as the string delimiter and the double quotation
mark (") as the SQL escape character within SQL statements.
APOSTSQL and QUOTESQL are mutually exclusive options. The default is in the
field SQL STRING DELIMITER on Application Programming Defaults Panel 1
during installation. If SQL STRING DELIMITER is the apostrophe ('), APOSTSQL is
the default.
854 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 139. SQL processing options (continued)
Option keyword Meaning
ATTACH(TSO|CAF| RRSAF| Specifies the attachment facility that the application uses to access Db2 TSO,
ULI) CAF, RRSAF, or DSNULI applications that load the attachment facility can use
this option to specify the correct attachment facility, instead of coding a dummy
DSNHLI entry point.
You can specify ATTACH(ULI) only when you use the Db2 coprocessor.
This option is not available for Fortran applications.
The default is ATTACH(TSO).
CCSID(n) Specifies the numeric value n of the CCSID in which the source program is
written. The number n must be an EBCDIC CCSID.
The default setting is the EBCDIC system CCSID as specified on the panel
DSNTIPF during installation.
The Db2 coprocessor uses the following process to determine the CCSID of the
source statements:
1. If the CCSID of the source program is specified by a compiler option, such
as the COBOL CODEPAGE compiler option, the Db2 coprocessor uses that
CCSID. If you also specify the CCSID suboption of the SQL compiler option
that is different from the CCSID compiler option, a warning is returned, and
the CCSID suboption value is not used.
2. If the CCSID is not specified by a compiler option:
a. If the CCSID suboption of the SQL compiler option is specified and
contains a valid EBCDIC CCSID, that CCSID is used.
b. If the CCSID suboption of the SQL compiler option is not specified, and the
compiler supports an option for specifying the CCSID, such as the COBOL
CODEPAGE compiler option, the default for the CCSID compiler option is
used.
c. If the CCSID suboption of the SQL compiler option is not specified, and the
compiler does not support an option for specifying the CCSID, the default
CCSID from DSNHDECP or a user-specified application defaults module is
used.
d. If the CCSID suboption of the SQL option is specified and contains an
invalid CCSID, compilation terminates.
CCSID supersedes the GRAPHIC and NOGRAPHIC SQL processing options.
If you specify CCSID(1026) or CCSID(1155), the Db2 coprocessor does not
support the code point 'FC'X for the double quotation mark (").
COMMA Recognizes the comma (,) as the decimal point indicator in decimal or floating
point literals in the following cases:
• For static SQL statements in COBOL programs
• For dynamic SQL statements, when the value of installation parameter
DYNRULS is NO and the package or plan that contains the SQL statements
has DYNAMICRULES bind, define, or invoke behavior.
COMMA and PERIOD are mutually exclusive options. The default (COMMA or
PERIOD) is chosen under DECIMAL POINT IS on Application Programming
Defaults Panel 1 during installation.
DECP(name) name represents the 1 to 8 character name of the application defaults data-only
load module that is to be used.
The default name DSNHDECP is used if this parameter is omitted.
GRAPHIC This option is no longer used for SQL statement processing. Use the CCSID
option instead.
Indicates that the source code might use mixed data, and that X'0E'and X'0F' are
special control characters (shift-out and shift-in) for EBCDIC data.
GRAPHIC and NOGRAPHIC are mutually exclusive options. The default
(GRAPHIC or NOGRAPHIC) is specified in the field MIXED DATA on Application
Programming Defaults Panel 1 during installation.
856 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 139. SQL processing options (continued)
Option keyword Meaning
Defines the host language that contains the SQL statements.
HOST1(ASM|C[(FOLD)]|
CPP[(FOLD)]| Use IBMCOB for Enterprise COBOL for z/OS.
IBMCOB|
For C, specify:
PLI|
FORTRAN| • C if you do not want Db2 to fold lowercase letters in SBCS SQL ordinary
SQL| identifiers to uppercase
SQLPL) • C(FOLD) if you want Db2 to fold lowercase letters in SBCS SQL ordinary
identifiers to uppercase
For C++, specify:
• CPP if you do not want Db2 to fold lowercase letters in SBCS SQL ordinary
identifiers to uppercase
• CPP(FOLD) if you want Db2 to fold lowercase letters in SBCS SQL ordinary
identifiers to uppercase
For SQL procedural language, specify:
• SQL, to perform syntax checking and conversion to a generated C program for
an external SQL procedure.
• SQLPL, to perform syntax checking for a native SQL procedure.
If you omit the HOST option, the Db2 precompiler issues a level-4 diagnostic
message and uses the default value for this option.
The default is in the field LANGUAGE DEFAULT on Application Programming
Defaults Panel 1 during installation.
This option also sets the language-dependent defaults.
LEVEL[(aaaa)] Defines the level of a module, where aaaa is any alphanumeric value of up
to seven characters. This option is not recommended for general use, and the
L
DSNH CLIST and the DB2I panels do not support it.
For assembler, C, C++, Fortran, and PL/I, you can omit the suboption (aaaa).
The resulting consistency token is blank. For COBOL, you need to specify the
suboption.
Defines the number of lines per page to be n for the Db2 precompiler listing.
LINECOUNT1(n)
This includes header lines that are inserted by the Db2 precompiler. The default
LC
setting is LINECOUNT(60).
Specifies what part of each source record contains host language or
MARGINS1(m,n[,c])
SQL statements. For assembler, this option also specifies where column
MAR
continuations begin. The first option (m) is the beginning column for statements.
The second option (n) is the ending column for statements. The third option (c)
specifies where assembler continuations begin. Otherwise, the Db2 precompiler
places a continuation indicator in the column immediately following the ending
column. Margin values can range 1 - 80.
Default values depend on the HOST option that you specify.
The DSNH CLIST and the DB2I panels do not support this option. In assembler,
the margin option must agree with the ICTL instruction, if presented in the
source.
NOFOR In static SQL, eliminates the need for the FOR UPDATE or FOR UPDATE OF
clause in DECLARE CURSOR statements. When you use NOFOR, your program
can make positioned updates to any columns that the program has Db2 authority
to update.
When you do not use NOFOR, if you want to make positioned updates to any
columns that the program has Db2 authority to update, you need to specify FOR
UPDATE with no column list in your DECLARE CURSOR statements. The FOR
UPDATE clause with no column list applies to static or dynamic SQL statements.
Regardless of whether you use NOFOR, you can specify FOR UPDATE OF with a
column list to restrict updates to only the columns that are named in the clause,
and you can specify the acquisition of update locks.
You imply NOFOR when you use the option STDSQL(YES).
If the resulting DBRM is very large, you might need extra storage when you
specify NOFOR or use the FOR UPDATE clause with no column list.
NOGRAPHIC This option is no longer used for SQL statement processing. Use the CCSID
option instead.
Indicates the use of X'0E'and X'0F' in a string, but not as control characters.
GRAPHIC and NOGRAPHIC are mutually exclusive options. The default
(GRAPHIC or NOGRAPHIC) is specified in the field MIXED DATA on Application
Programming Defaults Panel 1 during installation.
The NOGRAPHIC option applies to only EBCDIC data.
858 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 139. SQL processing options (continued)
Option keyword Meaning
NOPADNTSTR Indicates that output host variables that are NUL-terminated strings are not
padded with blanks. That is, additional blanks are not inserted before the NUL-
terminator is placed at the end of the string.
PADNTSTR and NOPADNTSTR are mutually exclusive options. The default
(PADNTSTR or NOPADNTSTR) is specified in the field PAD NUL-TERMINATED
on Application Programming Defaults Panel 2 during installation.
This option applies to only C and C++ applications.
NOXREF Suppresses the Db2 precompiler cross-reference listing. This is the default.
Processes in one pass, to avoid the additional processing time for making two
ONEPASS
passes. Declarations must appear before SQL references.
ON
Default values depend on the HOST option specified.
ONEPASS and TWOPASS are mutually exclusive options.
PADNTSTR Indicates that output host variables that are NUL-terminated strings are padded
with blanks with the NUL-terminator placed at the end of the string.
PADNTSTR and NOPADNTSTR are mutually exclusive options. The default
(PADNTSTR or NOPADNTSTR) is specified in the field PAD NUL-TERMINATED
on Application Programming Defaults Panel 2 during installation.
This option applies to only C and C++ applications.
PERIOD Recognizes the period (.) as the decimal point indicator in decimal or floating
point literals in the following cases:
• For static SQL statements in COBOL programs
• For dynamic SQL statements, when the value of installation parameter
DYNRULS is NO and the package or plan that contains the SQL statements
has DYNAMICRULES bind, define, or invoke behavior.
COMMA and PERIOD are mutually exclusive options. The default (COMMA or
PERIOD) is specified in the field DECIMAL POINT IS on Application Programming
Defaults Panel 1 during installation.
QUOTESQL Recognizes the double quotation mark (") as the string delimiter and the
apostrophe (') as the SQL escape character within SQL statements. This option
applies only to COBOL.
The default is specified in the field SQL STRING DELIMITER on Application
Programming Defaults Panel 1 during installation. If SQL STRING DELIMITER is
the double quotation mark (") or DEFAULT, QUOTESQL is the default.
APOSTSQL and QUOTESQL are mutually exclusive options.
SQL(ALL|DB2) Indicates whether the source contains SQL statements other than those
recognized by Db2 for z/OS.
SQL(ALL) is recommended for application programs whose SQL statements must
execute on a server other that Db2 for z/OS using DRDA access. SQL(ALL)
indicates that the SQL statements in the program are not necessarily for Db2
for z/OS. Accordingly, the SQL statement processor then accepts statements
that do not conform to the Db2 syntax rules. The SQL statement processor
interprets and processes SQL statements according to distributed relational
database architecture (DRDA) rules. The SQL statement processor also issues an
informational message if the program attempts to use IBM SQL reserved words
as ordinary identifiers. SQL(ALL) does not affect the limits of the SQL statement
processor.
SQL(Db2), the default, means to interpret SQL statements and check syntax for
use by Db2 for z/OS. SQL(Db2) is recommended when the database server is
Db2 for z/OS.
860 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 139. SQL processing options (continued)
Option keyword Meaning
SQLLEVEL(V10R1|V11R1| Indicates whether to accept the SQL syntax that is new in Db2 12 function levels.
function-level) SQLLEVEL(function-level)
Specifies the function level allowed by the precompilation process.The
format is VvvRrMmmm, where vv is the version, r is the release, and mmm
is the modification level. SQLLEVEL V12R1M100 is equivalent to V11R1.
SQLLEVEL(V11R1)
Specifies that any SQL syntax up to Db2 11 is allowed.
SQLLEVEL(V10R1)
Specifies that any SQL syntax up to DB2 10 is allowed.
SQLLEVEL(V9R1)
Specifies that any SQL syntax up to DB2 9 is allowed. DB2 9 is supported,
but causes the precompilation process to support only a DB2 9 level of SQL
syntax.
SQLLEVEL(V8R1)
Specifies that any SQL syntax up to DB2 version 8 is allowed. DB2 version 8
is supported, but causes the precompilation process to support only a DB2
version 8 level of SQL syntax.
The function level activated on the Db2 subsystem does not restrict the
SQLLEVEL value. However, you must ensure that you bind the resulting DBRM
with the correct application compatibility level on a Db2 subsystem with the
correct function level activated.
TIME(ISO|USA|EUR|JIS| Specifies that time output always return in a particular format, regardless of the
LOCAL) format that is specified as the location default.
The default is specified in the field TIME FORMAT on Application Programming
Defaults Panel 2 during installation.
The default format is determined by the installation defaults of the system where
the program is bound, not by the installation defaults of the system where the
program is precompiled.
You cannot use the LOCAL option unless you have a time exit routine.
XREF5 Includes a sorted cross-reference listing of symbols that are used in SQL
statements in the listing output.
Notes:
1. The Db2 coprocessor ignores this option when the Db2 coprocessor is invoked by the compiler to prepare
the application.
2. This option is always in effect when the Db2 coprocessor is invoked by the compiler to prepare the
application.
3. You can use STDSQL(86) as in prior releases of Db2. The SQL statement processor treats it the same as
STDSQL(YES).
4. Precompiler options do not affect ODBC behavior.
5. The Db2 coprocessor ignores this option when the Db2 coprocessor is invoked by the compiler to prepare
the application. However, if you are using PL/I V4.1 or later, it is supported.
Related concepts
Precision for operations with decimal numbers
Db2 accepts two sets of rules for determining the precision and scale of the result of an operation with
decimal numbers.
Datetime values (Db2 SQL)
Related tasks
Creating a package version
If you want to run different versions of a program without needing to make changes to the associated
application plan, use package versions. This technique is useful if you need to make changes to your
program without causing an interruption to the availability of the program.
Setting the program level
The program level defines the level for a particular module. This information is stored in the consistency
token, which is in an internal Db2 format. Overriding the program level in the consistency token is
possible, if needed, but generally not recommended.
Related reference
Defaults for SQL processing options
862 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Some SQL statement processing options have default values that are based on values that are specified
on the DB2I Application Programming Defaults panels.
Table 140. IBM-supplied installation default SQL statement processing options. The installer can change these
defaults.
Equivalent SQL
statement processing Available SQL statement
Install option Install default option processing options
STRING DELIMITER quotation mark (") QUOTE APOSTQUOTE
SQL STRING DELIMITER quotation mark (") QUOTESQL APOSTSQLQUOTESQL
DECIMAL POINT IS PERIOD PERIOD COMMAPERIOD
DATE FORMAT ISO DATE(ISO) DATE(ISO|USA| EUR|JIS|
LOCAL)
DECIMAL ARITHMETIC DEC15 DEC(15) DEC(15|31)
MIXED DATA NO CCSID(n) CCSID(n)
LANGUAGE DEFAULT COBOL HOST(COBOL) HOST(ASM|C[(FOLD)]|
CPP[(FOLD)]|IBMCOB|
FORTRAN|PLI)
STD SQL LANGUAGE NO STDSQL(NO) STDSQL(YES|NO|86)
TIME FORMAT ISO TIME(ISO) TIME(IS|USA|EUR| JIS|
LOCAL)
Notes: For dynamic SQL statements, another application programming default, USE FOR DYNAMICRULES,
determines whether Db2 uses the application programming default or the SQL statement processor option for
the following installation options:
• STRING DELIMITER
• SQL STRING DELIMITER
• DECIMAL POINT IS
• DECIMAL ARITHMETIC
If the value of USE FOR DYNAMICRULES is YES, dynamic SQL statements use the application programming
defaults. If the value of USE FOR DYNAMICRULES is NO, dynamic SQL statements in packages or plans with
bind, define, and invoke behavior use the SQL statement processor options.
Some SQL statement processor options have default values based on the host language. Some options do
not apply to some languages. The following table shows the language-dependent options and defaults.
Notes:
1. Forced for this language; no alternative is allowed.
2. The default is chosen on Application Programming Defaults Panel 1 during installation. The IBM-supplied
installation defaults for string delimiters are QUOTE (host language delimiter) and QUOTESQL (SQL escape
character). The installer can replace the IBM-supplied defaults with other defaults. The precompiler options
that you specify override any defaults that are in effect.
864 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Compiling and link-editing an application
If you use the Db2 coprocessor, you process SQL statements as you compile your program, and the next
step is the link edit the program. The purpose of the link-edit step is to produce an executable load
module.
Procedure
• You can use one of the following methods to compile and link-edit an application:
• DB2I panels. For details, see “DB2I panels that are used for program preparation” on page 902.
• The DSNH command procedure (a TSO CLIST). For details, see DSNH (TSO CLIST) (Db2
Commands).
• JCL procedures supplied with Db2. For details, see “Db2-supplied JCL procedures for preparing an
application” on page 899.
• JCL procedures supplied with a host language compiler.
• Use a link-edit procedure that builds a load module that satisfies the environment-specific
requirements of the program.
TSO and batch
Include the Db2 TSO attachment facility language interface module (DSNELI) or Db2 call
attachment facility language interface module (DSNALI) or the Universal Language Interface
module (DSNULI).
IMS
Include the Db2 IMS language interface module (DFSLI000), which contains the DSNHLI entry
point. Also, the IMS RESLIB must precede the SDSNLOAD library in the link list, JOBLIB, or
STEPLIB concatenations.
IMS and Db2 share a common alias name, DSNHLI, for the language interface module. You must do
the following when you concatenate your libraries:
– If you use IMS, be sure to concatenate the IMS library first so that the application program
compiles with the correct IMS version of DSNHLI.
– If you run your application program only under Db2, be sure to concatenate the Db2 library first.
CICS
Include the Db2 CICS language interface module (DSNCLI) or the Universal Language Interface
module (DSNULI). You can link DSNCLI with your program in either 24-bit or 31-bit addressing
mode (AMODE=31), but DSNULI must be linked with your program in 31-bit addressing mode
(AMODE=31). If your application runs in 31-bit addressing mode, you should link-edit the DSNCLI
or DSNULI stub to your application with the attributes AMODE=31 and RMODE=ANY so that your
application can run above the 16-MB line.
866 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Exception: You do not need to bind a DBRM if the only SQL statement in the program is SET CURRENT
PACKAGESET.
Because you do not need a plan or package to execute the SET CURRENT PACKAGESET statement, the
ENCODING bind option does not affect the SET CURRENT PACKAGESET statement. An application that
needs to provide a host variable value in an encoding scheme other than the system default encoding
scheme must use the DECLARE VARIABLE statement to specify the encoding scheme of the host variable.
You must bind plans locally, regardless of whether they reference packages that run remotely. However,
you must bind the packages that run at remote locations at those remote locations.
From a Db2 requester, you can run a plan by specifying it in the RUN subcommand, but you cannot run a
package directly. You must include the package in a plan and then run the plan.
Tip: Develop a naming convention and strategy for the most effective and efficient use of your plans and
packages.
Procedure
To bind application programs, take the following actions.
1. To bind individual DBRMs into packages, use BIND PACKAGE commands with ACTION(REPLACE).
Packages provide the flexibility for you to test different versions of a program without having to rebind
everything in the application plan.
For programs whose corresponding DBRMs are in HFS files, you can use the command line processor
to bind the DBRMs to packages. Optionally, you can also copy the DBRM into a partitioned data set
member by using the oput and oget commands and then bind it by using conventional JCL.
To create new trigger packages for existing triggers, you must re-create the trigger that is associated
with the package. For more information, see “Trigger packages” on page 159.
2. To designate packages in application plans, use the BIND PLAN command with ACTION(REPLACE).
Plans can specify packages, collections of packages, or a combination of these elements. If you
specify one or more DBRMs to include in the plan (by using the MEMBER option of BIND PLAN), Db2
automatically binds those DBRMs into packages and then binds those packages into the plan. The plan
contains information about the designated packages and about the data that the application programs
intend to use. The plan is stored in the Db2 catalog.
Related concepts
Package copies for plan management (Db2 Performance)
Automatic rebinds
Automatic rebinds (sometimes called "autobinds") occur when an authorized user runs a package or
plan and the runtime structures in the plan or package cannot be used. This situation usually results
from changes to the attributes of the data on which the package or plan depends, or changes to the
environment in which the package or plan runs.
Related tasks
Binding a DBRM that is in an HFS file to a package or collection
If DBRMs are in z/OS UNIX HFS files, you can use the command line processor to bind the DBRMs to
packages at the target Db2 server. Optionally, you can also copy the DBRM into a partitioned data set
member by using the TSO/E oput and oget commands and then bind the DBRM by using conventional JCL.
Related reference
BIND PACKAGE (DSN) (Db2 Commands)
BIND PLAN (DSN) (Db2 Commands)
BIND and REBIND options for packages, plans, and services (Db2 Commands)
Procedure
To create a package version:
1. Precompile your program with the option VERSION(version-identifier).
2. Bind the resulting DBRM with the same collection name and package name as any existing versions of
that package. When you run the program, Db2 uses the package version that you specified when you
precompiled it.
Example
Suppose that you bound a plan with the following statement:
The following steps show how to create two versions of a package, one for each of two programs.
868 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Procedure
To bind a DBRM that is in an HFS file to a package or collection:
1. Invoke the command line processor and connect to the target Db2 server.
2. Specify the BIND command with the appropriate options.
Related concepts
The Db2 command line processor (Db2 Commands)
Related tasks
Processing SQL statements by using the Db2 coprocessor
You can use the Db2 coprocessor for processing SQL statements at compile time. With theDb2
coprocessor, the compiler scans a program and copies all of the SQL statements and host variable
information into a database request module (DBRM). The Db2 coprocessor is the recommended method
for processing SQL statements in application programs. Compared to the Db2 precompiler, the Db2
coprocessor has fewer restrictions on SQL programs, and more fully supports the latest SQL and
programming language enhancements.
Related reference
Command line processor BIND command
Use the command line processor BIND command to bind DBRMs that are in z/OS UNIX HFS files to
packages.
2
BIND dbrm-file-name options-clause
1
-COLLECTION collection-name
Notes:
1 If you do not specify a collection, Db2 uses NULLID.
2 You can specify the options after collection-name in any order.
options-clause:
NODEFER(PREPARE)
DEFERPREPARE(INHERITFROMPLAN)
DEFER(PREPARE)
ACTION (REPLACE)
(ADD)
CURRENTDATA ( NO ) DBPROTOCOL(PRIVATE)
ALL
DEGREE(1) DYNAMICRULES(RUN)
DEFINEBIND
DEFINERUN
INVOKEBIND
INVOKERUN
EXPLAIN(NO)
EBCDIC ALL
UNICODE ONLY
ccsid
IMMEDWRITE(NO) KEEPDYNAMIC(NO)
PH1
INHERITFROMPLAN
1
ISOLATION(CS) REOPT(NONE)
ISOLATION( RR ) 2
REOPT(ALWAYS)
RS
UR
NC
RELEASE(COMMIT)
RELEASE(INHERITFROMPLAN)
SQLERROR(NOPACKAGE) VALIDATE(RUN)
CHECK
path-clause
Notes:
1 You can specify NOREOPT(VARS) as a synonym of REOPT(NONE).
2 You can specify REOPT(VARS) as a synonym of REOPT(ALWAYS).
870 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
path-clause:
PATH( )
PATH( schema-name )
USER
Procedure
To bind an application plan, use the BIND PLAN subcommand with at least one of the following options:
MEMBER
Specify this option to bind DBRMs to a package and then bind the package list to a plan. After the
keyword MEMBER, specify the member names of the DBRMS.
PKLIST
Specify this option to include package lists in the plan. After the keyword PKLIST, specify the names of
the packages to include in the package list. To include an entire collection of packages in the list, use
an asterisk after the collection name. For example, PKLIST(GROUP1.*).
Specifying the package list for the PKLIST option of BIND PLAN
The order in which you specify packages in a package list can affect run time performance. Searching
for the specific package involves searching the Db2 directory, which can be costly. When you use
collection-id.* with the PKLIST keyword, you should specify first the collections in which Db2 is most
likely to find a package.
For example, assume that you perform the following bind:
Then you execute program PROG1. Db2 does the following package search:
a. Checks to see if program PROG1 is bound as part of the plan
b. Searches for COLL1.PROG1.timestamp
c. If it does not find COLL1.PROG1.timestamp, searches for COLL2.PROG1.timestamp
d. If it does not find COLL2.PROG1.timestamp, searches for COLL3.PROG1.timestamp
PKLIST (collection.*)
PKLIST (*.collection.*)
If you use an asterisk for part of a name in a package list, Db2 checks the authorization for the package to
which the name resolves at run time. To avoid the checking at run time in the preceding example, you can
grant EXECUTE authority for the entire collection to the owner of the plan before you bind the plan.
Related tasks
Improving performance for applications that access distributed data (Db2 Performance)
Related reference
BIND PLAN (DSN) (Db2 Commands)
CURRENT PACKAGE PATH (Db2 SQL)
CURRENT PACKAGESET (Db2 SQL)
872 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
How Db2 identifies packages at run time
The Db2 precompiler or Db2 coprocessor identifies each call to Db2 with a consistency token. The same
consistency token identifies the DBRM that the SQL statement processor produces and the package to
which you bound the DBRM.
When you run the program, Db2 uses the consistency token in matching the call to Db2 to the correct
DBRM. Usually, the consistency token is in an internal Db2 format. You can override that token if you want.
You also need other identifiers. The consistency token alone does not necessarily identify a unique
package. You can bind the same DBRM to many packages, at different locations and in different
collections, and you can include all those packages in the package list of the same plan. All those
packages will have the same consistency token. You can specify a particular location or a particular
collection at run time.
Related tasks
Setting the program level
The program level defines the level for a particular module. This information is stored in the consistency
token, which is in an internal Db2 format. Overriding the program level in the consistency token is
possible, if needed, but generally not recommended.
874 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 142. Scope of CURRENT PACKAGE PATH (continued)
Example What happens
PACKAGE PATH at server S2 is an empty string because it
SET CURRENT PACKAGE PATH
CONNECT TO S2 ... has not been explicitly set. The values from the PKLIST bind
SELECT ... FROM T1 ... option of the plan that is at the requester determine which
package is invoked.1
The collections in PACKAGE PATH that are set at server S2
SET CURRENT PACKAGE PATH
= 'A,B' determine which package is invoked.
CONNECT TO S2 ...
SET CURRENT PACKAGE PATH
= 'X,Y'
SELECT ... FROM T1 ...
Notes:
1. When CURRENT PACKAGE PATH is set at the requester (and not at the remote server), Db2 passes
one collection at a time from the list of collections to the remote server until a package is found or
until the end of the list. Each time a package is not found at the server, Db2 returns an error to the
requester. The requester then sends the next collection in the list to the remote server.
Example: Bind a package at the local site and the remote site
Suppose that you precompiled program MYPROG to generate DBRM MYPROG, and compiled and link-
edited program MYPROG. You want to run MYPROG to access tables at site CHICAGO from your local site.
Use commands like these to bind local and remote packages and a plan. The number at the end of each
line corresponds to a previously described step.
876 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
statements, Db2 uses the ENCODING value for the package that is at the site where a statement
executes.
878 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Binding a batch program
Before a batch program can issue SQL statements, a Db2 plan must exist.
Conversion of DBRMs that are bound to a plan to DBRMs that are bound to a
package
You must bind all DBRMs into a package, and bind the packages into a plan. One package can have only
one DBRM.
The default REBIND PLAN COLLID (*) option converts all plans with DBRMs into plans with a package
list. You can use this technique for local applications only. If the plan that you specify already contains
both DBRMs and package lists, the newly converted package entries will be inserted into the front of the
existing package list.
Important: If the same DBRM is in multiple plans, and you run REBIND PLAN with the same COLLID
option value on more than one of those plans, Db2 overlays the previously created package in the
collection each time you run REBIND with COLLID. To avoid overlaying packages, specify a different
COLLID value for each plan that contains DBRMs that are also in other plans.
For more information on developing a strategy for converting your plans to include only packages, see
DB2 9 for z/OS: Packages Revisited (IBM Redbooks).
Procedure
To turn an existing plan with member DBRMs into packages to run remotely, perform the following actions
for each remote location:
1. Choose a name for a collection to contain member DBRMs, such as REMOTE1.
2. Convert the plan into a plan with a package list of packages.
REBIND PLAN(REMOTE1)COLLID(*)
880 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
3. Query SYSIBM.SYSPACKDEP, to see if any of the packages have a dependency on an alias. That alias is
a definition for a 3-part name.
a) For each of the packages that have a dependency on an alias:
BIND PACKAGE(location.remote_server_collid)
COPY(DSN_DEFAULT_COLLID_planname.pgkid)
COPYVER(...) OPTIONS(COMPOSITE)
4. Adjust the location's package list. If prior to this process, the plan had no package list, after “2” on
page 880 it will have a package list containing DSN_DEFAULT_COLLID_planname.pgkid.
Results
When you now run the existing application at your local Db2 system using the new application plan, these
things happen:
• You connect immediately to the remote location that is named in the CURRENTSERVER option.
• Db2 searches for the package in the collection REMOTE1 at the remote location.
• Any UPDATE, DELETE, or INSERT statements in your application affect tables at the remote location.
• Any results from SELECT statements are returned to your existing application program, which processes
them as though they came from your local Db2 system.
Procedure
Use the LEVEL (aaaa) option.
Db2 uses the value that you choose for aaaa to generate the consistency token. Although this method
is not recommended for general use and the DSNH CLIST or the Db2 Program Preparation panels do not
support it, this method enables you to perform the following actions:
a. Change the source code (but not the SQL statements) in the Db2 precompiler output of a bound
program.
b. Compile and link-edit the changed program.
c. Run the application without rebinding a plan or package.
Table 143. How DYNAMICRULES and the runtime environment determine dynamic SQL statement
behavior
Behavior of dynamic SQL statements
Stand-alone program User-defined function or stored
DYNAMICRULES value environment procedure environment
RUN Run Run
BIND Bind Bind
DEFINERUN Run Define
DEFINEBIND Bind Define
INVOKERUN Run Invoke
INVOKEBIND Bind Invoke
Note: BIND and RUN values can be specified for packages, plans, and native SQL procedures. The other
values can be specified for packages and native SQL procedures but not for plans.
The following table shows the dynamic SQL attribute values for each type of dynamic SQL behavior.
882 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 144. Definitions of dynamic SQL statement behaviors (continued)
Dynamic SQL attribute Setting for dynamic SQL behavior attributes
Bind Run Define Invoke
Source for application Determined by Install panel Determined by Determined by
programming options DSNHDECP or DSNTIP4 DSNHDECP or DSNHDECP or
a user-specified a user-specified a user-specified
application defaults application defaults application defaults
module parameter module parameter module parameter
DYNRULS3 DYNRULS3 DYNRULS3
Can execute GRANT, No Yes No No
REVOKE, CREATE, ALTER,
DROP, RENAME?
Notes:
1. If the invoker is the primary authorization ID of the process or the CURRENT SQLID value, secondary
authorization IDs are also checked if they are needed for the required authorization. Otherwise, only one ID,
the ID of the invoker, is checked for the required authorization.
2. Db2 uses the value of CURRENT SQLID as the authorization ID for dynamic SQL statements only for plans
and packages that have run behavior. For the other dynamic SQL behaviors, Db2 uses the authorization ID
that is associated with each dynamic SQL behavior, as shown in this table.
The value to which CURRENT SQLID is initialized is independent of the dynamic SQL behavior. For stand-
alone programs, CURRENT SQLID is initialized to the primary authorization ID.
You can execute the SET CURRENT SQLID statement to change the value of CURRENT SQLID for packages
with any dynamic SQL behavior, but Db2 uses the CURRENT SQLID value only for plans and packages with
run behavior.
3. The value of DSNHDECP or a user-specified application defaults module parameter DYNRULS, which you
specify in field USE FOR DYNAMICRULES in installation panel DSNTIP4, determines whether Db2 uses the
SQL statement processing options or the application programming defaults for dynamic SQL statements.
See “Options for SQL statement processing” on page 853 for more information.
Related concepts
Authorization IDs and dynamic SQL (Db2 SQL)
Authorization behaviors for dynamic SQL statements (Managing Security)
Related reference
DYNAMICRULES bind option (Db2 Commands)
The following scenario illustrates thread association for a task that runs program MAIN. Suppose that you
execute the following SQL statements in the indicated order. For each SQL statement, the resulting event
is described.
1. EXEC CICS START TRANSID(MAIN)
TRANSID(MAIN) executes program MAIN.
2. EXEC SQL SELECT…
Program MAIN issues an SQL SELECT statement. The default dynamic plan exit routine selects plan
MAIN.
3. EXEC CICS LINK PROGRAM(PROGA)
Program PROGA is invoked.
4. EXEC SQL SELECT…
Db2 does not call the default dynamic plan exit routine, because the program does not issue a sync
point. The plan is MAIN.
5. EXEC CICS LINK PROGRAM(PROGB)
Program PROGB is invoked.
6. EXEC SQL SELECT…
Db2 does not call the default dynamic plan exit routine, because the program does not issue a sync
point. The plan is MAIN and the program uses package PKGB.
7. EXEC CICS SYNCPOINT
Db2 calls the dynamic plan exit routine when the next SQL statement executes.
8. EXEC CICS LINK PROGRAM(PROGC)
Program PROGC is invoked.
9. EXEC SQL SELECT…
Db2 calls the default dynamic plan exit routine and selects PLANC.
10. EXEC SQL SET CURRENT SQLID = 'ABC'
The CURRENT SQLID special register is assigned the value 'ABC.'
11. EXEC CICS SYNCPOINT
Db2 does not call the dynamic plan exit routine when the next SQL statement executes because the
previous statement modifies the special register CURRENT SQLID.
12. EXEC CICS RETURN
Control returns to program PROGB.
13. EXEC SQL SELECT…
884 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
CICS With packages, you probably do not need dynamic plan selection and its accompanying exit routine.
A package that is listed within a plan is not accessed until it is executed. However, you can use dynamic
plan selection and packages together, which can reduce the number of plans in an application and the
effort to maintain the dynamic plan exit routine.
Rebinding applications
You must rebind applications to change bind options. You also need to rebind applications when you make
changes that affect the plan or package, such as creating an index, but you have not changed the SQL
statements.
Rebinding a package
You need to rebind a package when you make changes that affect the package but that do not involve
changes to the SQL statements. For example, if you create a new index, you need to rebind the package. If
you change the SQL, you need to use the BIND PACKAGE command with the ACTION(REPLACE) option.
Table 146. Behavior of REBIND PACKAGE specification. "All" means all collections, packages, or versions
at the local Db2 server for which the authorization ID that issues the command has the BIND privilege.
Input Collections Packages affected Versions affected
affected
all all all
*
886 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 146. Behavior of REBIND PACKAGE specification. "All" means all collections, packages, or versions
at the local Db2 server for which the authorization ID that issues the command has the BIND privilege.
(continued)
Input Collections Packages affected Versions affected
affected
all pkg-id ver-id
*.pkg-id.(ver-id)
Examples
Example: Rebinding a package at a remote location
The following example shows the options for rebinding a package at the remote location. The location
name is SNTERSA. The collection is GROUP1, the package ID is PROGA, and the version ID is V1. The
connection types shown in the REBIND subcommand replace connection types that are specified on
the original BIND subcommand.
Related tasks
Reusing and comparing access paths at bind and rebind (Db2 Performance)
Related reference
BIND and REBIND options for packages, plans, and services (Db2 Commands)
REBIND PACKAGE (DSN) (Db2 Commands)
888 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Rebinding a plan
You need to rebind a plan when you make a change to one of the attributes of the plan, such as the
package list.
Procedure
Use the REBIND PLAN subcommand.
You can change any of bind options for that plan.
When you rebind a plan, use the PKLIST keyword to replace any previously specified package list. Omit
the PKLIST keyword to use of the previous package list for rebinding. Use the NOPKLIST keyword to
delete any package list that was specified when the plan was previously bound.
Examples
Example
The following command rebinds PLANA and changes the package list:
Example
The following command rebinds the plan and drops the entire package list:
Related reference
BIND and REBIND options for packages, plans, and services (Db2 Commands)
REBIND PLAN (DSN) (Db2 Commands)
890 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Example: REBIND all plans without terminating because of unavailable resources.
Example: REBIND all versions of all packages without terminating because of unavailable resources.
Example: REBIND all plans bound before a given date and time.
where yymmdd represents the date portion and hhmmssth represents the time portion of the
timestamp string.
If the date specified is after 2000, you need to include another condition that includes plans that were
bound before year 2000:
WHERE
BINDDATE >= '830101' OR
BINDDATE <= 'yymmdd' OR
(BINDDATE <= 'yymmdd' AND
BINDTIME <= 'hhmmssth');
Example: REBIND all versions of all packages bound before a given date and time.
where yymmdd represents the date portion and hhmmssth represents the time portion of the
timestamp string.
Example: REBIND all versions of all packages bound since a given date and time.
where yymmdd represents the date portion and hhmmssth represents the time portion of the
timestamp string.
Example: REBIND all versions of all packages bound within a given date and time range.
Example: REBIND all plans bound with ISOLATION level of cursor stability.
Example: REBIND all versions of all packages that allow CPU and/or I/O parallelism.
892 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
//*********************************************************************/
//SETUP EXEC PGM=IKJEFT01
//SYSTSPRT DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
RUN PROGRAM(DSNTIAUL) PLAN(DSNTIBC1) PARMS('SQL') -
LIB('DSN1210.RUNLIB.LOAD')
END
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSPUNCH DD SYSOUT=*
//SYSREC00 DD DSN=SYSADM.SYSTSIN.DATA,
// UNIT=SYSDA,DISP=SHR
//*********************************************************************/
//*
//* GENER= '<SUBCOMMANDS TO REBIND ALL PACKAGES BOUND IN YYYY
//*
//*********************************************************************/
//SYSIN DD *
SELECT SUBSTR('REBIND PACKAGE('CONCAT COLLID CONCAT'.'
CONCAT NAME CONCAT'.(*)) ',1,55)
FROM SYSIBM.SYSPACKAGE
WHERE BINDTIME >= 'YYYY-MM-DD-hh.mm.ss' AND
BINDTIME <= 'YYYY-MM-DD-hh.mm.ss';
/*
//*********************************************************************/
//*
//* STRIP THE BLANKS OUT OF THE REBIND SUBCOMMANDS
//*
//*********************************************************************/
//STRIP EXEC PGM=IKJEFT01
//SYSPROC DD DSN=SYSADM.DSNCLIST,DISP=SHR
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//SYSTSIN DD *
DSNTEDIT SYSADM.SYSTSIN.DATA
//SYSIN DD DUMMY
/*
//*********************************************************************/
//*
//* PUT IN THE DSN COMMAND STATEMENTS
//*
//*********************************************************************/
//EDIT EXEC PGM=IKJEFT01
//SYSTSPRT DD SYSOUT=*
//SYSTSIN DD *
EDIT 'SYSADM.SYSTSIN.DATA' DATA NONUM
TOP
INSERT DSN SYSTEM(DSN)
BOTTOM
INSERT END
TOP
LIST * 99999
END SAVE
/*
//*********************************************************************/
//*
//* EXECUTE THE REBIND PACKAGE SUBCOMMANDS THROUGH DSN
//*
//*********************************************************************/
//LOCAL EXEC PGM=IKJEFT01
//DBRMLIB DD DSN=DSN1210.DBRMLIB.DATA,
// DISP=SHR
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSTSIN DD DSN=SYSADM.SYSTSIN.DATA,
// UNIT=SYSDA,DISP=SHR
/*
The following example shows some sample JCL for rebinding all plans bound without specifying the
DEGREE keyword on BIND with DEGREE(ANY).
Automatic rebinds
Automatic rebinds (sometimes called "autobinds") occur when an authorized user runs a package or
plan and the runtime structures in the plan or package cannot be used. This situation usually results
from changes to the attributes of the data on which the package or plan depends, or changes to the
environment in which the package or plan runs.
For a list of actions that might cause Db2 to mark packages invalid, see “Changes that invalidate
packages” on page 14.
In most cases, Db2 marks a package that must be automatically rebound as invalid by setting VALID='N'
in the SYSIBM.SYSPLAN and SYSIBM.SYSPACKAGE catalog tables.
If an automatic rebind fails, Db2 marks a package as inoperative in the OPERATIVE column of
SYSIBM.SYSPLAN and SYSIBM.SYSPACKAGE catalog tables. However, if autobind phase-in fails for a
package that is invalidated at the statement level, OPERATIVE='R' is used in the SYSPACKAGE table only.
894 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Controls for automatic binds
Db2 uses automatic binds only when the ABIND subsystem parameter is set to YES or COEXIST. If ABIND
is set to NO when an invalid package runs, Db2 returns an error. For details, see AUTO BIND field (ABIND
subsystem parameter) (Db2 Installation and Migration).
You can also use resource limit tables to control automatic binds. For details, see Restricting bind
operations (Db2 Performance).
EXEC SQL
SET CURRENT RULES = 'DB2';
EXEC SQL
ALTER TABLE DSN8C10.EMP
ADD CONSTRAINT C1 CHECK (BONUS <= 1000.0);
EXEC SQL
SET CURRENT RULES = 'STD';
See “Check constraints” on page 127 for information about check constraints.
You can also use CURRENT RULES in host variable assignments. For example, if you want to store the
value of the CURRENT RULES special register at a particular point in time, you can use assign the value to
a host variable, as in the following statement:
You can also use CURRENT RULES as the argument of a search-condition. For example, the following
statement retrieves rows where the COL1 column contains the same value as the CURRENT RULES
special register.
896 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Input and output data sets for DL/I batch jobs
DL/I batch jobs require an input data set with DD name DDITV02 and an output data set with DD name
DDOTV02.
Db2 DL/I batch input:
Before you can run a DL/I batch job, you need to provide values for a number of input parameters. The
input parameters are positional and delimited by commas.
You can specify values for the following parameters using a DDITV02 data set or a subsystem member:
SSN,LIT,ESMT,RTT,REO,CRC
You can specify values for the following parameters only in a DDITV02 data set:
CONNECTION_NAME,PLAN,PROG
If you use the DDITV02 data set and specify a subsystem member, the values in the DDITV02 DD
statement override the values in the specified subsystem member. If you provide neither, Db2 abnormally
terminates the application program with system abend code X'04E' and a unique reason code in register
15.
DDITV02 is the DD name for a data set that has DCB options of LRECL=80 and RECFM=F or FB.
A subsystem member is a member in the IMS procedure library. Its name is derived by concatenating
the value of the SSM parameter to the value of the IMSID parameter. You specify the SSM parameter and
the IMSID parameter when you invoke the DLIBATCH procedure, which starts the DL/I batch processing
environment.
The meanings of the input parameters are:
SSN
Specifies the name of the Db2 subsystem. This value is required. You must specify a name in order to
make a connection to Db2.
The SSN value can be from one to four characters long.
If the value in the SSN parameter is the name of an active subsystem in the data sharing group,
the application attaches to that subsystem. If the SSN parameter value is not the name of an active
subsystem, but the value is a group attachment name, the application attaches to an active Db2
subsystem in the data sharing group.
LIT
Specifies a language interface token. Db2 requires a language interface token to route SQL statements
when operating in the online IMS environment. Because a batch application program can connect to
only one Db2 system, Db2 does not use the LIT value.
The LIT value can be from zero to four characters long.
Recommendation: Specify the LIT value as SYS1.
You can omit the LIT value by entering SSN,,ESMT.
ESMT
Specifies the name of the Db2 initialization module, DSNMIN10. This value is required.
The ESMT value must be eight characters long.
RTT
Specifies the resource translation table. This value is optional.
The RTT can be from zero to eight characters long.
REO
Specifies the region error option. This option determines what to do if Db2 is not operational or the
plan is not available. The three options are:
DSN,SYS1,DSNMIN10,,R,-,BATCH001,DB2PLAN,PROGA
898 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
statement. Ensure that the output data set has DCB options of RECFM=V or VB, LRECL=4092, and
BLKSIZE of at least LRECL + 4. If the DD statement is missing, Db2 issues the message IEC130I and
continues processing without any output.
You might want to save and print the data set, as the information is useful for diagnostic purposes. You
can use the IMS module, DFSERA10, to print the variable-length data set records in both hexadecimal and
character format.
Related concepts
Submitting work to be processed (Db2 Data Sharing Planning and Administration)
Notes:
1. You must customize these programs to invoke the procedures that are listed in this table.
2. This procedure demonstrates how you can prepare an object-oriented program that consists of two
data sets or members, both of which contain SQL.
If you use the PL/I macro processor, you must not use the PL/I *PROCESS statement in the source to
pass options to the PL/I compiler. You can specify the needed options on the PARM.PLI= parameter of the
EXEC statement in the DSNHPLI procedure.
JCL to include the appropriate interface code when using the Db2-supplied
JCL procedures
To include the proper interface code when you submit the JCL procedures, use an INCLUDE SYSLIB
statement in your link-edit JCL. The statement should specify the correct language interface module for
the environment.
TSO, batch
//LKED.SYSIN DD *
INCLUDE SYSLIB(member)
/*
member must be DSNELI or DSNULI, except for FORTRAN, in which case member must be DSNHFT.
//LKED.SYSIN DD *
INCLUDE SYSLIB(member)
/*
900 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
The following example illustrates the necessary changes. This example assumes the use of a COBOL
program. For any other programming language, change the CICS procedure name and the Db2
precompiler options.
//TESTC01 JOB
//*
//*********************************************************
//* DB2 PRECOMPILE THE COBOL PROGRAM
//*********************************************************
(1) //PC EXEC PGM=DSNHPC,
(1) // PARM='HOST(COB2),XREF,SOURCE,FLAG(I),APOST'
(1) //STEPLIB DD DISP=SHR,DSN=prefix.SDSNEXIT
(1) // DD DISP=SHR,DSN=prefix.SDSNLOAD
(1) //DBRMLIB DD DISP=OLD,DSN=USER.DBRMLIB.DATA(TESTC01)
(1) //SYSCIN DD DSN=&&DSNHOUT,DISP=(MOD,PASS),UNIT=SYSDA,
(1) // SPACE=(800,(500,500))
(1) //SYSLIB DD DISP=SHR,DSN=USER.SRCLIB.DATA
(1) //SYSPRINT DD SYSOUT=*
(1) //SYSTERM DD SYSOUT=*
(1) //SYSUDUMP DD SYSOUT=*
(1) //SYSUT1 DD SPACE=(800,(500,500),,,ROUND),UNIT=SYSDA
(1) //SYSUT2 DD SPACE=(800,(500,500),,,ROUND),UNIT=SYSDA
(1) //SYSIN DD DISP=SHR,DSN=USER.SRCLIB.DATA(TESTC01)
(1) //*
//********************************************************************
//*** BIND THIS PROGRAM.
//********************************************************************
(2) //BIND EXEC PGM=IKJEFT01,
(2) // COND=((4,LT,PC))
(2) //STEPLIB DD DISP=SHR,DSN=prefix.SDSNEXIT
(2) // DD DISP=SHR,DSN=prefix.SDSNLOAD
(2) //DBRMLIB DD DISP=OLD,DSN=USER.DBRMLIB.DATA(TESTC01)
(2) //SYSPRINT DD SYSOUT=*
(2) //SYSTSPRT DD SYSOUT=*
(2) //SYSUDUMP DD SYSOUT=*
(2) //SYSTSIN DD *
(2) DSN S(DSN)
(2) BIND PLAN(TESTC01) MEMBER(TESTC01) ACTION(REP) RETAIN ISOLATION(CS)
(2) END
//********************************************************************
//* COMPILE THE COBOL PROGRAM
//********************************************************************
(3) //CICS EXEC DFHEITVL
(4) //TRN.SYSIN DD DSN=&&DSNHOUT,DISP=(OLD,DELETE)
(5) //LKED.SYSLMOD DD DSN=USER.RUNLIB.LOAD
(6) //LKED.CICSLOAD DD DISP=SHR,DSN=prefix.SDFHLOAD
//LKED.SYSIN DD *
(7) INCLUDE CICSLOAD(DSNCLI)
NAME TESTC01(R)
//********************************************************************
“DB2I Defaults Panel 1” on Lets you change many of the system defaults that are set at Db2
page 907 installation time.
“DB2I Defaults Panel 2” on Lets you change your default job statement and set additional COBOL
page 909 options.
“Precompile panel” on page Lets you specify values for precompile functions.
910
You can reach this panel directly from the DB2I Primary Option Menu or
from the Db2 Program Preparation panel. If you reach this panel from
the Program Preparation panel, many of the fields contain values from
the Primary and Precompile panels.
“Bind Package panel” on page Lets you change many options when you bind a package.
912
You can reach this panel directly from the DB2I Primary Option Menu or
from the Db2 Program Preparation panel. If you reach this panel from
the Db2 Program Preparation panel, many of the fields contain values
from the Primary and Precompile panels.
“Bind Plan panel” on page Lets you change options when you bind an application plan.
914
You can reach this panel directly from the DB2I Primary Option Menu
or as a part of the program preparation process. This panel also follows
the Bind Package panels.
“Defaults for Bind Package and Let you change the defaults for BIND or REBIND PACKAGE or PLAN.
Defaults for Rebind Package
panels” on page 917
“System Connection Types Lets you specify a system connection type.
panel” on page 921
This panel displays if you choose to enable or disable connections on
the Bind or Rebind Package or Plan panels.
902 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 148. DB2I panels used for program preparation (continued)
Panel name Panel description
“Panels for entering lists of Let you enter or modify an unlimited number of values. A list panel
values” on page 923 looks similar to an ISPF edit session and lets you scroll and use a
limited set of commands.
“Program Preparation: Lets you perform the last two steps in the program preparation process
Compile, Link, and Run panel” (compile and link-edit).
on page 924
This panel also lets you do the PL/I MACRO PHASE for programs that
require this option.
For TSO programs, the panel also lets you run programs.
Related reference
The DB2I primary option menu (Introduction to Db2 for z/OS)
DB2I panels that are used to rebind and free plans and packages
A set of DB2I panels lets you bind, rebind, or free packages.
The following explains the functions on the Db2 Program Preparation panel and how to complete the
necessary fields in order to start program preparation.
1 INPUT DATA SET NAME
Lets you specify the input data set name. The input data set name can be a PDS or a sequential data
set, and can also include a member name. If you do not enclose the data set name in apostrophes, a
standard TSO prefix (user ID) qualifies the data set name.
The input data set name you specify is used to precompile, bind, link-edit, and run the program.
2 DATA SET NAME QUALIFIER
Lets you qualify temporary data set names involved in the program preparation process. Use any
character string from 1 to 8 characters that conforms to normal TSO naming conventions. (The default
is TEMP.)
For programs that you prepare in the background or that use EDITJCL for the PREPARATION
ENVIRONMENT option, Db2 creates a data set named tsoprefix.qualifier.CNTL to contain the program
preparation JCL. The name tsoprefix represents the prefix TSO assigns, and qualifier represents the
value you enter in the DATA SET NAME QUALIFIER field. If a data set with this name already exists,
Db2 deletes it.
3 PREPARATION ENVIRONMENT
Lets you specify whether program preparation occurs in the foreground or background. You can also
specify EDITJCL, in which case you are able to edit and then submit the job. Use:
FOREGROUND to use the values you specify on the Program Preparation panel and to run
immediately.
BACKGROUND to create and submit a file containing a DSNH CLIST that runs immediately using
the JOB control statement from either the DB2I Defaults panel or your site's SUBMIT exit. The file
is saved.
EDITJCL to create and open a file containing a DSNH CLIST in edit mode. You can then submit the
CLIST or save it.
4 RUN TIME ENVIRONMENT
Lets you specify the environment (TSO, CAF, CICS, IMS, RRSAF) in which your program runs.
All programs are prepared under TSO, but can run in any of the environments. If you specify CICS,
IMS, or RRSAF, then you must set the RUN field to NO because you cannot run such programs from
the Program Preparation panel. If you set the RUN field to YES, you can specify only TSO or CAF.
(Batch programs also run under the TSO Terminal Monitor Program. You therefore need to specify TSO
in this field for batch programs.)
904 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
5 OTHER DSNH OPTIONS
Lets you specify a list of DSNH options that affect the program preparation process, and that override
options specified on other panels. If you are using CICS, these can include options you want to specify
to the CICS command translator.
If you specify options in this field, separate them by commas. You can continue listing options on the
next line, but the total length of the option list can be no more than 70 bytes.
Fields 6 through 15 let you select the function to perform and to choose whether to show the DB2I panels
for the functions you select. Use Y for YES, or N for NO.
If you are willing to accept default values for all the steps, enter N under Display panel? for all the other
preparation panels listed.
To make changes to the default values, entering Y under Display panel? for any panel you want to see.
DB2I then displays each of the panels that you request. After all the panels display, Db2 proceeds with
the steps involved in preparing your program to run.
Variables for all functions used during program preparation are maintained separately from variables
entered from the DB2I Primary Option Menu. For example, the bind plan variables you enter on the
Program Preparation panel are saved separately from those on any Bind Plan panel that you reach from
the Primary Option Menu.
6 CHANGE DEFAULTS
Lets you specify whether to change the DB2I defaults. Enter Y in the Display panel? field next to this
option; otherwise enter N. Minimally, you should specify your subsystem identifier and programming
language on the Defaults panel.
7 PL/I MACRO PHASE
Lets you specify whether to display the "Program Preparation: Compile, Link, and Run" panel to
control the PL/I macro phase by entering PL/I options in the OPTIONS field of that panel. That panel
also displays for options COMPILE OR ASSEMBLE, LINK, and RUN.
This field applies to PL/I programs only. If your program is not a PL/I program or does not use the PL/I
macro processor, specify N in the Perform function field for this option, which sets the Display panel?
field to the default N.
8 PRECOMPILE
Lets you specify whether to display the Precompile panel. To see this panel enter Y in the Display
panel? field next to this option; otherwise enter N.
9 CICS COMMAND TRANSLATION
Lets you specify whether to use the CICS command translator. This field applies to CICS programs
only.
IMS and TSO: If you run under TSO or IMS, ignore this step; this allows the Perform function field to
default to N.
CICS: If you are using CICS and have precompiled your program, you must translate your program
using the CICS command translator.
The command translator does not have a separate DB2I panel. You can specify translation options on
the Other Options field of the Db2 Program Preparation panel, or in your source program if it is not an
assembler program.
Because you specified a CICS run time environment, the Perform function column defaults to Y.
Command translation takes place automatically after you precompile the program.
10 BIND PACKAGE
Lets you specify whether to display the Bind Package panel. To see it, enter Y in the Display panel?
field next to this option; otherwise, enter N.
11 BIND PLAN
Lets you specify whether to display the Bind Plan panel. To see it, enter Y in the Display panel? field
next to this option; otherwise, enter N.
906 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
The Compile, Link, and Run panel lets you perform the last two steps in the program preparation process
(compile and link-edit). This panel also lets you perform the PL/I MACRO PHASE for programs that require
this option.
DSNH (TSO CLIST) (Db2 Commands)
Prelinking an application (z/OS Language Environment Programming Guide)
908 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
After Db2 establishes the trusted connection, the primary authorization ID, any secondary
authorization IDs, any role, and any security label that is associated with the user ID that is specified
in the AS USER field are used for the trusted connection. Db2 uses this security label to verify
multilevel security for the user.
If the primary authorization ID that is associated with the user ID that is specified in the AS USER field
is not allowed to use the trusted connection or requires authentication information, the connection
request fails. If Db2 cannot verify the security label, the connection request also fails.
The value that you enter in this field is retained only for the length of the DB2I session. The field is
reset to blank when you exit DB2I.
Suppose that the default programming language is PL/I and the default number of lines per page of
program listing is 60. Your program is in COBOL, so you want to change field 3, APPLICATION LANGUAGE.
You also want to print 80 lines to the page, so you need to change field 4, LINES/PAGE OF LISTING, as
well. Figure 45 on page 907 shows the entries that you make in DB2I Defaults Panel 1 to make these
changes. In this case, pressing ENTER takes you to Db2 Defaults Panel 2.
Precompile panel
After you set the DB2I defaults, you can precompile your application. You can reach the Precompile panel
by specifying it as a part of the program preparation process from the Db2 Program Preparation panel. Or
you can reach it directly from the DB2I Primary Option Menu.
The way you choose to reach the panel determines the default values of the fields it contains. The
following figure shows the Precompile panel.
The following explains the functions on the Precompile panel, and how to enter the fields for preparing to
precompile.
1 INPUT DATA SET
Lets you specify the data set name of the source program and SQL statements to precompile.
If you reached this panel through the Db2 Program Preparation panel, this field contains the data set
name specified there. You can override it on this panel.
If you reached this panel directly from the DB2I Primary Option Menu, you must enter the data set
name of the program you want to precompile. The data set name can include a member name. If you
do not enclose the data set name with apostrophes, a standard TSO prefix (user ID) qualifies the data
set name.
2 INCLUDE LIBRARY
Lets you enter the name of a library containing members that the precompiler should include. These
members can contain output from DCLGEN. If you do not enclose the name in apostrophes, a
standard TSO prefix (user ID) qualifies the name.
You can request additional INCLUDE libraries by entering DSNH CLIST parameters of the form
PnLIB(dsname), where n is 2, 3, or 4) on the OTHER OPTIONS field of this panel or on the OTHER
DSNH OPTIONS field of the Program Preparation panel.
3 DSNAME QUALIFIER
Lets you specify a character string that qualifies temporary data set names during precompile.
Use any character string from 1 to 8 characters in length that conforms to normal TSO naming
conventions.
If you reached this panel through the Db2 Program Preparation panel, this field contains the data set
name qualifier specified there. You can override it on this panel.
910 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
If you reached this panel from the DB2I Primary Option Menu, you can either specify a DSNAME
QUALIFIER or let the field take its default value, TEMP.
IMS and TSO: For IMS and TSO programs, Db2 stores the precompiled source statements (to pass
to the compiler or assemble step) in a data set named tsoprefix.qualifier.suffix. A data set named
tsoprefix.qualifier.PCLIST contains the precompiler print listing.
For programs prepared in the background or that use the PREPARATION ENVIRONMENT option
EDITJCL (on the Db2 Program Preparation panel), a data set named tsoprefix.qualifier.CNTL contains
the program preparation JCL.
In these examples, tsoprefix represents the prefix TSO assigns, often the same as the authorization
ID. qualifier represents the value entered in the DSNAME QUALIFIER field. suffix represents the
output name, which is one of the following: COBOL, FORTRAN, C, PLI, ASM, DECK, CICSIN, OBJ, or
DATA. In the Precompile Panel that is shown above, the data set tsoprefix.TEMP.COBOL contains the
precompiled source statements, and tsoprefix.TEMP.PCLIST contains the precompiler print listing. If
data sets with these names already exist, then Db2 deletes them.
CICS: For CICS programs, the data set tsoprefix.qualifier.suffix receives the precompiled source
statements in preparation for CICS command translation.
If you do not plan to do CICS command translation, the source statements in tsoprefix.qualifier.suffix,
are ready to compile. The data set tsoprefix.qualifier.PCLIST contains the precompiler print listing.
When the precompiler completes its work, control passes to the CICS command translator.
Because there is no panel for the translator, translation takes place automatically. The data set
tsoprefix.qualifier.CXLIST contains the output from the command translator.
4 DBRM DATA SET
Lets you name the DBRM library data set for the precompiler output. The data set can also include a
member name.
When you reach this panel, the field is blank. When you press ENTER, however, the value contained
in the DSNAME QUALIFIER field of the panel, concatenated with DBRM, specifies the DBRM data set:
qualifier.DBRM.
You can enter another data set name in this field only if you allocate and catalog the data set before
doing so. This is true even if the data set name that you enter corresponds to what is otherwise the
default value of this field.
The precompiler sends modified source code to the data set qualifier.host, where host is the language
specified in the APPLICATION LANGUAGE field of DB2I Defaults panel 1.
5 WHERE TO PRECOMPILE
Lets you indicate whether to precompile in the foreground or background. You can also specify
EDITJCL, in which case you are able to edit and then submit the job.
If you reached this panel from the Db2 Program Preparation panel, the field contains the preparation
environment specified there. You can override that value if you want.
If you reached this panel directly from the DB2I Primary Option Menu, you can either specify a
processing environment or allow this field to take its default value. Use:
FOREGROUND to immediately precompile the program with the values you specify in these panels.
BACKGROUND to create and immediately submit to run a file containing a DSNH CLIST using the
JOB control statement from either DB2I Defaults Panel 2 or your site's SUBMIT exit. The file is
saved.
EDITJCL to create and open a file containing a DSNH CLIST in edit mode. You can then submit the
CLIST or save it.
6 VERSION
Lets you specify the version of the program and its DBRM. If the version contains the maximum
number of characters permitted (64), you must enter each character with no intervening blanks from
one line to the next. This field is optional.
COMMAND ===>_
The following information explains the functions on the Bind Package panel and how to fill the necessary
fields in order to bind your program.
1 LOCATION NAME
Lets you specify the system at which to bind the package. You can use from 1 to 16
characters to specify the location name. The location name must be defined in the catalog table
SYSIBM.LOCATIONS. The default is the local DBMS.
2 COLLECTION-ID
Lets you specify the collection the package is in. You can use from 1 to 128 characters to specify the
collection, and the first character must be alphabetic. This field is scrollable.
3 DBRM: COPY:
Lets you specify whether you are creating a new package (DBRM) or making a copy of a package that
already exists (COPY). Use:
DBRM
To create a new package. You must specify values in the LIBRARY, PASSWORD, and MEMBER
fields.
COPY
To copy an existing package. You must specify values in the COLLECTION-ID and PACKAGE-ID
fields. (The VERSION field is optional.)
912 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
4 MEMBER or COLLECTION-ID
MEMBER (for new packages): If you are creating a new package, this option lets you specify the
DBRM to bind. You can specify a member name from 1 to 128 characters. This field is scrollable. The
default name depends on the input data set name.
• If the input data set is partitioned, the default name is the member name of the input data set
specified in the INPUT DATA SET NAME field of the Db2 Program Preparation panel.
• If the input data set is sequential, the default name is the second qualifier of this input data set.
COLLECTION-ID (for copying a package): If you are copying a package, this option specifies the
collection ID that contains the original package. You can specify a collection ID from 1 to 128
characters, which must be different from the collection ID specified on the PACKAGE ID field. This
field is scrollable.
5 PASSWORD or PACKAGE-ID
PASSWORD (for new packages): If you are creating a new package, this lets you enter password for
the library you list in the LIBRARY field. You can use this field only if you reached the Bind Package
panel directly from the Db2 Primary Option Menu. This field is scrollable.
PACKAGE-ID (for copying packages): If you are copying a package, this option lets you specify the
name of the original package. You can enter a package ID from 1 to 128 characters. This field is
scrollable.
6 LIBRARY or VERSION
LIBRARY (for new packages): If you are creating a new package, this lets you specify the names of
the libraries that contain the DBRMs specified on the MEMBER field for the bind process. Libraries are
searched in the order specified and must in the catalog tables.
VERSION (for copying packages): If you are copying a package, this option lets you specify the
version of the original package. You can specify a version ID from 1 to 64 characters.
7 OPTIONS
Lets you specify which bind options Db2 uses when you issue BIND PACKAGE with the COPY option.
Specify:
• COMPOSITE (default) to cause Db2 to use any options you specify in the BIND PACKAGE
command. For all other options, Db2 uses the options of the copied package.
• COMMAND to cause Db2 to use the options you specify in the BIND PACKAGE command. For all
other options, Db2 uses the following values:
– For a local copy of a package, Db2 uses the defaults for the local Db2 subsystem.
– For a remote copy of a package, Db2 uses the defaults for the server on which the package is
bound.
8 CHANGE CURRENT DEFAULTS?
Lets you specify whether to change the current defaults for binding packages. If you enter YES in
this field, you see the Defaults for Bind Package panel as your next step. You can enter your new
preferences there; for instructions, see “Defaults for Bind Package and Defaults for Rebind Package
panels” on page 917.
9 ENABLE/DISABLE CONNECTIONS?
Lets you specify whether you want to enable and disable system connections types to use with this
package. This is valid only if the LOCATION NAME field names your local Db2 system.
Placing YES in this field displays a panel (shown in Figure 54 on page 922) that lets you specify
whether various system connections are valid for this application. You can specify connection names
to further identify enabled connections within a connection type. A connection name is valid only
when you also specify its corresponding connection type.
The default enables all connection types.
914 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
DSNEBP02 BIND PLAN SSID: DSN
COMMAND ===>_
The following explains the functions on the Bind Plan panel and how to fill the necessary fields in order to
bind your program.
1 LOCATION NAME
Lets you specify the remote system where the package that is named in the PACKAGE ID field is
bound. The location name must be defined in the catalog table SYSIBM.LOCATIONS. The default is the
local DBMS.
2 COLLECTION ID
Lets you specify the collection that includes the package that is to be bound into the plan.
The field is scrollable, and the maximum field length is 128.
3 PACKAGE ID
Lets you specify the name of the package that is to be bound into the plan.
4 ADDITIONAL PACKAGE LISTS
Lets you include a list of additional packages in the plan. If you specify YES, a separate panel displays,
where you must enter the package location, collection name, and package name for each package to
include in the plan. This list is optional.
5 PLAN NAME
Lets you name the application plan to create. You can specify a name from 1 to 8 characters, and
the first character must be alphabetic. If there are no errors, the bind process prepares the plan and
enters its description into the EXPLAIN table.
If you reached this panel through the Db2 Program Preparation panel, the default for this field
depends on the value you entered in the INPUT DATA SET NAME field of that panel.
If you reached this panel directly from the Db2 Primary Option Menu, you must include a plan name if
you want to create an application plan. The default name for this field depends on the input data set:
• If the input data set is partitioned, the default name is the member name.
• If the input data set is sequential, the default name is the second qualifier of the data set name.
6 CHANGE CURRENT DEFAULTS?
Lets you specify whether to change the current defaults for binding plans. If you enter YES in this field,
you see the Defaults for Bind Plan panel as your next step. You can enter your new preferences there.
7 ENABLE/DISABLE CONNECTIONS?
Lets you specify whether you want to enable and disable system connections types to use with this
package. This is valid only if the LOCATION NAME field names your local Db2 system.
Placing YES in this field displays a panel (shown in Figure 54 on page 922) that lets you specify
whether various system connections are valid for this application. You can specify connection names
916 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Related reference
Defaults for Bind Plan and Defaults for Rebind Plan panels
These DB2I panels let you change your defaults for BIND PLAN and REBIND PLAN options.
BIND and REBIND options for packages, plans, and services (Db2 Commands)
Defaults for Bind Package and Defaults for Rebind Package panels
These DB2I panels lets you change your defaults for BIND PACKAGE and REBIND PACKAGE options.
On the following panel, enter new defaults for binding a package.
1 ISOLATION LEVEL ......... ===> (SAME, CS, RR, RS, UR, or NC)
2 PLAN VALIDATION TIME .... ===> (SAME, RUN, or BIND)
3 RESOURCE RELEASE TIME ... ===> (SAME, DEALLOCATE, COMMIT,
or INHERITFROMPLAN)
4 EXPLAIN PATH SELECTION .. ===> (SAME, NO, or YES)
5 DATA CURRENCY ........... ===> (SAME, NO, or YES)
6 PARALLEL DEGREE ......... ===> (SAME, 1 or ANY)
7 REOPTIMIZE FOR INPUT VARS ===> (SAME, ALWAYS, NONE, ONCE, AUTO)
8 DEFER PREPARE ........... ===> (SAME, NO, YES,
or INHERITFROMPLAN)
9 KEEP DYNAMIC SQL
PAST COMMIT OR ROLLBACK. ===> (SAME, NO, or YES)
10 APPLICATION ENCODING ... ===> (SAME, Blank, ASCII, EBCDIC,
UNICODE, or ccsid)
11 OPTIMIZATION HINT ...... ===> > (Blank or 'hint-id')
12 IMMEDIATE WRITE ......... ===> (SAME, NO, YES,
or INHERITFROMPLAN)
13 DBPROTOCOL .............. ===> (blank, DRDA, or DRDACBF)
14 DYNAMIC RULES ........... ===> (SAME, RUN, BIND,
DEFINERUN, DEFINEBIND,
INVOKERUN or INVOKEBIND)
15 PLAN MANAGEMENT ......... ===> (DEFAULT, BASIC, EXTENDED, OFF)
16 ACCESS PATH REUSE ....... ===> (DEFAULT, ERROR, NONE, or WARN)
17 ACCESS PATH COMPARISON .. ===> (DEFAULT, ERROR, NONE, or WARN)
18 ACCESS PATH RETAIN DUPS . ===> (DEFAULT, NO, OR YES)
19 SYSTEM_TIME SENSITIVE ... ===> (SAME, NO, or YES)
20 BUSINESS_TIME SENSITIVE . ===> (SAME, NO, or YES)
21 ARCHIVE SENSITIVE ....... ===> (SAME, NO, or YES)
22 APPLICATION COMPATIBILITY ===> (SAME, DB2 funtion level,
V10R1, or V11R1)
-------------------------------------------------------------------------------
PRESS: ENTER to continue UP/DOWN to scroll RETURN to EXIT
The following table lists the fields on the Defaults for Bind Package and Defaults for Rebind Package
panels, and the corresponding bind and rebind options.
Table 149. Defaults for Bind Package and Defaults for Rebind Package panel fields and corresponding
bind or rebind options
Field name Bind or rebind option
ACCESS PATH COMPARISON APCOMPARE
ACCESS PATH RETAIN DUPS APRETAINDUP
ACCESS PATH REUSE APREUSE
APPLICATION COMPATIBILITY APPLCOMPAT
APPLICATION ENCODING ENCODING
ARCHIVE SENSITIVE ARCHIVESENSITIVE
BUSINESS_TIME SENSITIVE BUSTINESENSITIVE
DATA CURRENCY CURRENTDATA
DBPROTOCOL DBPROTOCOL
DEFER PREPARE DEFER and NODEFER
DYNAMIC RULES DYNAMICRULES
EXPLAIN PATH SELECTION EXPLAIN
IMMEDIATE WRITE IMMEDWRITE
918 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 149. Defaults for Bind Package and Defaults for Rebind Package panel fields and corresponding
bind or rebind options (continued)
Field name Bind or rebind option
ISOLATION LEVEL ISOLATION
KEEP DYNAMIC SQL PAST COMMIT OR ROLLBACK KEEPDYNAMIC
OPTIMIZATION HINT OPTHINT
PARALLEL DEGREE DEGREE
PLAN MANAGEMENT PLANMGMT
REOPTIMIZE FOR INPUT VARS REOPT
RESOURCE RELEASE TIME RELEASE
SQLERROR PROCESSING SQLERROR
SYSTEM_TIME SENSITIVE SYSTIMESENSITIVE
VALIDATION TIME and PLAN VALIDATION TIME VALIDATE
Related concepts
Dynamic rules options for dynamic SQL statements
The DYNAMICRULES bind option and the runtime environment determine the rules for the dynamic SQL
attributes.
Parallel processing (Db2 Performance)
Investigating SQL performance by using EXPLAIN (Db2 Performance)
Related tasks
Setting the isolation level of SQL statements in a REXX program
Isolation levels specify the locking behavior for SQL statements. You can set the isolation level for SQL
statements in your REXX program to repeatable read (RR), read stability (RS), cursor stability (CS), or
uncommitted read (UR).
Related reference
BIND and REBIND options for packages, plans, and services (Db2 Commands)
Defaults for Bind Plan and Defaults for Rebind Plan panels
These DB2I panels let you change your defaults for BIND PLAN and REBIND PLAN options.
On the following panel, enter new defaults for binding a plan.
1 ISOLATION LEVEL ......... ===> SAME (SAME, RR, RS, CS, or UR)
2 PLAN VALIDATION TIME .... ===> SAME (SAME, RUN, or BIND)
3 RESOURCE RELEASE TIME ... ===> SAME (SAME, DEALLOCATE, COMMIT,
or INHERITFROMPLAN)
4 EXPLAIN PATH SELECTION .. ===> SAME (SAME, NO, or YES)
5 DATA CURRENCY ........... ===> SAME (SAME, NO, or YES)
6 PARALLEL DEGREE ......... ===> SAME (SAME, 1 or ANY)
7 REOPTIMIZE FOR INPUT VARS ===> SAME (SAME, ALWAYS, NONE, ONCE, AUTO)
8 DEFER PREPARE ........... ===> SAME (SAME, NO, YES,
or INHERITFROMPLAN)
9 KEEP DYNAMIC SQL
PAST COMMIT OR ROLLBACK.. ===> SAME (SAME, NO, or YES)
10 APPLICATION ENCODING ... ===> SAME (SAME,Blank,ASCII,EBCDIC,
UNICODE, or ccsid)
11 OPTIMIZATION HINT ...... ===> > (SAME, 'hint-id')
12 IMMEDIATE WRITE ........ ===> SAME (SAME, NO, YES,
or INHERITFROMPLAN)
13 SQLRULES ............... ===> SAME (SAME, DB2 or STD)
14 DYNAMIC RULES ........... ===> SAME (SAME, RUN, or BIND)
15 RESOURCE ACQUISITION TIME ===> SAME (SAME, ALLOCATE, or USE)
16 DISCONNECT .............. ===> SAME (SAME, EXPLICIT, AUTOMATIC,
or CONDITIONAL)
17 PROGRAM AUTHORIZATION ... ===> SAME (SAME, DISABLE, ENABLE)
The following table lists the fields on the Defaults for Bind Package and Defaults for Rebind Package, and
the corresponding bind and rebind options.
Table 150. Defaults for Bind Plan and Defaults for Rebind Plan panel fields and corresponding bind or
rebind options
Field name Bind or rebind option
APPLICATION ENCODING ENCODING
DATA CURRENCY CURRENTDATA
920 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 150. Defaults for Bind Plan and Defaults for Rebind Plan panel fields and corresponding bind or
rebind options (continued)
Field name Bind or rebind option
DBPROTOCOL DBPROTOCOL
DEFER PREPARE DEFER and NODEFER
DISCONNECT DISCONNECT
DYNAMIC RULES DYNAMICRULES
EXPLAIN PATH SELECTION EXPLAIN
IMMEDIATE WRITE IMMEDWRITE
ISOLATION LEVEL ISOLATION
KEEP DYNAMIC SQL PAST COMMIT OR ROLLBACK KEEPDYNAMIC
OPTIMIZATION HINT OPTHINT
PARALLEL DEGREE DEGREE
PROGRAM AUTHORIZATION PROGAUTH
REOPTIMIZE FOR INPUT VARS REOPT
RESOURCE ACQUISITION TIME ACQUIRE
RESOURCE RELEASE TIME RELEASE
VALIDATION TIME and PLAN VALIDATION TIME VALIDATE
Related concepts
Dynamic rules options for dynamic SQL statements
The DYNAMICRULES bind option and the runtime environment determine the rules for the dynamic SQL
attributes.
Parallel processing (Db2 Performance)
Investigating SQL performance by using EXPLAIN (Db2 Performance)
Related tasks
Caching authorization IDs for plans (Managing Security)
Setting the isolation level of SQL statements in a REXX program
Isolation levels specify the locking behavior for SQL statements. You can set the isolation level for SQL
statements in your REXX program to repeatable read (RR), read stability (RS), cursor stability (CS), or
uncommitted read (UR).
Specifying the rules that apply to SQL behavior at run time
You can specify whether Db2 rules or SQL standard rules apply to SQL behavior at run time.
To enable or disable connection types (that is, allow or prevent the connection from running the package
or plan), enter the following information.
1 ENABLE ALL CONNECTION TYPES?
Lets you enter an asterisk (*) to enable all connections. After that entry, you can ignore the rest of the
panel.
2 ENABLE/DISABLE SPECIFIC CONNECTION TYPES
Lets you specify a list of types to enable or disable; you cannot enable some types and disable others
in the same operation. If you list types to enable, enter E; that disables all other connection types. If
you list types to disable, enter D; that enables all other connection types.
For each connection type that follows, enter Y (yes) if it is on your list, N (no) if it is not. The
connection types are:
• BATCH for a TSO connection
• DB2CALL for a CAF connection
• RRSAF for an RRSAF connection
• CICS for a CICS connection
• IMS for all IMS connections: DLIBATCH, IMSBMP, and IMSMPP
• DLIBATCH for a DL/I Batch Support Facility connection
• IMSBMP for an IMS connection to a BMP region
• IMSMPP for an IMS connection to an MPP or IFP region
• REMOTE for all remote locations or no remote locations
For each connection type that has a second arrow, under SPECIFY CONNECTION NAMES?, enter Y if
you want to list specific connection names of that type. Leave N (the default) if you do not. If you use Y
in any of those fields, you see another panel on which you can enter the connection names.
If you use the DISPLAY command under TSO on this panel, you can determine what you have currently
defined as "enabled" or "disabled" in your ISPF DSNSPFT library (member DSNCONNS). The information
does not reflect the current state of the Db2 Catalog.
If you type DISPLAY ENABLED on the command line, you get the connection names that are currently
enabled for your TSO connection types. For example:
CONNECTION SUBSYSTEM
CICS1 ENABLED
CICS2 ENABLED
CICS3 ENABLED
CICS4 ENABLED
DLI1 ENABLED
DLI2 ENABLED
DLI3 ENABLED
922 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
DLI4 ENABLED
DLI5 ENABLED
Related reference
Panels for entering lists of values
Some fields in DB2I panels are associated with command keywords that accept multiple values. Those
fields lead you to a list panel that lets you enter or modify multiple values.
BIND and REBIND options for packages, plans, and services (Db2 Commands)
CMD
"""" value …
"""" value …
""""
""""
""""
""""
All of the list panels let you enter limited commands in two places:
• On the system command line, prefixed by ====>
• In a special command area, identified by """"
On the system command line, you can use:
END
Saves all entered variables, exits the table, and continues to process.
CANCEL
Discards all entered variables, terminates processing, and returns to the previous panel.
SAVE
Saves all entered variables and remains in the table.
In the special command area, you can use:
Inn
Insert nn lines after this one.
Dnn
Delete this and the following lines for nn lines.
Rnn
Repeat this line nn number of times.
The default for nn is 1.
When you finish with a list panel, specify END to same the current panel values and continue processing.
DSNEPP02 PROGRAM PREP: COMPILE, PRELINK, LINK, AND RUN SSID: DSN
COMMAND ===>_
Figure 56. The Program Preparation: Compile, Link, and Run panel
924 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
If you are preparing an IMS or CICS program, you must leave this field blank; you cannot use DB2I to
run IMS and CICS programs.
Use a slash (/) to separate the options for your run time processor from those for your program.
• For PL/I and Fortran, run time processor parameters must appear on the left of the slash, and the
application parameters must appear on the right.
• For COBOL, reverse this order. run time processor parameters must appear on the right of the slash,
and the application parameters must appear on the left.
• For assembler and C, there is no supported run time environment, and you need not use a slash to
pass parameters to the application program.
11 SYSIN DATA SET
Lets you specify the name of a SYSIN (or in Fortran, FT05F001) data set for your application program,
if it needs one. If you do not enclose the data set name in apostrophes, a standard TSO prefix (user
ID) and suffix is added to it. The default for this field is TERM.
If you are preparing an IMS or CICS program, you must leave this field blank; you cannot use DB2I to
run IMS and CICS programs.
12 SYSPRINT DS
Lets you specify the names of a SYSPRINT (or in Fortran, FT06F001) data set for your application
program, if it needs one. If you do not enclose the data set name in apostrophes, a standard TSO
prefix (user ID) and suffix is added to it. The default for this field is TERM.
If you are preparing an IMS or CICS program, you must leave this field blank; you cannot use DB2I to
run IMS and CICS programs.
Your application could need other data sets besides SYSIN and SYSPRINT. If so, remember to catalog and
allocate them before you run your program.
When you press ENTER after entering values in this panel, Db2 compiles and link-edits the application. If
you specified in the Db2 Program Preparation panel that you want to run the application, Db2 also runs
the application.
Related reference
Prelinking an application (z/OS Language Environment Programming Guide)
DB2I panels that are used to rebind and free plans and packages
A set of DB2I panels lets you bind, rebind, or free packages.
The following table describes additional panels that you can use to rebind and free packages and plans.
It also describes the Run panel, which you can use to run application programs that have already been
prepared.
Table 151. DB2I panels used to rebind and free plans and packages and used to Run application
programs
Panel Panel description
“Bind/Rebind/Free Selection The BIND/REBIND/FREE panel lets you select the BIND, REBIND, or
panel” on page 926 FREE, PLAN, PACKAGE, or TRIGGER PACKAGE process that you need.
“Rebind Package panel” on The Rebind Package panel lets you change options when you rebind a
page 927 package.
“Rebind Trigger Package The Rebind Trigger Package panel lets you change options when you
panel” on page 929 rebind a trigger package.
“Rebind Plan panel” on page The Rebind Plan panel lets you change options when you rebind an
930 application plan.
Related reference
DB2I panels that are used for program preparation
DB2I contains a set of panels that let you prepare an application for execution.
The DB2I primary option menu (Introduction to Db2 for z/OS)
926 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
4 BIND PACKAGE
Lets you build a package. If you select this option, the Bind Package panel displays. For more
information, see “Bind Package panel” on page 912.
5 REBIND PACKAGE
Lets you rebuild a package when changes to it affect the package but the SQL statements in the
program are the same. For example, you should rebind when you change authorizations, create a new
index that the package uses, or use RUNSTATS. If you select this option, the Rebind Package panel
displays. For more information, see “Rebind Package panel” on page 927.
6 REBIND TRIGGER PACKAGE
Lets you rebuild a trigger package when you need to change options for the package. When you
execute CREATE TRIGGER, Db2 binds a trigger package using a set of default options. You can use
REBIND TRIGGER PACKAGE to change those options. For example, you can use REBIND TRIGGER
PACKAGE to change the isolation level for the trigger package. If you select this option, the Rebind
Trigger Package panel displays. For more information, see “Rebind Trigger Package panel” on page
929.
7 FREE PACKAGE
Lets you delete a specific version of a package, all versions of a package, or whole collections of
packages from Db2. If you select this option, the Free Package panel displays. For more information,
see “Free Package panel” on page 932.
or
Enter package name(s) to be rebound:
2 LOCATION NAME ............. ===> (Defaults to local)
3 COLLECTION-ID ............. ===> > (Required)
4 PACKAGE-ID ................ ===> > (Required)
5 VERSION-ID ................ ===>
(*, Blank, (), or version-id)
6 ADDITIONAL PACKAGES? ...... ===> (Yes to include more packages)
928 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Rebind Trigger Package panel
The Rebind Trigger Package panel specifies options for rebinding a trigger package.
The following figure shows those options.
or
Enter trigger package name(s) to be rebound:
2 LOCATION NAME ............. ===> (Defaults to local)
3 COLLECTION-ID (SCHEMA NAME) ===> > (Required)
4 PACKAGE-ID (TRIGGER NAME).. ===> > (Required)
This panel lets you choose options for rebinding a trigger package.
1 Rebind all trigger packages
Lets you rebind all packages on the local DBMS. To do so, place an asterisk (*) in this field; otherwise,
leave it blank.
2 LOCATION NAME
Lets you specify where to bind the trigger package. If you specify a location name, you should use
from 1 to 16 characters, and you must have defined it in the catalog table SYSIBM.LOCATIONS.
3 COLLECTION-ID (SCHEMA NAME)
Lets you specify the collection of the trigger package to rebind. You must specify a collection ID from
1 to 128 characters, or an asterisk (*) to rebind all collections in the local Db2 system. You cannot use
the asterisk to rebind a remote collection. This field is scrollable.
4 PACKAGE-ID
Lets you specify the name of the trigger package to rebind. You must specify a package ID from 1 to
128 characters, or an asterisk (*) to rebind all trigger packages in the specified collections in the local
Db2 system. You cannot use the asterisk to rebind a remote trigger package. This field is scrollable.
5 ISOLATION LEVEL
Lets you specify how far to isolate your application from the effects of other running applications. The
default is the value used for the old trigger package.
6 RESOURCE RELEASE TIME
Lets you specify COMMIT or DEALLOCATE to tell when to release locks on resources. The default is
that used for the old trigger package.
7 EXPLAIN PATH SELECTION
Lets you specify YES or NO for whether to obtain EXPLAIN information about how SQL statements in
the package execute. The default is the value used for the old trigger package.
The bind process inserts information into the table owner.PLAN_TABLE, where owner is the
authorization ID of the plan or package owner. If you defined owner.DSN_STATEMNT_TABLE, Db2
also inserts information about the cost of statement execution into that table. If you specify YES in
930 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
DSNEBP03 REBIND PLAN SSID: DSN
COMMAND ===>_
This panel lets you specify options for rebinding your plan.
1 PLAN NAME
Lets you name the application plan to rebind. You can specify a name from 1 to 8 characters, and the
first character must be alphabetic. Do not begin the name with DSN, because it could create name
conflicts with Db2. If there are no errors, the bind process prepares the plan and enters its description
into the EXPLAIN table.
If you leave this field blank, the bind process occurs but produces no plan.
2 ADDITIONAL PLANS?
Lets you indicate whether to name more plans to rebind. Use YES to specify more plans on an
additional panel, described at “Panels for entering lists of values” on page 923. The default is NO.
3 CHANGE CURRENT DEFAULTS?
Lets you indicate whether to change the binding defaults. Use:
NO (default) to retain the binding defaults of the previous plan.
YES to change the binding defaults from the previous plan.
4 OWNER OF PLAN (AUTHID)
Lets you change the authorization ID for the plan owner. The owner must have the required privileges
to execute the SQL statements in the plan. The default is the existing plan owner.
The field is scrollable, and the maximum field length is 128.
5 QUALIFIER
Lets you specify the default schema for all unqualified table names, views, indexes, and aliases in the
plan. You can specify a schema name from 1 to 128 characters, which must conform to the rules for
the SQL identifier. The default is the authorization ID. This field is scrollable.
6 CACHESIZE
Lets you specify the size (in bytes) of the authorization cache. Valid values are in the range 0 to
4096. Values that are not multiples of 256 round up to the next highest multiple of 256. A value of 0
indicates that Db2 does not use an authorization cache. The default is the cache size specified for the
previous plan.
Each concurrent user of a plan requires 8 bytes of storage, with an additional 32 bytes for overhead.
7 ENABLE/DISABLE CONNECTIONS?
Lets you specify whether you want to enable and disable system connections types to use with this
plan. This is valid only for rebinding on your local Db2 system.
Placing YES in this field displays a panel (shown in Figure 54 on page 922) that lets you specify
whether various system connections are valid for this application.
The default is the values used for the previous plan.
or
Enter package name(s) to be freed:
2 LOCATION NAME ............. ===> (Defaults to local)
3 COLLECTION-ID ............. ===> > (Required)
4 PACKAGE-ID ................ ===> >(* to free all packages)
5 VERSION-ID ................ ===>
(*, Blank, (), or version-id)
6 ADDITIONAL PACKAGES?....... ===> (Yes to include more packages)
7 PLAN MANAGEMENT SCOPE ..... ===> ALL (ALL or INACTIVE)
932 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
1 Free ALL packages
Lets you free (erase) all packages for which you have authorization or to which you have BINDAGENT
authority. To do so, place an asterisk (*) in this field; otherwise, leave it blank.
2 LOCATION NAME
Lets you specify the location name of the DBMS to free the package. You can specify a name from 1 to
16 characters.
3 COLLECTION-ID
Lets you specify the collection from which you want to delete packages for which you own or have
BINDAGENT privileges. You can specify a name from 1 to 128 characters, or an asterisk (*) to free all
collections in the local Db2 system. You cannot use the asterisk to free a remote collection. This field
is scrollable.
4 PACKAGE-ID
Lets you specify the name of the package to free. You can specify a name from 1 to 128 characters, or
an asterisk (*) to free all packages in the specified collections in the local Db2 system. You cannot use
the asterisk to free a remote package. The name you specify must be in the Db2 catalog tables. This
field is scrollable.
5 VERSION-ID
Lets you specify the version of the package to free. You can specify an identifier from 1 to 64
characters, or an asterisk (*) to free all versions of the specified collections and packages in the local
Db2 system. You cannot use the asterisk to free a remote version.
6 ADDITIONAL PACKAGES?
Lets you indicate whether to name more packages to free. Use YES to specify more packages on an
additional panel, described in “Panels for entering lists of values” on page 923. The default is NO.
7 PLAN MANAGEMENT SCOPE
Specifies whether Db2 frees all copies of the package, or only the inactive previous and original
copies. This value corresponds to the PLANMGMTSCOPE option. The default value is ALL.
936 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
run time processor parameters / application parameters
• For COBOL, reverse this order. run time processor parameters must appear on the right of the slash,
and the application parameters must appear on the left.
• For assembler and C, there is no supported run time environment, and you need not use the slash to
pass parameters to the application program.
4 PLAN NAME
Lets you specify the name of the plan to which the program is bound. The default is the member name
of the program.
5 WHERE TO RUN
Lets you indicate whether to run in the foreground or background. You can also specify EDITJCL, in
which case you are able to edit the job control statement before you run the program. Use:
FOREGROUND to immediately run the program in the foreground with the specified values.
BACKGROUND to create and immediately submit to run a file containing a DSNH CLIST using the
JOB control statement from either DB2I Defaults Panel 2 or your site's SUBMIT exit. The program
runs in the background.
EDITJCL to create and open a file containing a DSNH CLIST in edit mode. You can then submit the
CLIST or save it. The program runs in the background.
Running command processors
To run a command processor (CP), use the following commands from the TSO ready prompt or as a
TSO TMP:
The RUN subcommand prompts you for more input. The end the DSN processor, use the END
command.
This sequence also works in ISPF option 6. You can package this sequence in a CLIST. Db2 does not
support access to multiple Db2 subsystems from a single address space.
The PARMS keyword of the RUN subcommand enables you to pass parameters to the run time processor
and to your application program:
Check your host language publications for the correct form of the PARMS option.
The SYSEXEC data set contains your REXX application, and the SYSTSIN data set contains the command
that you use to invoke the application.
ISPF
The Interactive System Productivity Facility (ISPF) helps you to construct and execute dialogs. Db2
includes a sample application that illustrates how to use ISPF through the call attachment facility (CAF).
Each scenario has advantages and disadvantages in terms of efficiency, ease of coding, ease of
maintenance, and overall flexibility.
938 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
under ISPF, so you cannot use these to pass control from load module to load module. Instead, use LINK,
XCTL, or LOAD.
The following figure shows the task control blocks that result from attaching the DSN command processor
below TSO or ISPF.
TSO or ISPF
ATTACH
DSN initialization
load module
Alias=DSN
ATTACH
Ordinary
DSN main load LINK
application
module
program
(See Note 2)
ATTACH
Application
command
processor
(See Note 1)
Notes:
1. The RUN command with the CP option causes DSN to attach your program and create a new TCB.
2. The RUN command without the CP option causes DSN to link to your program.
If you are in ISPF and running under DSN, you can perform an ISPLINK to another program, which calls a
CLIST. In turn, the CLIST uses DSN and another application. Each such use of DSN creates a separate unit
of recovery (process or transaction) in Db2.
All such initiated DSN work units are unrelated, with regard to isolation (locking) and recovery (commit).
It is possible to deadlock with yourself; that is, one unit (DSN) can request a serialized resource (a data
page, for example) that another unit (DSN) holds incompatibly.
A COMMIT in one program applies only to that process. There is no facility for coordinating the processes.
Related concepts
Dynamic SQL and the ISPF/CAF application (Db2 Installation and Migration)
Printing options for the sample application listings (Db2 Installation and Migration)
Sample applications supplied with Db2 for z/OS
Db2 provides sample applications to help you with Db2 programming techniques and coding practices
within each of the four environments: batch, TSO, IMS, and CICS. The sample applications contain various
applications that might apply to managing a company.
DSN command processor
DSN
RUN PROGRAM(MYPROG) PLAN(MYPLAN)
END
The application has one large load module and one plan.
Disadvantages: For large programs of this type, you want a more modular design, making the plan more
flexible and easier to maintain. If you have one large plan, you must rebind the entire plan whenever you
change a module that includes SQL statements. To achieve a more modular construction when all parts
of the program use SQL, consider using packages. See Chapter 9, “Preparing an application to run on Db2
for z/OS,” on page 833. You cannot pass control to another load module that makes SQL calls by using
ISPLINK; rather, you must use LINK, XCTL, or LOAD and BALR.
If you want to use ISPLINK, then call ISPF to run under DSN:
DSN
RUN PROGRAM(ISPF) PLAN(MYPLAN)
END
You then need to leave ISPF before you can start your application.
Furthermore, the entire program is dependent on Db2; if Db2 is not running, no part of the program can
begin or continue to run.
PGM(program-name) PARM(parameters)
CMD(command)
940 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
For a part that accesses Db2, the command can name a CLIST that starts DSN:
DSN
RUN PROGRAM(PART1) PLAN(PLAN1) PARM(input from panel)
END
Breaking the application into separate modules makes it more flexible and easier to maintain.
Furthermore, some of the application might be independent of Db2; portions of the application that do not
call Db2 can run, even if Db2 is not running. A stopped Db2 database does not interfere with parts of the
program that refer only to other databases.
Disadvantages: The modular application, on the whole, has to do more work. It calls several CLISTs,
and each one must be located, loaded, parsed, interpreted, and executed. It also makes and breaks
connections to Db2 more often than the single load module. As a result, you might lose some efficiency.
Procedure
To run a program using Db2, you need a Db2 plan.
The bind process creates the Db2 plan. Db2 first verifies whether the DL/I batch job step can connect to
Db2. Then Db2 verifies whether the application program can access Db2 and enforce user identification of
batch jobs accessing Db2.
The two ways to submit DL/I batch applications to Db2 are:
• DSNMTV01 can be specified as the application program name for the batch region. When this method
is used, control is given to DSNMTV01. When the Db2 environment is established, control is passed to
the application program.
• The application program name can be specified for the batch region. Control is given to DSNMTV01
directly to establish the external subsystem environment for Db2. When the Db2 environment is
established, control is passed to the application program that is specified in the batch region. To
accomplish this, in the batch region startup procedure in your application JCL, specify the following
information:
– MBR=application-name
– SSM=DB2-subsystem-name
Examples
Example: Submitting a DL/I batch application without using DSNMTV01
The skeleton JCL in the following example illustrates a COBOL application program, IVP8CP22, that
runs using Db2 DL/I batch support.
Related concepts
Input and output data sets for DL/I batch jobs
DL/I batch jobs require an input data set with DD name DDITV02 and an output data set with DD name
DDOTV02.
942 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Restarting a batch program
To restart a batch program that updates data, first run the IMS Batch Backout utility, followed by a restart
job indicating the last successful checkpoint ID.
Examples
Example: Batch checkout with JCL
The skeleton JCL example that follows illustrates a batch backout for PSB=IVP8CA.
Procedure
To run a stored procedure from the command line processor:
944 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
1. Invoke the command line processor and connect to the appropriate Db2 subsystem. For more
information about how to perform these tasks, see The Db2 command line processor (Db2
Commands).
2. Specify the CALL statement in the form that is acceptable for the command line processor.
Related tasks
Calling a stored procedure from your application
To run a stored procedure, you can either call it from a client program or invoke it from the command line
processor.
Implementing Db2 stored procedures (Db2 Administration Guide)
234
parameter
Notes:
1 If you specify an unqualified stored procedure name, Db2 searches the schema list in the CURRENT
PATH special register. Db2 searches this list for a stored procedure with the specified number of input
and output parameters.
2 Specify a question mark (?) as a placeholder for each output parameter.
3 For non-numeric, BLOB, or CLOB input parameters, enclose each value in single quotation marks (').
The exception is if the data is a BLOB or CLOB value that is to be read from a file. In that case, use the
notation file://fully qualified file name.
4 Specify the input and output parameters in the order that they are specified in the signature for the
stored procedure.
Examples
Example1
Assume that the TEST.DEPT_MEDIAN stored procedure was created with the following statement:
To invoke the stored procedure from the command line processor, you can specify the following CALL
statement:
CALL TEST.DEPT_MEDIAN(51, ?)
Assume that the stored procedure returns a value of 25,000. The following information is displayed by
the command line processor:
Example 2
Suppose that stored procedure TEST.BLOBSP is defined with one input parameter of type BLOB and
one output parameter. You can invoke this stored procedure from the command line processor with
the following statement:
The command line processor reads the contents from /tmp/photo.bmp as the input parameter.
Alternatively, you can invoke this stored procedure by specifying the input parameter in the CALL
statement itself, as in the following example:
CALL TEST.BLOBSP('abcdef',?)
• The JOB option identifies this as a job card. The USER option specifies the Db2 authorization ID of the
user.
• The EXEC statement calls the TSO Terminal Monitor Program (TMP).
• The STEPLIB statement specifies the library in which the DSN Command Processor load modules and
DSNHDECP or a user-specified application defaults module reside. It can also reference the libraries in
which user applications, exit routines, and the customized DSNHDECP module reside. The customized
DSNHDECP module is created during installation.
• Subsequent DD statements define additional files that are needed by your program.
• The DSN command connects the application to a particular Db2 subsystem.
• The RUN subcommand specifies the name of the application program to run.
• The PLAN keyword specifies plan name.
• The LIB keyword specifies the library that the application should access.
• The PARMS keyword passes parameters to the run time processor and the application program.
• END ends the DSN command processor.
Usage notes
• Keep DSN job steps short.
• Recommendation: Do not use DSN to call the EXEC command processor to run CLISTs that contain
ISPEXEC statements; results are unpredictable.
• If your program abends or gives you a non-zero return code, DSN terminates.
• You can use a group attachment or subgroup attachment name instead of a specific ssid to connect to a
member of a data sharing group.
Related tasks
Running TSO application programs (Db2 Administration Guide)
946 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Related reference
Executing the terminal monitor program (TSO/E Customization)
DSN (TSO) (Db2 Commands)
Procedure
To analyze the data needs of your application:
Because the application does not change any data in the DSN8C10.DEPT table, you can base the view
on the table itself (rather than on a test table). However, a safer approach is to have a complete set of
test tables and to test the program thoroughly using only test data.
950 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Authorization for test tables and applications
Before you can create a table, you need to be authorized to create tables and to use the table space in
which the table is to reside. You must also have authority to bind and run programs that you want to test.
Your DBA can grant you the necessary authorization to create and access tables and to bind and run
programs.
If you intend to use existing tables and views (either directly or as the basis for a view), you need
privileges to access those tables and views. Your DBA can grant those privileges.
To create a view, you must have authorization for each table and view on which you base the view. You
then have the same privileges over the view that you have over the tables and views on which you based
the view. Before trying the examples, have your DBA grant you the privileges to create new tables and
views and to access existing tables. Obtain the names of tables and views that you are authorized to
access (as well as the privileges you have for each table) from your DBA.
Related reference
CREATE DATABASE (Db2 SQL)
CREATE STOGROUP (Db2 SQL)
CREATE TABLE (Db2 SQL)
CREATE TABLESPACE (Db2 SQL)
Chapter 11. Testing and debugging an application program on Db2 for z/OS 951
Populating the test tables with data
To populate test tables, use SQL INSERT statements or the LOAD utility.
952 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Test with the command line processor: You can use the command line processor to test SQL statements
from UNIX System Services on z/OS.
SQL statements that are executed under SPUFI or the command line processor operate on actual tables
(in this case, the tables that you created for testing). Consequently, before you access Db2 data:
• Make sure that all tables and views that your SQL statements refer to exist.
• If the tables or views do not exist, create them (or have your database administrator create them). You
can use SPUFI or the command line processor to issue the CREATE statements that are used to create
the tables and views that you need for testing.
Related concepts
The Db2 command line processor (Db2 Commands)
Related tasks
Executing SQL by using SPUFI
You can execute SQL statements dynamically in a TSO session by using the SPUFI (SQL processor using
file input) facility.
Procedure
To execute SQL by using SPUFI:
1. Open SPUFI and specify the initial options. To open SPUFI and specify initial options:
a) Select SPUFI from the DB2I Primary Option Menu as shown in The DB2I primary option menu
(Introduction to Db2 for z/OS).
The SPUFI panel is displayed.
b) Specify the input data set name and output data set name.
An example of a SPUFI panel in which an input data set and output data set have been specified is
shown in the following figure.
Chapter 11. Testing and debugging an application program on Db2 for z/OS 953
DSNESP01 SPUFI SSID: DSN
===>
Enter the input data set name: (Can be sequential or partitioned)
1 DATA SET NAME..... ===> EXAMPLES(XMP1)
2 VOLUME SERIAL..... ===> (Enter if not cataloged)
3 DATA SET PASSWORD. ===> (Enter if password protected)
Enter the output data set name: (Must be a sequential data set)
4 DATA SET NAME..... ===> RESULT
Consider the following rules and recommendations when editing this input data set:
• Indent your lines and enter your statements on several lines to make your statements easier
to read. Entering your statements on multiple lines does not change how your statements are
processed.
• Do not put more than one SQL statement on a single line. If you do, the first statement executes,
but Db2 ignores the other SQL statements on the same line. You can put more than one SQL
statement in the input data set. Db2 executes the statements in the order in which you placed
them in the data set.
954 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
• If the length of an SQL statement is greater than 71 bytes for an input data set with record
length 79, or 72 bytes for an input data set with record length 80, you need to continue the
SQL statement on additional lines of the SPUFI input data set. SPUFI concatenates the text on
multiple lines without adding extra spaces at the end of any line. Therefore, if an SQL statement
contains two values with a space between them, and the first value ends at the last allowed input
position (71 or 72), you need to add an extra space on the next line before the second value.
For example, suppose that the record length of your SPUFI input data set is 80, so the maximum
length of an input line is 72. Also suppose that the SQL statement that you wish to enter is
81 bytes long. Bytes 69 through 81 contain FROM MYTABLE;. If you split the SQL statement
after FROM, the first line of the statement ends in column 72, so you need to include a space in
column 1 of the next line, before MYTABLE;. Otherwise, when SPUFI concatenates the two lines,
the result is FROMMYTABLE;. When SPUFI runs the SQL statement, the SQL statement fails with
SQLCODE -104.
• End each SQL statement with the statement terminator that you specified on the CURRENT SPUFI
DEFAULTS panel.
• Save the data set every 10 minutes or so by entering the SAVE command.
c) Press the END PF key.
The data set is saved, and the SPUFI panel is displayed.
4. Process SQL statements with SPUFI.
You can use SPUFI to submit the SQL statements in a data set to Db2. To process SQL statements by
using SPUFI:
a) On the SPUFI panel, specify YES in the EXECUTE field.
b) If you did not just finish using the EDIT panel to edit the input data set as described in "Entering
SQL statements in SPUFI," specify NO In the EDIT INPUT field.
c) Press Enter.
SPUFI passes the input data set to Db2 for processing. Db2 executes the SQL statement in the
input data set and sends the output to the output data set.
The output data set opens.
Your SQL statement might take a long time to execute, depending on how large a table Db2 must
search, or on how many rows Db2 must process. In this case, you can interrupt the processing
by pressing the PA1 key. Then respond to the message that asks you if you really want to stop
processing. This action cancels the executing SQL statement. Depending on how much of the input
data set Db2 was able to process before you interrupted its processing, Db2 might not have opened
the output data set yet, or the output data set might contain all or part of the results data that are
produced so far.
Results
SQL statements that exceed resource limit thresholds
Your system administrator might use the Db2 resource limit facility (governor) to set time limits for
processing SQL statements in SPUFI. Those limits can be error limits or warning limits.
If you execute an SQL statement through SPUFI that runs longer than this error time limit, SPUFI
terminates processing of that SQL statement and all statements that follow in the SPUFI input data
set. SPUFI displays a panel that lets you commit or roll back the previously uncommitted changes that
you have made. That panel is shown in the following figure.
Chapter 11. Testing and debugging an application program on Db2 for z/OS 955
DSNESP04 SQL STATEMENT RESOURCE LIMIT EXCEEDED SSID: DSN
===>
Statement text
Your SQL statement has exceeded the resource utilization threshold set
by your site administrator.
You must ROLLBACK or COMMIT all the changes made since the last COMMIT.
SPUFI processing for the current input file will terminate immediately
after the COMMIT or ROLLBACK is executed.
If you execute an SQL statement through SPUFI that runs longer than the warning time limit for
predictive governing, SPUFI displays the SQL STATEMENT RESOURCE LIMIT EXCEEDED panel. On this
panel, you can tell Db2 to continue executing that statement, or stop processing that statement and
continue to the next statement in the SPUFI input data set. That panel is shown in the following figure.
Statement text
You can now either CONTINUE executing this statement or BYPASS the execution
of this statement. SPUFI processing for the current input file will continue
after the CONTINUE or BYPASS processing is completed.
Related tasks
Setting limits for system resource usage by using the resource limit facility (Db2 Performance)
Related reference
Using ISPF/PDF to Allocate Data Sets (z/OS ISPF User's Guide Vol II)
Related information
Lesson 1.1: Querying data interactively (Introduction to Db2 for z/OS)
956 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
The SPUFI panel
The SPUFI panel is the first panel that you need to fill out to run the SPUFI application.
After you complete any fields on the SPUFI panel and press Enter, those settings are saved. When the
SPUFI panel displays again, the data entry fields on the panel contain the values that you previously
entered. You can specify data set names and processing options each time the SPUFI panel is displayed,
as needed. Values that you do not change remain in effect.
The following descriptions explain the fields that are available on the SPUFI panel.
1,2,3 INPUT DATA SET NAME
Identify the input data set in fields 1 through 3. This data set contains one or more SQL statements
that you want to execute. Allocate this data set before you use SPUFI, if one does not already exist.
Consider the following rules:
• The name of the data set must conform to standard TSO naming conventions.
• The data set can be empty before you begin the session. You can then add the SQL statements by
editing the data set from SPUFI.
• The data set can be either sequential or partitioned, but it must have the following DCB
characteristics:
– A record format (RECFM) of either F or FB.
– A logical record length (LRECL) of either 79 or 80. Use 80 for any data set that the EXPORT
command of QMF did not create.
• Data in the data set can begin in column 1. It can extend to column 71 if the logical record length is
79, and to column 72 if the logical record length is 80. SPUFI assumes that the last 8 bytes of each
record are for sequence numbers.
If you use this panel a second time, the name of the data set you previously used displays in the
field DATA SET NAME. To create a new member of an existing partitioned data set, change only the
member name.
4 OUTPUT DATA SET NAME
Enter the name of a data set to receive the output of the SQL statement. You do not need to allocate
the data set before you do this.
If the data set exists, the new output replaces its content. If the data set does not exist, Db2 allocates
a data set on the device type specified on the CURRENT SPUFI DEFAULTS panel and then catalogs
the new data set. The device must be a direct-access storage device, and you must be authorized to
allocate space on that device.
Attributes required for the output data set are:
• Organization: sequential
• Record format: F, FB, FBA, V, VB, or VBA
• Record length: 80 to 32768 bytes, not less than the input data set
“Executing SQL by using SPUFI” on page 953 shows the simplest choice, entering RESULT. SPUFI
allocates a data set named userid.RESULT and sends all output to that data set. If a data set named
userid.RESULT already exists, SPUFI sends Db2 output to it, replacing all existing data.
5 CHANGE DEFAULTS
Enables you to change control values and characteristics of the output data set and format of your
SPUFI session. If you specify Y(YES) you can look at the SPUFI defaults panel. See “Changing SPUFI
defaults” on page 958 for more information about the values you can specify and how they affect
SPUFI processing and output characteristics. You do not need to change the SPUFI defaults for this
example.
6 EDIT INPUT
To edit the input data set, leave Y(YES) on line 6. You can use the ISPF editor to create a new member
of the input data set and enter SQL statements in it. (To process a data set that already contains a set
Chapter 11. Testing and debugging an application program on Db2 for z/OS 957
of SQL statements you want to execute immediately, enter N (NO). Specifying N bypasses the step 3
described in “Executing SQL by using SPUFI” on page 953.)
7 EXECUTE
To execute SQL statements contained in the input data set, leave Y(YES) on line 7.
SPUFI handles the SQL statements that can be dynamically prepared.
8 AUTOCOMMIT
To make changes to the Db2 data permanent, leave Y(YES) on line 8. Specifying Y makes SPUFI
issue COMMIT if all statements execute successfully. If all statements do not execute successfully,
SPUFI issues a ROLLBACK statement, which deletes changes already made to the file (back to the last
commit point).
If you specify N, Db2 displays the SPUFI COMMIT OR ROLLBACK panel after it executes the SQL in
your input data set. That panel prompts you to COMMIT, ROLLBACK, or DEFER any updates made by
the SQL. If you enter DEFER, you neither commit nor roll back your changes.
9 BROWSE OUTPUT
To look at the results of your query, leave Y(YES) on line 9. SPUFI saves the results in the output data
set. You can look at them at any time, until you delete or write over the data set.
10 CONNECT LOCATION
Specify the name of the database server, if applicable, to which you want to submit SQL statements.
SPUFI then issues a type 2 CONNECT statement to this server.
SPUFI is a locally bound package. SQL statements in the input data set can process only if the
CONNECT statement is successful. If the connect request fails, the output data set contains the
resulting SQL return codes and error messages.
Related reference
Characteristics of SQL statements in Db2 for z/OS (Db2 SQL)
COMMIT (Db2 SQL)
ROLLBACK (Db2 SQL)
Procedure
To change the SPUFI defaults:
1. On the SPUFI panel, specify YES in the CHANGE DEFAULTS field.
2. Press Enter.
The CURRENT SPUFI DEFAULTS panel opens. The following figure shows the initial default values.
958 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
DSNESP02 CURRENT SPUFI DEFAULTS SSID: DSN
===>
Enter the following to control your SPUFI session:
1 SQL TERMINATOR .. ===> ; (SQL Statement Terminator)
2 ISOLATION LEVEL ===> RR (RR=Repeatable Read, CS=Cursor Stability)
UR=Uncommitted Read)
3 MAX SELECT LINES ===> 250 (Maximum lines to be returned from a SELECT)
4 ALLOW SQL WARNINGS===> NO (Continue fetching after SQL warning)
5 CHANGE PLAN NAMES ===> NO (Change the plan names used by SPUFI)
6 SQL FORMAT ...... ===> SQL (SQL, SQLCOMNT, or SQLPL)
Output data set characteristics:
7 SPACE UNIT ...... ===> TRK (TRK or CYL)
8 PRIMARY SPACE ... ===> 5 (Primary space allocation 1-999)
9 SECONDARY SPACE . ===> 6 (Secondary space allocation 0-999)
10 RECORD LENGTH ... ===> 4092 (LRECL= logical record length)
11 BLOCKSIZE ....... ===> 4096 (Size of one block)
12 RECORD FORMAT.... ===> VB (RECFM= F, FB, FBA, V, VB, or VB)
13 DEVICE TYPE...... ===> SYSDA (Must be a DASD unit name)
Output format characteristics:
14 MAX NUMERIC FIELD ===> 33 (Maximum width for numeric field)
15 MAX CHAR FIELD .. ===> 80 (Maximum width for character field)
16 COLUMN HEADING .. ===> NAMES (NAMES, LABELS, ANY, or BOTH)
Results
Next, continue with one of the following tasks:
• If you want to add SQL statements to the input data set or edit the SQL statements in the input data set,
enter SQL statements in SPUFI.
• Otherwise if the input data set already contains the SQL statements that you want to execute, process
SQL statements with SPUFI.
Related reference
CURRENT SPUFI DEFAULTS panel
Chapter 11. Testing and debugging an application program on Db2 for z/OS 959
Use the CURRENT SPUFI DEFAULTS panel to specify SPUFI default values.
CURRENT SPUFI DEFAULTS - PANEL 2 panel
Use the CURRENT SPUFI DEFAULTS - PANEL 2 panel to specify default plan name information.
Use a character other than a semicolon if you plan to execute a statement that contains embedded
semicolons. For example, suppose you choose the character # as the statement terminator. Then a
CREATE TRIGGER statement with embedded semicolons looks like the following statement:
A CREATE PROCEDURE statement with embedded semicolons looks like the following statement:
Be careful to choose a character for the SQL terminator that is not used within the statement.
You can also set or change the SQL terminator within a SPUFI input data set by using the --#SET
TERMINATOR statement.
2 ISOLATION LEVEL
Specify the isolation level for your SQL statements.
3 MAX SELECT LINES
The maximum number of rows that a SELECT statement can return. To limit the number of rows
retrieved, enter an integer greater than 0.
960 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
4 ALLOW SQL WARNINGS
Enter YES or NO to indicate whether SPUFI will continue to process an SQL statement after receiving
SQL warnings:
YES
If a warning occurs when SPUFI executes an OPEN or FETCH for a SELECT statement, SPUFI
continues to process the SELECT statement.
NO
If a warning occurs when SPUFI executes an OPEN or FETCH for a SELECT statement, SPUFI stops
processing the SELECT statement. If SQLCODE +802 occurs when SPUFI executes a FETCH for a
SELECT statement, SPUFI continues to process the SELECT statement.
You can also specify how SPUFI pre-processes the SQL input by using the --#SET TOLWARN
statement.
5 CHANGE PLAN NAMES
If you enter YES in this field, you can change plan names on a subsequent SPUFI defaults panel,
DSNESP07. Enter YES in this field only if you are certain that you want to change the plan names that
are used by SPUFI. Consult with your Db2 system administrator if you are uncertain whether you want
to change the plan names. Using an invalid or incorrect plan name might cause SPUFI to experience
operational errors or it might cause data contamination.
6 SQL FORMAT
Specify how SPUFI pre-processes the SQL input before passing it to Db2. Select one of the following
options:
SQL
This is the preferred mode for SQL statements other than SQL procedural language. When you use
this option, which is the default, SPUFI collapses each line of an SQL statement into a single line
before passing the statement to Db2. SPUFI also discards all SQL comments.
SQLCOMNT
This mode is suitable for all SQL, but it is intended primarily for SQL procedural language
processing. When this option is in effect, behavior is similar to SQL mode, except that SPUFI does
not discard SQL comments. Instead, it automatically terminates each SQL comment with a line
feed character (hex 25), unless the comment is already terminated by one or more line formatting
characters. Use this option to process SQL procedural language with minimal modification by
SPUFI.
SQLPL
This mode is suitable for all SQL, but it is intended primarily for SQL procedural language
processing. When this option is in effect, SPUFI retains SQL comments and terminates each line of
an SQL statement with a line feed character (hex 25) before passing the statement to Db2. Lines
that end with a split token are not terminated with a line feed character. Use this mode to obtain
improved diagnostics and debugging of SQL procedural language.
You can also specify how SPUFI pre-processes the SQL input by using the --#SET SQLFORMAT
statement.
7 SPACE UNIT
Specify how space for the SPUFI output data set is to be allocated.
TRK
Track
CYL
Cylinder
8 PRIMARY SPACE
Specify how many tracks or cylinders of primary space are to be allocated.
9 SECONDARY SPACE
Specify how many tracks or cylinders of secondary space are to be allocated.
Chapter 11. Testing and debugging an application program on Db2 for z/OS 961
10 RECORD LENGTH
The record length must be at least 80 bytes. The maximum record length depends on the device type
you use. The default value allows a 32756-byte record.
Each record can hold a single line of output. If a line is longer than a record, the output is truncated,
and SPUFI discards fields that extend beyond the record length.
11 BLOCKSIZE
Follow the normal rules for selecting the block size. For record format F, the block size is equal to the
record length. For FB and FBA, choose a block size that is an even multiple of LRECL. For VB and VBA
only, the block size must be 4 bytes larger than the block size for FB or FBA.
12 RECORD FORMAT
Specify F, FB, FBA, V, VB, or VBA. FBA and VBA formats insert a printer control character after the
number of lines specified in the LINES/PAGE OF LISTING field on the DB2I Defaults panel. The record
format default is VB (variable-length blocked).
13 DEVICE TYPE
Specify a standard z/OS name for direct-access storage device types. The default is SYSDA. SYSDA
specifies that z/OS is to select an appropriate direct access storage device.
14 MAX NUMERIC FIELD
The maximum width of a numeric value column in your output. Choose a value greater than 0. The
default is 33.
15 MAX CHAR FIELD
The maximum width of a character value column in your output. DATETIME and GRAPHIC data strings
are externally represented as characters, and SPUFI includes their defaults with the default values for
character fields. Choose a value greater than 0. The IBM-supplied default is 250.
16 COLUMN HEADING
You can specify NAMES, LABELS, ANY, or BOTH for column headings.
• NAMES uses column names only.
• LABELS (default) uses column labels. Leave the title blank if no label exists.
• ANY uses existing column labels or column names.
• BOTH creates two title lines, one with names and one with labels.
Column names are the column identifiers that you can use in SQL statements. If an SQL statement has
an AS clause for a column, SPUFI displays the contents of the AS clause in the heading, rather than
the column name. You define column labels with LABEL statements.
Related concepts
Output from SPUFI
SPUFI formats and displays the output data set using the ISPF Browse program.
Related tasks
Changing SPUFI defaults
Before you execute SQL statements in SPUFI, you can change the default execution behavior, such as the
SQL terminator and the isolation level.
Executing SQL by using SPUFI
You can execute SQL statements dynamically in a TSO session by using the SPUFI (SQL processor using
file input) facility.
962 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
DSNESP07 CURRENT SPUFI DEFAULTS - PANEL 2 SSID: DSN
===>
Enter the following to control your SPUFI session:
1 CS ISOLATION PLAN ===> DSNESPCS (Name of plan for CS isolation level)
2 RR ISOLATION PLAN ===> DSNESPRR (Name of plan for RR isolation level)
3 UR ISOLATION PLAN ===> DSNESPUR (Name of plan for UR isolation level)
The following descriptions explain the information on the CURRENT SPUFI DEFAULTS - PANEL 2 panel.
1 CS ISOLATION PLAN
Specify the name of the plan that SPUFI uses when you specify an isolation level of cursor stability
(CS). By default, this name is DSNESPCS.
2 RR ISOLATION PLAN
Specify the name of the plan that SPUFI uses when you specify an isolation level of repeatable read
(RR). By default, this name is DSNESPRR.
3 UR ISOLATION PLAN
Specify the name of the plan that SPUFI uses when you specify an isolation level of uncommitted read
(UR). By default, this name is DSNESPUR.
4 BLANK CCSID ALERT
Indicate whether to receive message DSNE345I when the terminal CCSID setting is blank. A blank
terminal CCSID setting occurs when the terminal code page and character set cannot be queried or if
they are not supported by ISPF.
Recommendation: To avoid possible data contamination use the default setting of YES, unless you
are specifically directed by your Db2 system administrator to use NO.
Chapter 11. Testing and debugging an application program on Db2 for z/OS 963
Table 154. Invalid special characters for the SQL terminator
Hexadecimal
Name Character representation
blank X'40'
comma , X'5E'
double quote " X'7F'
left parenthesis ( X'4D'
right parenthesis ) X'5D'
single quote ' X'7D'
underscore _ X'6D'
Use a character other than a semicolon if you plan to execute a statement that contains embedded
semicolons. For example, suppose that you choose the character # as the statement terminator. In this
case, a CREATE TRIGGER statement with embedded semicolons looks like this:
Example
The following example activates and then deactivates toleration of SQL warnings:
964 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
• The executed SQL statement, copied from the input data set
• The results of executing the SQL statement.
• The SQLCODE, and if the execution is unsuccessful, the formatted SQLCA.
At the end of the data set are summary statistics that describe the processing of the input data set as a
whole.
For SELECT statements that are executed with SPUFI, the message "SQLCODE IS 100" indicates an
error-free result. If the message SQLCODE IS 100 is the only result, Db2 is unable to find any rows that
satisfy the condition that is specified in the statement.
For all other types of SQL statements that are executed with SPUFI, the message "SQLCODE IS 0"
indicates an error-free result.
Chapter 11. Testing and debugging an application program on Db2 for z/OS 965
• A null value is displayed as a series of hyphens (-).
• A ROWID, BLOB, BINARY, or VARBINARY column value is displayed in hexadecimal.
• A CLOB column value is displayed in the same way as a VARCHAR column value.
• A DBCLOB column value is displayed in the same way as a VARGRAPHIC column value.
• An XML column is displayed in the same way as a LOB column.
• A heading identifies each selected column, and is repeated at the top of each output page. The contents
of the heading depend on the value that you specified in the COLUMN HEADING field of the CURRENT
SPUFI DEFAULTS panel.
Procedure
To test a user-defined function by using the Debug Tool for z/OS, choose one of the following approaches:
• To use the Debug Tool interactively:
966 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
a) Compile the user-defined function with the TEST option.
This places information in the program that the Debug Tool uses.
b) Invoke the Debug Tool. One way to do that is to specify the Language Environment run time TEST
option. The TEST option controls when and how the Debug Tool is invoked. The most convenient
place to specify run time options is with the RUN OPTIONS clause of CREATE FUNCTION or ALTER
FUNCTION.
For example, suppose that you code this option:
TEST(ALL,*,PROMPT,JBJONES%SESSNA:)
This should be the first command that you enter from the terminal or include in your commands file.
• To use the Debug Tool in batch mode:
a) If you plan to use the Language Environment run time TEST option to invoke the Debug Tool,
compile the user-defined function with the TEST option.
This places information in the program that the Debug Tool uses during a debugging session.
b) Allocate a log data set to receive the output from the Debug Tool. Put a DD statement for the log
data set in the startup procedure for the stored procedures address space.
c) Enter commands in a data set that you want the Debug Tool to execute. Put a DD statement for that
data set in the startup procedure for the stored procedures address space. To define the data set
that contains the commands to the Debug Tool, specify its data set name or DD name in the TEST
run time option.
For example, this option tells the Debug Tool to look for the commands in the data set that is
associated with DD name TESTDD:
TEST(ALL,TESTDD,PROMPT,*)
This command directs output from your debugging session to the log data set you defined in step 2.
For example, if you defined a log data set with DD name INSPLOG in the start-up procedure for the
stored procedures address space, the first command should be:
Chapter 11. Testing and debugging an application program on Db2 for z/OS 967
– Specify the Language Environment run time TEST option. The most convenient place to do that is
in the RUN OPTIONS parameter of CREATE FUNCTION or ALTER FUNCTION.
– Put CEETEST calls in the user-defined function source code. If you use this approach for an
existing user-defined function, you must compile, link-edit, and bind the user-defined function
again. Then you must issue the STOP FUNCTION SPECIFIC and START FUNCTION SPECIFIC
commands to reload the user-defined function.
You can combine the Language Environment run time TEST option with CEETEST calls. For
example, you might want to use TEST to name the commands data set but use CEETEST calls to
control when the Debug Tool takes control.
You can combine the Language Environment run time TEST option with CEETEST calls. For example,
you might want to use TEST to name the commands data set but use CEETEST calls to control when
the Debug Tool takes control.
Related reference
CREATE FUNCTION (Db2 SQL)
Debug Tool for z/OS
968 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Debugging stored procedures
When debugging stored procedures, you might need to use different techniques than you would use for
regular application programs. For example, some commonly used debugging tools, such as TSO TEST, are
not available in the environment where stored procedures run.
Procedure
To debug a stored procedure, perform one or more of the following actions:
• Take one or more of the following general actions, which are appropriate in many situations with stored
procedures:
• Ensure that all stored procedures are written to handle any SQL errors.
• Debug stored procedures as stand-alone programs on a workstation.
If you have debugging tools on a workstation, consider doing most of your development and testing
on a workstation before installing a stored procedure on z/OS. This technique results in very little
debugging activity on z/OS.
• Record stored procedure debugging messages to a disk file or JES spool file.
• Store debugging information in a table. This technique is especially useful for remote stored
procedures.
• Use the DISPLAY command to view information about particular stored procedures, including
statistics and thread information.
• In the stored procedure that you are debugging, issue DISPLAY commands. You can view the
DISPLAY results in the SDSF output. The DISPLAY results can help you find information about the
started task that is associated with the address space for the WLM application environment.
• If necessary, use the STOP PROCEDURE command to stop calls to one or more problematic stored
procedures. You can restart them later.
• If your stored procedures address space has the CEEDUMP data set allocated, look at the diagnostic
information in the CEEDUMP output.
• For COBOL, C, and C++ stored procedures, use the Debug Tool for z/OS.
• For COBOL stored procedures, compile the stored procedure with the option TEST(SYM) if you want a
formatted local variable dump to be included in the CEEDUMP output.
• For native SQL procedures, external SQL procedures, and Java stored procedures, use the Unified
Debugger.
• For external stored procedures, consider taking one or both of the following actions:
• Use a driver application.
• Create or alter the stored procedure definition to include the PARAMETER STYLE SQL option. This
option enables the stored procedure to share any error information with the calling application.
Ensure that your procedure follows linkage conventions for stored procedures.
• If you changed a stored procedure or a startup JCL procedure for a WLM application environment,
determine whether you need to refresh the WLM environment. You must refresh the WLM environment
before certain stored procedure changes take effect.
Related tasks
Handling SQL conditions in an SQL procedure
In an SQL procedure, you can specify how the program should handle certain SQL errors and SQL
warnings.
Displaying information about stored procedures with Db2 commands (Db2 Administration Guide)
Refreshing WLM application environments for stored procedures (Db2 Administration Guide)
Implementing Db2 stored procedures (Db2 Administration Guide)
Related reference
Linkage conventions for external stored procedures
Chapter 11. Testing and debugging an application program on Db2 for z/OS 969
The linkage convention for a stored procedure can be either GENERAL, GENERAL WITH NULLS, or SQL.
These linkage conventions apply to only external stored procedures.
-START PROCEDURE (Db2) (Db2 Commands)
-STOP PROCEDURE (Db2) (Db2 Commands)
Related information
Db2 for z/OS Stored Procedures: Through the CALL and Beyond (IBM Redbooks)
Procedure
To debug stored procedures by using the Unified Debugger:
1. Set up the Unified Debugger by performing the following steps:
a) Ensure that job DSNTIJRT successfully created the stored procedures that provide server support
for the Unified Debugger. This job is run during the installation and migration process. The stored
procedures that this job creates must run in WLM environments.
Recommendation: Initially, define and use the Db2 core WLM environment DSNWLM_GENERAL
to run the SYSPROC.DBG_RUNSESSIONMANAGER stored procedure and core WLM environment
DSNWLM_DEBUGGER to run the other stored procedures for Unified Debugger.
b) Define the debug mode characteristics for the stored procedure that you want to debug by
completing one of the following actions:
• For native SQL procedures, define the procedures with the ALLOW DEBUG MODE option and the
WLM ENVIRONMENT FOR DEBUG MODE option. If the procedure already exists, you can use the
ALTER PROCEDURE statement to specify these options.
• For an external SQL procedure, use DSNTPSMP to build the SQL procedure with the
BUILD_DEBUG option.
• If you deploy the procedure with Db2 Developer Extension, specify Enable debugging in the
deployment options.
• For Java stored procedures, define the procedures with the ALLOW DEBUG MODE option, select
an appropriate WLM environment for Java debugging, and compile the Java code with the -G
option.
c) Grant the DEBUGSESSION privilege to the user who runs the debug client.
2. Include breakpoints in your routines or executable files.
3. Follow the instructions for debugging stored procedures in the information for IBM Data Studio.
Related concepts
Java stored procedures and user-defined functions (Db2 Application Programming for Java)
Related tasks
Creating an external SQL procedure by using DSNTPSMP
The SQL procedure processor, DSNTPSMP, is one of several methods that you can use to create and
prepare an external SQL procedure. DSNTPSMP is a REXX stored procedure that you can invoke from your
application program.
Developing database routines (IBM Data Studio, IBM Optim Database Administrator, IBM infoSphere Data
Architect, IBM Optim Development Studio)
970 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Installing the Unified Debugger session manager on a z/OS system (Db2 Installation and Migration)
Related reference
Sample programs to help you prepare and run external SQL procedures
Db2 provides sample jobs to help you prepare and run external SQL procedures. All samples are in data
set DSN1210.SDSNSAMP. Before you can run the samples, you must customize them for your installation.
ALTER PROCEDURE (SQL - native) (Db2 SQL)
CREATE PROCEDURE (SQL - native) (Db2 SQL)
Related information
Db2 for z/OS Stored Procedures: Through the CALL and Beyond (IBM Redbooks)
Procedure
To debug your stored procedure using the Debug Tool:
1. Compile the stored procedure with option TEST. This places information in the program that the Debug
Tool uses during a debugging session.
2. Invoke the Debug Tool. One way to do that is to specify the Language Environment run time option
TEST. The TEST option controls when and how the Debug Tool is invoked. The most convenient place
to specify run time options is in the RUN OPTIONS parameter of the CREATE PROCEDURE or ALTER
PROCEDURE statement for the stored procedure.
For example, you can code the TEST option using the following parameters:
TEST(ALL,*,PROMPT,JBJONES%SESSNA:)
The following table lists the effects that each parameter has on the Debug Tool:
Table 155. Effects of the TEST option parameters on the Debug Tool
Parameter value Effect on the Debug Tool
ALL The Debug Tool gains control when an attention
interrupt, ABEND, or program or Language
Environment condition of Severity 1 and above
occurs.
Debug commands will be entered from the
terminal.
Chapter 11. Testing and debugging an application program on Db2 for z/OS 971
This command saves a log of your debugging session to a file on the workstation called dbgtool.log.
This should be the first command that you enter from the terminal or include in your commands file.
Results
Using Debug Tool in batch mode: To test your stored procedure in batch mode, you must have the Debug
Tool installed on the z/OS system where the stored procedure runs. To debug your stored procedure in
batch mode using the Debug Tool, complete the following steps:
• Compile the stored procedure with option TEST, if you plan to use the Language Environment run time
option TEST to invoke the Debug Tool. This places information in the program that the Debug Tool uses
during a debugging session.
• Allocate a log data set to receive the output from the Debug Tool. Put a DD statement for the log data
set in the start-up procedure for the stored procedures address space.
• Enter commands in a data set that you want the Debug Tool to execute. Put a DD statement for that data
set in the start-up procedure for the stored procedures address space. To define the commands data set
to the Debug Tool, specify the commands data set name or DD name in the TEST run time option. For
example, to specify that the Debug Tool use the commands that are in the data set that is associated
with the DD name TESTDD, include the following parameter in the TEST option:
TEST(ALL,TESTDD,PROMPT,*)
This command directs output from your debugging session to the log data set that you defined in
the previous step. For example, if you defined a log data set with DD name INSPLOG in the stored
procedures address space start-up procedure, the first command should be the following command:
• Invoke the Debug Tool. The following are two possible methods for invoking the Debug Tool:
– Specify the run time option TEST. The most convenient place to do that is in the RUN OPTIONS
parameter of the CREATE PROCEDURE or ALTER PROCEDURE statement for the stored procedure.
– Put CEETEST calls in the stored procedure source code. If you use this approach for an existing
stored procedure, you must recompile, re-link, and bind it, and issue the STOP PROCEDURE and
START PROCEDURE commands to reload the stored procedure.
You can combine the run time option TEST with CEETEST calls. For example, you might want to use
TEST to name the commands data set but use CEETEST calls to control when the Debug Tool takes
control.
Related reference
Debug Tool for z/OS
Procedure
To record stored procedure debugging messages in a file:
1. Specify the Language Environment (LE) MSGFILE run time option for the stored procedure. This option
identifies where LE is to write the debugging messages. To specify this option, include the RUN
OPTIONS clause in either the CREATE PROCEDURE statement or an ALTER PROCEDURE statement.
972 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Specify the following MSGFILE parameters:
• Use the first MSGFILE parameter to specify the JCL DD statement that identifies the data set for the
debugging messages. You can direct debugging messages to a disk file or JES spool file. To prevent
multiple procedures from sharing a data set, ensure that you specify a unique DD statement.
• Use the ENQ option to serialize I/O to the message file. This action is necessary, because multiple
TCBs can be active in the stored procedure address space. Alternatively, if you debug your
applications infrequently or on a Db2 test system, you can serialize I/O by temporarily running the
stored procedures address space with NUMTCB=1 in the stored procedures address space start-up
procedure.
2. For each instance of MSGFILE that you specify, add a DD statement to the JCL procedure that is used
to start the stored procedures address space.
Related reference
ALTER PROCEDURE (external) (Db2 SQL)
ALTER PROCEDURE (SQL - external) (deprecated) (Db2 SQL)
CREATE PROCEDURE (external) (Db2 SQL)
CREATE PROCEDURE (SQL - external) (deprecated) (Db2 SQL)
GRANT (system privileges) (Db2 SQL)
Using Language Environment MSGFILE (z/OS Language Environment Programming Guide)
Chapter 11. Testing and debugging an application program on Db2 for z/OS 973
Locating the problem in an application
If your program does not run correctly, you need to isolate the problem. You should check several items.
974 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Error and warning messages from the precompiler
In some circumstances, the statements that the Db2 precompiler generates might produce compiler or
assembly error messages. You need to know why the messages occur when you compile Db2-produced
source statements.
DSNH104I E DSNHPARS LINE 32 COL 26 ILLEGAL SYMBOL "X" VALID SYMBOLS ARE:, FROM1
SELECT VALUE INTO HIPPO X;2
Notes:
1. Error message.
2. Source SQL statement.
3. Summary statements of source statistics.
4. Summary statement of the number of errors that were detected.
5. Summary statement that indicates the number of errors that were detected but not printed. This
situation might occur if you specify a FLAG option other than I.
6. Storage requirement statement that indicates how many bytes of working storage that the Db2
precompiler actually used to process your source statements. That value helps you determine the
storage allocation requirements for your program.
7. Return code: 0 = success, 4 = warning, 8 = error, 12 = severe error, and 16 = unrecoverable error.
Chapter 11. Testing and debugging an application program on Db2 for z/OS 975
precompiler finishes, telling you where to find your precompiler listings. This helps you locate your
diagnostics quickly and easily.
The SYSPRINT output can provide information about your precompiled source module if you specify the
options SOURCE and XREF when you start the Db2 precompiler.
The format of SYSPRINT output is as follows:
• A list of the Db2 precompiler options that are in effect during the precompilation (if you did not specify
NOOPTIONS).
• A list of your source statements (only if you specified the SOURCE option). An example is shown in
Figure 73 on page 977.
• A list of the symbolic names used in SQL statements (this listing appears only if you specify the XREF
option). An example is show in Figure 74 on page 977.
• A summary of the errors that are detected by the Db2 precompiler and a list of the error messages that
are generated by the precompiler. An example is shown in
The following code shows an example list of Db2 precompiler options as it is displayed in the SYSPRINT
output.
Notes:
1. This section lists the options that are specified at precompilation time. This list does not appear if one
of the precompiler option is NOOPTIONS.
2. This section lists the options that are in effect, including defaults, forced values, and options that you
specified. The Db2 precompiler overrides or ignores any options that you specify that are inappropriate
for the host language.
The following figure shows an example list of source statements as it is displayed in the SYSPRINT output.
976 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
DB2 SQL PRECOMPILER TMN5P40:PROCEDURE OPTIONS (MAIN): PAGE 2
Notes:
• The left column of sequence numbers, which the Db2 precompiler generates, is for use with the symbol
cross-reference listing, the precompiler error messages, and the BIND error messages.
• The right column shows sequence numbers that come from the sequence numbers that are supplied
with your source statements.
The following figure shows an example list of symbolic names as it is displayed in the SYSPRINT output.
...
Notes:
DATA NAMES
Identifies the symbolic names that are used in source statements. Names enclosed in double
quotation marks (") or apostrophes (') are names of SQL entities such as tables, columns, and
authorization IDs. Other names are host variables.
DEFN
Is the number of the line that the precompiler generates to define the name. **** means that the
object was not defined, or the precompiler did not recognize the declarations.
Chapter 11. Testing and debugging an application program on Db2 for z/OS 977
REFERENCE
Contains two kinds of information: the symbolic name, which the source program defines, and which
lines refer to the symbolic name. If the symbolic name refers to a valid host variable, the list also
identifies the data type or the word STRUCTURE.
The following code shows an example summary report of errors as it is displayed in the SYSPRINT output.
SOURCE STATISTICS
SOURCE LINES READ: 15231
NUMBER OF SYMBOLS: 1282
SYMBOL TABLE BYTES EXCLUDING ATTRIBUTES: 64323
Notes:
1. Summary statement that indicates the number of source lines.
2. Summary statement that indicates the number of symbolic names in the symbol table (SQL names and
host names).
3. Storage requirement statement that indicates the number of bytes for the symbol table.
4. Summary statement that indicates the number of messages that are printed.
5. Summary statement that indicates the number of errors that are detected but not printed. You might
get this statement if you specify the option FLAG.
6. Storage requirement statement that indicates the number of bytes of working storage that are actually
used by the Db2 precompiler to process your source statements.
7. Return code 0 = success, 4 = warning, 8 = error, 12 = severe error, and 16 = unrecoverable error.
8. Error messages (this example detects only one error).
978 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
The following example is a command procedure (CLIST) that runs a Db2 application named MYPROG
under TSO TEST, and sets an address stop at the entry to the program. The Db2 subsystem name in this
example is DB4.
PROC 0
TEST 'prefix.SDSNLOAD(DSN)' CP
DSN SYSTEM(DB4)
AT MYPROG.MYPROG.+0 DEFER
GO
RUN PROGRAM(MYPROG) LIBRARY('L186331.RUNLIB.LOAD(MYPROG)')
Related reference
TEST command (TSO/E Command Reference)
When your program encounters an error, it can pass all the required error information to a standard error
routine. Online programs can also send an error message to the originating logical terminal.
An interactive program also can send a message to the master terminal operator (MTO) operator giving
information about the termination of the program. To do that, the program places the logical terminal
name of the master terminal in an express PCB and issues one or more ISRT calls.
Some organizations run a BMP at the end of the day to list all the errors that occurred during the day. If
your organization does this, you can send a message by using an express PCB that has its destination set
for that BMP.
Batch Terminal Simulator: The Batch Terminal Simulator (BTS) enables you to test IMS application
programs. BTS traces application program DL/I calls and SQL statements, and it simulates data
communication functions. It can make a TSO terminal appear as an IMS terminal to the terminal operator,
which enables the user to interact with the application as though it were an online application. The user
can use any application program that is under the user's control to access any database (whether DL/I or
Db2) that is under the user's control. Access to Db2 databases requires BTS to operate in batch BMP or
TSO BMP mode.
Chapter 11. Testing and debugging an application program on Db2 for z/OS 979
Techniques for debugging programs in CICS
Documenting the errors that are identified during testing of a CICS application helps you investigate and
correct problems in the program.
The following information can be useful:
• The application plan name of the program
• The input data that is being processed
• The ID of the originating logical terminal
• The failing SQL statement and its function
• The contents of the SQLCA (SQL communication area) and, if your program accepts dynamic SQL
statements, the SQLDA (SQL descriptor area)
• The date and time of day
• Data that is peculiar to CICS that you should record
• Abend code and dump error messages
• Transaction dump, if produced
Using CICS facilities, you can have a printed error record; you can also print the SQLCA and SQLDA
contents.
980 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
EDF before execution
The following figure shows an example of an EDF screen before it executes an SQL statement. The names
of the key information fields on this panel are in boldface.
ENTER: CONTINUE
PF1 : UNDEFINED PF2 : UNDEFINED PF3 : UNDEFINED
PF4 : SUPPRESS DISPLAYS PF5 : WORKING STORAGE PF6 : USER DISPLAY
PF7 : SCROLL BACK PF8 : SCROLL FORWARD PF9 : STOP CONDITIONS
PF10: PREVIOUS DISPLAY PF11: UNDEFINED PF12: ABEND USER TASK
Chapter 11. Testing and debugging an application program on Db2 for z/OS 981
Specifies the length of the host variable.
• IND=indicator variable status number
Specifies the indicator variable that is associated with this particular host variable. A value of zero
indicates that no indicator variable exists. If the value for the selected column is null, Db2 puts a
negative value in the indicator variable for this host variable.
• DATA=host variable data
Specifies the data, displayed in hexadecimal format, that is associated with this host variable. If the
data exceeds what can display on a single line, three periods (...) appear at the far right to indicate that
more data is present.
ENTER: CONTINUE
PF1 : UNDEFINED PF2 : UNDEFINED PF3 : END EDF SESSION
PF4 : SUPPRESS DISPLAYS PF5 : WORKING STORAGE PF6 : USER DISPLAY
PF7 : SCROLL BACK PF8 : SCROLL FORWARD PF9 : STOP CONDITIONS
PF10: PREVIOUS DISPLAY PF11: UNDEFINED PF12: ABEND USER TASK
982 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
The OVAR (output host variables) section and its attendant fields are displayed only when the executing
statement returns output host variables.
The following figure contains the rest of the EDF output for this example.
ENTER: CONTINUE
PF1 : UNDEFINED PF2 : UNDEFINED PF3 : END EDF SESSION
PF4 : SUPPRESS DISPLAYS PF5 : WORKING STORAGE PF6 : USER DISPLAY
PF7 : SCROLL BACK PF8 : SCROLL FORWARD PF9 : STOP CONDITIONS
PF10: PREVIOUS DISPLAY PF11: UNDEFINED PF12: ABEND USER TASK
The attachment facility automatically displays SQL information while in the EDF mode. (You can start EDF
as outlined in the appropriate CICS application programmer's reference manual.) If this information is not
displayed, contact the person that is responsible for installing and migrating Db2.
Related concepts
Data types of columns
When you create a Db2 table, you define each column to have a specific data type. The data type of a
column determines what you can and cannot do with the column.
Indicator variables, arrays, and structures
An indicator variable is associated with a particular host variable. Each indicator variable contains a small
integer value that indicates some information about the associated host variable. Indicator arrays and
structures serve the same purpose for host-variable arrays and structures.
Related information
CICS debugging aids (CICS Transaction Server for z/OS)
Chapter 11. Testing and debugging an application program on Db2 for z/OS 983
If you use the SQLCA to check whether an SQL statement executed successfully, your program needs to
read the data in the appropriate SQLCA fields. One easy way to read these fields is to use the assembler
subroutine DSNTIAR.
984 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Chapter 12. Sample data and applications supplied
with Db2 for z/OS
You can use sample applications that are included with Db2 for z/OS to learn about how to program
applications that take advantage Db2 capabilities. Db2 also provides models for your own situations.
To prepare and run the supplied sample applications, use the JCL in prefix.SDSNSAMP as a model:
Related reference
Db2 sample tables (Introduction to Db2 for z/OS)
The sample storage group, databases, table spaces, tables, and views are created when you run the
installation sample jobs DSNTEJ1 and DSNTEJ7. Db2 sample objects that include LOBs are created in job
DSNTEJ7. All other sample objects are created in job DSNTEJ1. The CREATE INDEX statements for the
sample tables are not shown here; they, too, are created by the DSNTEJ1 and DSNTEJ7 sample jobs.
Authorization on all sample objects is given to PUBLIC in order to make the sample programs easier to
run. You can review the contents of any table by executing an SQL statement, for example SELECT * FROM
DSN8C10.PROJ. For convenience in interpreting the examples, the department and employee tables are
listed in full.
GUPI
Related concepts
Phase 1: Creating and loading sample tables (Db2 Installation and Migration)
The activity table resides in database DSN8D12A and is created with the following statement:
GUPI
The department table resides in table space DSN8D12A.DSN8S12D and is created with the following
statement:
Because the department table is self-referencing, and also is part of a cycle of dependencies, its foreign
keys must be added later with the following statements:
GUPI
986 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 158. Columns of the department table (continued)
Column Column name Description
2 DEPTNAME A name that describes the general activities of the
department.
3 MGRNO Employee number (EMPNO) of the department manager.
4 ADMRDEPT ID of the department to which this department reports; the
department at the highest level reports to itself.
5 LOCATION The remote location name.
The LOCATION column contains null values until sample job DSNTEJ6 updates this column with the
location name.
Chapter 12. Sample data and applications supplied with Db2 for z/OS 987
• The employee table, through a foreign key on column WORKDEPT
• The project table, through a foreign key on column DEPTNO
The department table is a dependent of the employee table, through its foreign key on column MGRNO.
GUPI
988 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 161. Columns of the employee table (continued)
Column Column name Description
11 BIRTHDATE Date of birth
12 SALARY Yearly salary in dollars
13 BONUS Yearly bonus in dollars
14 COMM Yearly commission in dollars
The following table shows the first half (left side) of the content of the employee table. (Table 164 on page
990 shows the remaining content (right side) of the employee table.)
Table 163. Left half of DSN8C10.EMP: employee table. Note that a blank in the MIDINIT column is an actual
value of " " rather than null.
EMPNO FIRSTNME MIDINIT LASTNAME WORKDEPT PHONENO HIREDATE
000010 CHRISTINE I HAAS A00 3978 1965-01-01
000020 MICHAEL L THOMPSON B01 3476 1973-10-10
000030 SALLY A KWAN C01 4738 1975-04-05
000050 JOHN B GEYER E01 6789 1949-08-17
000060 IRVING F STERN D11 6423 1973-09-14
000070 EVA D PULASKI D21 7831 1980-09-30
000090 EILEEN W HENDERSON E11 5498 1970-08-15
000100 THEODORE Q SPENSER E21 0972 1980-06-19
000110 VINCENZO G LUCCHESSI A00 3490 1958-05-16
000120 SEAN O'CONNELL A00 2167 1963-12-05
000130 DOLORES M QUINTANA C01 4578 1971-07-28
000140 HEATHER A NICHOLLS C01 1793 1976-12-15
000150 BRUCE ADAMSON D11 4510 1972-02-12
000160 ELIZABETH R PIANKA D11 3782 1977-10-11
000170 MASATOSHI J YOSHIMURA D11 2890 1978-09-15
000180 MARILYN S SCOUTTEN D11 1682 1973-07-07
000190 JAMES H WALKER D11 2986 1974-07-26
000200 DAVID BROWN D11 4501 1966-03-03
000210 WILLIAM T JONES D11 0942 1979-04-11
000220 JENNIFER K LUTZ D11 0672 1968-08-29
000230 JAMES J JEFFERSON D21 2094 1966-11-21
Chapter 12. Sample data and applications supplied with Db2 for z/OS 989
Table 163. Left half of DSN8C10.EMP: employee table. Note that a blank in the MIDINIT column is an actual
value of " " rather than null. (continued)
EMPNO FIRSTNME MIDINIT LASTNAME WORKDEPT PHONENO HIREDATE
000240 SALVATORE M MARINO D21 3780 1979-12-05
000250 DANIEL S SMITH D21 0961 1969-10-30
000260 SYBIL P JOHNSON D21 8953 1975-09-11
000270 MARIA L PEREZ D21 9001 1980-09-30
000280 ETHEL R SCHNEIDER E11 8997 1967-03-24
000290 JOHN R PARKER E11 4502 1980-05-30
000300 PHILIP X SMITH E11 2095 1972-06-19
000310 MAUDE F SETRIGHT E11 3332 1964-09-12
000320 RAMLAL V MEHTA E21 9990 1965-07-07
000330 WING LEE E21 2103 1976-02-23
000340 JASON R GOUNOT E21 5698 1947-05-05
200010 DIAN J HEMMINGER A00 3978 1965-01-01
200120 GREG ORLANDO A00 2167 1972-05-05
200140 KIM N NATZ C01 1793 1976-12-15
200170 KIYOSHI YAMAMOTO D11 2890 1978-09-15
200220 REBA K JOHN D11 0672 1968-08-29
200240 ROBERT M MONTEVERDE D21 3780 1979-12-05
200280 EILEEN R SCHWARTZ E11 8997 1967-03-24
200310 MICHELLE F SPRINGER E11 3332 1964-09-12
200330 HELENA WONG E21 2103 1976-02-23
200340 ROY R ALONZO E21 5698 1947-05-05
(Table 163 on page 989 shows the first half (right side) of the content of employee table.)
990 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 164. Right half of DSN8C10.EMP: employee table (continued)
(EMPNO) JOB EDLEVEL SEX BIRTHDATE SALARY BONUS COMM
(000140) ANALYST 18 F 1946-01-19 28420.00 600.00 2274.00
(000150) DESIGNER 16 M 1947-05-17 25280.00 500.00 2022.00
(000160) DESIGNER 17 F 1955-04-12 22250.00 400.00 1780.00
(000170) DESIGNER 16 M 1951-01-05 24680.00 500.00 1974.00
(000180) DESIGNER 17 F 1949-02-21 21340.00 500.00 1707.00
(000190) DESIGNER 16 M 1952-06-25 20450.00 400.00 1636.00
(000200) DESIGNER 16 M 1941-05-29 27740.00 600.00 2217.00
(000210) DESIGNER 17 M 1953-02-23 18270.00 400.00 1462.00
(000220) DESIGNER 18 F 1948-03-19 29840.00 600.00 2387.00
(000230) CLERK 14 M 1935-05-30 22180.00 400.00 1774.00
(000240) CLERK 17 M 1954-03-31 28760.00 600.00 2301.00
(000250) CLERK 15 M 1939-11-12 19180.00 400.00 1534.00
(000260) CLERK 16 F 1936-10-05 17250.00 300.00 1380.00
(000270) CLERK 15 F 1953-05-26 27380.00 500.00 2190.00
(000280) OPERATOR 17 F 1936-03-28 26250.00 500.00 2100.00
(000290) OPERATOR 12 M 1946-07-09 15340.00 300.00 1227.00
(000300) OPERATOR 14 M 1936-10-27 17750.00 400.00 1420.00
(000310) OPERATOR 12 F 1931-04-21 15900.00 300.00 1272.00
(000320) FIELDREP 16 M 1932-08-11 19950.00 400.00 1596.00
(000330) FIELDREP 14 M 1941-07-18 25370.00 500.00 2030.00
(000340) FIELDREP 16 M 1926-05-17 23840.00 500.00 1907.00
(200010) SALESREP 18 F 1933-08-14 46500.00 1000.00 4220.00
(200120) CLERK 14 M 1942-10-18 29250.00 600.00 2340.00
(200140) ANALYST 18 F 1946-01-19 28420.00 600.00 2274.00
(200170) DESIGNER 16 M 1951-01-05 24680.00 500.00 1974.00
(200220) DESIGNER 18 F 1948-03-19 29840.00 600.00 2387.00
(200240) CLERK 17 M 1954-03-31 28760.00 600.00 2301.00
(200280) OPERATOR 17 F 1936-03-28 26250.00 500.00 2100.00
(200310) OPERATOR 12 F 1931-04-21 15900.00 300.00 1272.00
(200330) FIELDREP 14 F 1941-07-18 25370.00 500.00 2030.00
(200340) FIELDREP 16 M 1926-05-17 23840.00 500.00 1907.00
Chapter 12. Sample data and applications supplied with Db2 for z/OS 991
The employee table is a dependent of the department table, through its foreign key on column
WORKDEPT.
Db2 requires an auxiliary table for each LOB column in a table. The following statements define the
auxiliary tables for the three LOB columns in DSN8C10.EMP_PHOTO_RESUME:
GUPI
The following table shows the indexes for the employee photo and resume table.
992 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
The following table shows the indexes for the auxiliary tables that support the employee photo and
resume table.
Table 167. Indexes of the auxiliary tables for the employee photo and resume table
Name On table Type of index
DSN8C10.XAUX_BMP_PHOTO DSN8C10.AUX_BMP_PHOTO Unique
DSN8C10.XAUX_PSEG_PHOTO DSN8C10.AUX_PSEG_PHOTO Unique
DSN8C10.XAUX_EMP_RESUME DSN8C10.AUX_EMP_RESUME Unique
Because the project table is self-referencing, the foreign key for that constraint must be added later with
the following statement:
GUPI
Chapter 12. Sample data and applications supplied with Db2 for z/OS 993
Table 168. Columns of the project table (continued)
Column Column name Description
4 RESPEMP ID of employee responsible for the project
5 PRSTAFF Estimated mean number of persons that are needed
between PRSTDATE and PRENDATE to complete the whole
project, including any subprojects
6 PRSTDATE Estimated project start date
7 PRENDATE Estimated project end date
8 MAJPROJ ID of any project of which this project is a part
The following table shows the indexes for the project table:
GUPI
994 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 170. Columns of the project activity table
Column Column name Description
1 PROJNO Project ID
2 ACTNO Activity ID
3 ACSTAFF Estimated mean number of employees that are needed to
staff the activity
4 ACSTDATE Estimated activity start date
5 ACENDATE Estimated activity completion date
The following table shows the index of the project activity table:
The employee-to-project activity table resides in database DSN8D12A. Because this table has foreign
keys that reference EMP and PROJACT, those tables and the indexes on their primary keys must be
created first. Then EMPPROJACT is created with the following statement:
GUPI
Chapter 12. Sample data and applications supplied with Db2 for z/OS 995
Table 172. Columns of the employee-to-project activity table
Column Column name Description
1 EMPNO Employee ID number
2 PROJNO Project ID of the project
3 ACTNO ID of the activity within the project
4 EMPTIME A proportion of the employee's full time (between 0.00 and
1.00) that is to be spent on the activity
5 EMSTDATE Date the activity starts
6 EMENDATE Date the activity ends
The following table shows the indexes for the employee-to-project activity table:
The table resides in database DSN8D12A, and is defined with the following statement:
GUPI
996 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 174. Columns of the Unicode sample table
Column Column Name Description
1 LOWER_A_TO_Z Array of characters, 'a' to 'z'
2 UPPER_A_TO_Z Array of characters, 'A' to 'Z'
3 ZERO_TO_NINE Array of characters, '0' to '9'
4 X00_TO_XFF Array of characters, x'00' to x'FF'
CASCADE
DEPT
SET SET
NULL NULL
RESTRICT EMP
RESTRICT
RESTRICT EMP_PHOTO_RESUME
RESTRICT
CASCADE ACT
PROJ RESTRICT
RESTRICT
PROJACT
RESTRICT
RESTRICT
EMPPROJACT
Related reference
Activity table (DSN8C10.ACT) (Introduction to Db2 for z/OS)
Department table (DSN8C10.DEPT) (Introduction to Db2 for z/OS)
Employee photo and resume table (DSN8C10.EMP_PHOTO_RESUME) (Introduction to Db2 for z/OS)
Employee table (DSN8C10.EMP) (Introduction to Db2 for z/OS)
Employee-to-project activity table (DSN8C10.EMPPROJACT) (Introduction to Db2 for z/OS)
Project activity table (DSN8C10.PROJACT) (Introduction to Db2 for z/OS)
Chapter 12. Sample data and applications supplied with Db2 for z/OS 997
Project table (DSN8C10.PROJ) (Introduction to Db2 for z/OS)
Unicode sample table (DSN8C10.DEMO_UNICODE) (Introduction to Db2 for z/OS)
VEMPDPT1 Organization
DEPT
EMP
VASTRDE1 DEPT
VASTRDE2 Organization
VDEPMG1
EMP
VPROJRE1 Project
PROJ
EMP
VPSTRDE1 Project
VPROJRE1
VPROJRE2
VSTAFAC1 Project
PROJACT
ACT
998 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 175. Views on sample tables (continued)
View name On tables or views Used in application
VSTAFAC2 Project
EMPPROJACT
ACT
EMP
VPHONE Phone
EMP
DEPT
GUPI
Chapter 12. Sample data and applications supplied with Db2 for z/OS 999
The following SQL statement creates the view named VEMPPROJACT.
The following figure shows the SQL statement that creates the view named VPROJRE1.
1000 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
AS SELECT ALL
P1.PROJNO,P1.PROJNAME,P1.RESPEMP,P1.FIRSTNME,P1.MIDINIT,
P1.LASTNAME,
P2.PROJNO,P2.PROJNAME,P2.RESPEMP,P2.FIRSTNME,P2.MIDINIT,
P2.LASTNAME
FROM DSN8C10.VPROJRE1 P1,
DSN8C10.VPROJRE1 P2
WHERE P1.PROJNO = P2.MAJPROJ ;
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1001
FROM DSN8C10.EMP, DSN8C10.DEPT
WHERE WORKDEPT = DEPTNO;
GUPI
Table
spaces:
Separate
spaces for LOB spaces DSN8Svr P
DSN8Svr D DSN8Svr E other for employee common for
department employee application photo and programming
table table tables resume table table
In addition to the storage group and databases that are shown in the preceding figure, the storage group
DSN8G12U and database DSN8D12U are created when you run DSNTEJ2A.
The storage group that is used to store sample application data is defined by the following statement:
GUPI
1002 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Databases for sample application data
Sample application data is stored in several different databases. The default database that is created
when Db2 is installed is not used to store the sample application data.
GUPI DSN8D12P is the database that is used for tables that are related to programs. The other
databases are used for tables that are related to applications. The databases are defined by the following
statements:
GUPI
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1003
CREATE TABLESPACE DSN8S12B
IN DSN8D12L
USING STOGROUP DSN8G120
PRIQTY 20
SECQTY 20
ERASE NO
LOCKSIZE PAGE
LOCKMAX SYSTEM
BUFFERPOOL BP0
CLOSE NO
CCSID EBCDIC;
1004 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
CLOSE NO
CCSID EBCDIC;
GUPI
SYSDUMMYx tables
Db2 for z/OS provides a set of SYSDUMMYx catalog tables.
GUPI
The last character of the table name identifies the associated encoding scheme as follows:
• SYSIBM.SYSDUMMY1 uses the EBCDIC encoding scheme.
• SYSIBM.SYSDUMMYE uses the EBCDIC encoding scheme.
• SYSIBM.SYSDUMMYA uses the ASCII encoding scheme.
• SYSIBM.SYSDUMMYU uses the UNICODE encoding scheme.
Although the SYSDUMMYx tables are implemented as catalog tables, they are similar to sample tables,
and are used in some examples in the Db2 for z/OS documentation.
You can use any of the SYSDUMMYx tables when you need to write a query, but no data from a table is
referenced. In any query, you must specify a table reference in the FROM clause, but if the query does not
reference any data from the table, it does not matter which table is referenced in the FROM clause. Each
of the SYSDUMMYx tables contains one row, so a SYSDUMMYx table can be referenced in a SELECT INTO
statement without the need for a predicate to limit the result to a single row of data.
For example, when you want to retrieve the value of a special register or global variable, you can use a
query that references a SYSDUMMYx table.
Sometimes when Db2 for z/OS processes an SQL statement, the statement is rewritten, and a reference
to a SYSDUMMYx table is added. For example, some of the internal rewrites that result in adding a
reference to a SYSDUMMYx table are for processing the search condition of a trigger, or the SQL PL control
statements IF, REPEAT, RETURN, or WHILE. In these situations, the privilege set must include the SELECT
privilege on the SYSDUMMYx table that is referenced.
GUPI
Related concepts
Objects with different CCSIDs in the same SQL statement (Db2 Internationalization Guide)
Related tasks
Avoiding character conversion for LOB locators
In certain situations, Db2 materializes the entire LOB value and converts it to the encoding scheme of a
particular SQL statement. This extra processing can degrade performance and should be avoided.
Related reference
SYSDUMMY1 catalog table (Db2 SQL)
SYSDUMMYA catalog table (Db2 SQL)
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1005
SYSDUMMYE catalog table (Db2 SQL)
SYSDUMMYU catalog table (Db2 SQL)
Table 176. Jobs that prepare DSNTIAUL, DSNTIAD, DSNTEP2, and DSNTEP4
Program name Program preparation job
DSNTIAUL DSNTEJ2A
DSNTIAD DSNTIJTM
DSNTEP2 (source) DSNTEJ1P
DSNTEP2 (object) DSNTEJ1L
DSNTEP4 (source) DSNTEJ1P
DSNTEP4 (object) DSNTEJ1L
1006 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Application compatibility for the productivity-aid sample programs
If you are ready for the productivity-aid sample programs to start using new application capabilities in
later Db2 12 function levels, you must rebind the packages for these programs with the corresponding
APPLCOMPAT option.
The Db2 12 jobs for preparing the productivity-aid sample programs bind the packages with
APPLCOMPAT(V12R1) by default, which is equivalent to APPLCOMPAT(V12R1M500).
For more information, see Controlling Db2 application compatibility (Db2 for z/OS What's New?) and
Function levels and related levels in Db2 12 (Db2 for z/OS What's New?).
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1007
For more information, see “Db2 productivity-aid sample programs” on page 1006.
For more information about the RUN command, see RUN (DSN) (Db2 Commands).
DSNTIAUL parameters
PKGSET(collection)
Specifies that DSNTIAUL implicitly executes a SET CURRENT PACKAGESET statement to assign a
value to the CURRENT PACKAGESET special register before processing the dynamic SQL statements
in SYSIN.
collection
The value to assign to the CURRENT PACKAGESET special register. You can specify up to 40
characters.
SQL
Specify SQL to indicate that your input data set contains one or more complete SQL statements,
each of which ends with a semicolon. You can include any SQL statement that can be executed
dynamically in your input data set. In addition, you can include the static SQL statements CONNECT,
SET CONNECTION, or RELEASE. Static SQL statements must be uppercase.
DSNTIAUL uses the SELECT statements to determine which tables to unload and dynamically
executes all other statements except CONNECT, SET CONNECTION, and RELEASE. DSNTIAUL
executes CONNECT, SET CONNECTION, and RELEASE statically to connect to remote locations.
number-of-rows-per-fetch
Specify a number from 1 to 32767 to specify the number of rows that DSNTIAUL retrieves for each
SQL FETCH operation. If you do not specify this number, DSNTIAUL retrieves 100 rows for each
FETCH. This parameter can be specified with the SQL parameter.
If the LOBFILE parameter is also specified, and the result set of a FETCH operation can contain NULL
LOB values, number-of-rows-per-fetch must be 1.
TOLWARN
Specify NO (the default) or YES to indicate whether DSNTIAUL continues to retrieve rows after
receiving an SQL warning:
(NO)
If a warning occurs when DSNTIAUL executes an OPEN or FETCH to retrieve rows, DSNTIAUL
stops retrieving rows. If the SQLWARN1, SQLWARN2, SQLWARN6, or SQLWARN7 flag is set when
DSNTIAUL executes a FETCH to retrieve rows, DSNTIAUL continues to retrieve rows.
(YES)
If a warning occurs when DSNTIAUL executes an OPEN or FETCH to retrieve rows, DSNTIAUL
continues to retrieve rows.
(QUIET)
The same as YES except that the program suppresses all SQL warning messages from OPEN or
FETCH statements if the SQLCODE is 0 or greater.
LOBFILE(prefix)
Specify LOBFILE to indicate that you want DSNTIAUL to dynamically allocate data sets, each to
receive the full content of a LOB cell. (A LOB cell is the intersection of a row and a LOB column.) If you
do not specify the LOBFILE option, you can unload up to only 32 KB of data from a LOB column.
1008 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
prefix
Specify a high-level qualifier for these dynamically allocated data sets. You can specify up to 17
characters. The qualifier must conform with the rules for TSO data set names.
DSNTIAUL uses a naming convention for these dynamically allocated data sets of
prefix.Qiiiiiii.Cjjjjjjj.Rkkkkkkk, where these qualifiers have the following values:
prefix
The high-level qualifier that you specify in the LOBFILE option.
Qiiiiiii
The sequence number (starting from 0) of a query that returns one or more LOB columns
Cjjjjjjj
The sequence number (starting from 0) of a column in a query that returns one or more LOB
columns
Rkkkkkkk
The sequence number (starting from 0) of a row of a result set that has one or more LOB columns.
The generated LOAD statement contains LOB file reference variables that can be used to load data
from these dynamically allocated data sets.
If you do not specify the SQL parameter, your input data set must contain one or more single-line
statements (without a semicolon) that use the following syntax:
Each input statement must be a valid SQL SELECT statement with the clause SELECT * FROM omitted
and with no ending semicolon. DSNTIAUL generates a SELECT statement for each input statement by
appending your input line to SELECT * FROM, then uses the result to determine which tables to unload.
For this input format, the text for each table specification can be a maximum of 72 bytes and must not
span multiple lines.
You can use the input statements to specify SELECT statements that join two or more tables or select
specific columns from a table. If you specify columns, you need to modify the LOAD statement that
DSNTIAUL generates.
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1009
data sets must match the number of SELECT statements (if you specify parameter SQL) or table
specifications in your input data set.
Define all data sets as sequential data sets. You can specify the record length and block size of the
SYSPUNCH and SYSRECnn data sets. The maximum record length for the SYSPUNCH and SYSRECnn data
sets is 32760 bytes.
Examples
Example: using DSNTIAUL to unload a subset of rows in a table
Suppose that you want to unload the rows for department D01 from the project table. Because
you can fit the table specification on one line, and you do not want to execute any non-SELECT
statements, you do not need the SQL parameter. Your invocation looks like the one that is shown in
the following figure:
1010 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
• Lock both tables in share mode before you unload them
• Retrieve 250 rows per fetch
For these activities, you must specify the SQL parameter and the number-of-rows-per-fetch parameter
when you run DSNTIAUL. Your DSNTIAUL invocation is shown in the following figure:
The following call to DSNTIAUL unloads the sample LOB table. The parameters for DSNTIAUL indicate
the following options:
• The SQL parameter specifies that the input data set (SYSIN) contains SQL.
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1011
• The number-of-rows-per-fetch parameter value of 1 specifies that DSNTIAUL is to retrieve one row
for each FETCH operation. A value of 1 is necessary if the LOB columns that you unload might
contain NULL values.
• The LOBFILE parameter value of LOBFILE(DSN8UNLD) specifies that DSNTIAUL places the LOB data
in data sets with a high-level qualifier of DSN8UNLD.
Given that the sample LOB table has 4 rows of data, DSNTIAUL produces the following output:
• Data for columns EMPNO and EMP_ROWID are placed in the data set that is allocated according to
the SYSREC00 DD statement. The data set name is DSN8UNLD.SYSREC00
• A generated LOAD statement is placed in the data set that is allocated according to the SYSPUNCH
DD statement. The data set name is DSN8UNLD.SYSPUNCH
• The following data sets are dynamically created to store LOB data:
– DSN8UNLD.Q0000000.C0000002.R0000000
– DSN8UNLD.Q0000000.C0000002.R0000001
– DSN8UNLD.Q0000000.C0000002.R0000002
– DSN8UNLD.Q0000000.C0000002.R0000003
– DSN8UNLD.Q0000000.C0000003.R0000000
– DSN8UNLD.Q0000000.C0000003.R0000001
– DSN8UNLD.Q0000000.C0000003.R0000002
– DSN8UNLD.Q0000000.C0000003.R0000003
– DSN8UNLD.Q0000000.C0000004.R0000000
– DSN8UNLD.Q0000000.C0000004.R0000001
– DSN8UNLD.Q0000000.C0000004.R0000002
– DSN8UNLD.Q0000000.C0000004.R0000003
For example, DSN8UNLD.Q0000000.C0000004.R0000001 means that the data set contains data
that is unloaded from the second row (R0000001) and the fifth column (C0000004) of the result set
for the first query (Q0000000).
1012 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Preparing the DSNTIAD sample program
Before you can use the DSNTIAD sample program, you must precompile, assemble, link, and bind it first.
Also, when you are ready for DSNTIAD to start using to use new capabilities in later Db2 12 function
levels, you must rebind the packages at the corresponding APPLCOMPAT level.
For more information, see “Db2 productivity-aid sample programs” on page 1006
For more information about the RUN command, see RUN (DSN) (Db2 Commands).
DSNTIAD parameters
PKGSET(collection)
Specifies that DSNTIAD implicitly executes a SET CURRENT PACKAGESET statement to assign a value
to the CURRENT PACKAGESET special register before processing the dynamic SQL statements in
SYSIN.
collection
The value to assign to the CURRENT PACKAGESET special register. You can specify up to 40
characters.
RC0
If you specify this parameter, DSNTIAD ends with return code 0, even if the program encounters SQL
errors. If you do not specify RC0, DSNTIAD ends with a return code that reflects the severity of the
errors that occur. Without RC0, DSNTIAD terminates if more than 10 SQL errors occur during a single
execution.
SQLTERM(termchar)
Specify this parameter to indicate the character that you use to end each SQL statement. You can use
any special character except one of those listed in the following table. SQLTERM(;) is the default.
Use a character other than a semicolon if you plan to execute a statement that contains embedded
semicolons.
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1013
For example, suppose that you specify the parameter SQLTERM(#) to indicate that the character # is
the statement terminator. Then a CREATE TRIGGER statement with embedded semicolons looks like
this:
A CREATE PROCEDURE statement with embedded semicolons looks like the following statement:
Be careful to choose a character for the statement terminator that is not used within the statement.
1014 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Example: invoking the DSNTIAD program
Suppose that you want to execute 20 UPDATE statements, and you do not want DSNTIAD to terminate if
more than 10 errors occur. Your invocation looks like the one that is shown in the following figure:
If you use applications or other automation to process output from DSNTEP2 or DSNTEP4, be aware
that minor changes in the format can occur as a result of service or enhancements. Such changes might
require you to adjust your processes that use the output of these programs.
Important: When you allocate a new data set with the SYSPRINT DD statement, either specify a DCB with
RECFM=FBA and LRECL=nnn, where nnn matches the PAGEWIDTH value in the source program, or do not
specify the DCB parameter.
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1015
Running the DSNTEP2 and DSNTEP4 sample programs
To run the DSNTEP2 and DSNTEP4 sample programs, use the RUN (DSN) command and specify the
following load module and plan name.
DSNTEP2 load module and plan
For more information about the RUN command, see RUN (DSN) (Db2 Commands).
1016 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
SQL
This is the preferred mode for SQL statements other than SQL procedural language. When you use
this option, which is the default, DSNTEP2 or DSNTEP4 collapses each line of an SQL statement
into a single line before passing the statement to Db2. DSNTEP2 or DSNTEP4 also discards all SQL
comments.
SQLCOMNT
This mode is suitable for all SQL, but it is intended primarily for SQL procedural language
processing. When this option is in effect, behavior is similar to SQL mode, except that DSNTEP2
or DSNTEP4 does not discard SQL comments. Instead, it automatically terminates each SQL
comment with a line feed character (hex 25), unless the comment is already terminated by one or
more line formatting characters. Use this option to process SQL procedural language with minimal
modification by DSNTEP2 or DSNTEP4.
SQLPL
This mode is suitable for all SQL, but it is intended primarily for SQL procedural language
processing. When this option is in effect, DSNTEP2 or DSNTEP4 retains SQL comments and
terminates each line of an SQL statement with a line feed character (hex 25) before passing the
statement to Db2. Lines that end with a split token are not terminated with a line feed character.
Use this mode to obtain improved diagnostics and debugging of SQL procedural language.
SQLTERM(termchar)
Specifies the character that you use to end each SQL statement. You can use any character except one
of those that are listed in Table 178 on page 1013. SQLTERM(;) is the default.
Use a character other than a semicolon if you plan to execute a statement that contains embedded
semicolons.
See “Example: changing the SQL terminator” on page 1021.
TOLWARN
Indicates whether DSNTEP2 or DSNTEP4 continues to process SQL SELECT statements after receiving
an SQL warning. You can specify one of the following values:
NO
Indicates that the program stops processing the SELECT statement if a warning occurs when
the program executes an OPEN or FETCH for a SELECT statement. NO is the default value for
TOLWARN.
The following exceptions exist:
• If SQLCODE +445 or SQLCODE +595 occurs when DSNTEP2 or DSNTEP4 executes a FETCH for a
SELECT statement, the program continues to process the SELECT statement.
• If SQLCODE +354 occurs when DSNTEP4 executes a FETCH for a SELECT statement, the
program continues to process the SELECT statement.
• If SQLCODE +802 occurs when DSNTEP2 or DSNTEP4 executes a FETCH for a SELECT
statement, the program continues to process the SELECT statement if the TOLARTHWRN control
statement is set to YES.
YES
Indicates that the program continues to process the SELECT statement if a warning occurs when
the program executes an OPEN or FETCH for a SELECT statement.
QUIET
The same as YES except that the program suppresses all SQL warning messages from OPEN or FETCH
statements if the SQLCODE is 0 or greater.
Settings that you can change in the DSNTEP2 or DSNTEP4 source programs to
modify output formatting
If the DSNTEP2 or DSNTEP4 output formatting does not meet your requirements, you can change some
variables in the source code to modify the formatting.
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1017
For example, if you want to increase the maximum width of a page, the maximum size of a print line, and
the maximum number of characters in the output of a character column, you can increase the values of
the PAGEWIDTH, MAXPAGWD, and MAXCOLWD variable values.
For a complete description of the settings that you can change, see the information under PROGRAM
SIZES in the DSNTEP2 and DSNTEP4 prologs.
You can specify the following control option statements. If you specify a value of NO for any of the
options in this list, the program behaves as if you did not specify the parameter.
--#SET PKGSET value
Specifies that DSNTEP2 or DSNTEP4 implicitly executes a SET CURRENT PACKAGESET statement
to assign a value to the CURRENT PACKAGESET special register before processing dynamic
SQL statements after this control statement in SYSIN. value is the value to assign to CURRENT
PACKAGESET special register. You can specify up to 40 characters.
For an example, see “Example: Running dynamic SQL statements at different application
compatibility levels in the same SYSIN” on page 1021.
--#SET TERMINATOR value
The SQL statement terminator. value is any single-byte character other than one of those that
are listed in “DSNTIAD sample program” on page 1012. The default is the value of the SQLTERM
parameter.
See “Example: changing the SQL terminator within a series of SQL statements” on page 1021.
--#SET ROWS_FETCH value
The number of rows that are to be fetched from the result table. value is a numeric literal between
-1 and the number of rows in the result table. -1 means that all rows are to be fetched. The default
is -1.
--#SET ROWS_OUT value
The number of fetched rows that are to be sent to the output data set. value is a numeric literal
between -1 and the number of fetched rows. -1 means that all fetched rows are to be sent to the
output data set. The default is -1.
--#SET MULT_FETCH value
This option is valid only for DSNTEP4. Use MULT_FETCH to specify the number of rows that are to
be fetched at one time from the result table. The default fetch amount for DSNTEP4 is 100 rows,
but you can specify from 1 to 32676 rows.
--#SET TOLWARN value
Indicates whether DSNTEP2 or DSNTEP4 continues to process SQL SELECT statements after
receiving an SQL warning. You can specify one of the following values:
1018 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
NO
Indicates that the program stops processing the SELECT statement if a warning occurs when
the program executes an OPEN or FETCH for a SELECT statement. NO is the default value for
TOLWARN.
The following exceptions exist:
• If SQLCODE +445 or SQLCODE +595 occurs when DSNTEP2 or DSNTEP4 executes a FETCH
for a SELECT statement, the program continues to process the SELECT statement.
• If SQLCODE +354 occurs when DSNTEP4 executes a FETCH for a SELECT statement, the
program continues to process the SELECT statement.
• If SQLCODE +802 occurs when DSNTEP2 or DSNTEP4 executes a FETCH for a SELECT
statement, the program continues to process the SELECT statement if the TOLARTHWRN
control statement is set to YES.
YES
Indicates that the program continues to process the SELECT statement if a warning occurs
when the program executes an OPEN or FETCH for a SELECT statement.
--#SET TOLARTHWRN value
Indicates whether DSNTEP2 and DSNTEP4 continue to process an SQL SELECT statement after an
arithmetic SQL warning (SQLCODE +802) is returned. value is either NO (the default) or YES.
--#SET PREPWARN value
Specifies that DSNTEP2 or DSNTEP4 is to display details about any SQL warnings that are
encountered at PREPARE time.
Regardless of whether you specify PREPWARN, when an SQL warning is encountered at PREPARE
time, the program displays the message SQLWARNING ON PREPARE and sets the return code to
4. When you specify PREPWARN, the program also displays the details about any SQL warnings.
--#SET SQLFORMAT value
Specifies how DSNTEP2 or DSNTEP4 pre-processes SQL statements before passing them to Db2.
Select one of the following options:
SQL
This is the preferred mode for SQL statements other than SQL procedural language. When
you use this option, which is the default, DSNTEP2 or DSNTEP4 collapses each line of an SQL
statement into a single line before passing the statement to Db2. DSNTEP2 or DSNTEP4 also
discards all SQL comments.
SQLCOMNT
This mode is suitable for all SQL, but it is intended primarily for SQL procedural language
processing. When this option is in effect, behavior is similar to SQL mode, except that
DSNTEP2 or DSNTEP4 does not discard SQL comments. Instead, it automatically terminates
each SQL comment with a line feed character (hex 25), unless the comment is already
terminated by one or more line formatting characters. Use this option to process SQL
procedural language with minimal modification by DSNTEP2 or DSNTEP4.
SQLPL
This mode is suitable for all SQL, but it is intended primarily for SQL procedural language
processing. When this option is in effect, DSNTEP2 or DSNTEP4 retains SQL comments and
terminates each line of an SQL statement with a line feed character (hex 25) before passing
the statement to Db2. Lines that end with a split token are not terminated with a line feed
character. Use this mode to obtain improved diagnostics and debugging of SQL procedural
language.
--#SET MAXERRORS value
value specifies that number of errors that DSNTEP2 and DSNTEP4 handle before processing
stops. The default is 10. Use a value of -1 to indicate that a program is to tolerate an unlimited
number of errors.
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1019
SYSPRINT
Output data set. DSNTEP2 and DSNTEP4 write informational and error messages in this data set.
DSNTEP2 and DSNTEP4 write output records of no more than 133 bytes.
Define all data sets as sequential data sets.
Examples
Example: invoking DSNTEP2
Suppose that you want to use DSNTEP2 to execute SQL SELECT statements that might contain DBCS
characters. You also want left-aligned output. Your invocation looks like the following example.
1020 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
In this example, V12R1M508 is the default application compatibility level for DSNTEP2 because the
package named M508TEP2 is bound with APPLCOMPAT(V12R1M508) and is listed first in the BIND
PLAN step. However, you can also use DSNTEP2 to issue dynamic SQL statements at application
compatibility level V12R1M503. To do so in this example, specify the following parameters when you
run DSNTEP2.
DSNTEP2 implicitly issues the following statement before it runs the dynamic SQL statements, and it
runs dynamic SQL statements at application compatibility level V12R1M503:
Example: Running dynamic SQL statements at different application compatibility levels in the same
SYSIN
Assume that you issued the same BIND commands from the previous example, and suppose that you
want to create a new multi-table segmented table space, which can only be created at application
compatibility V12R1M503 or lower. As in the previous example, the default application compatibility
level is V12R1M508, but you can use the following example --#SET PKGSET control statement to run
some statements at a lower application compatibility in the same SYSIN.
In this example, the first three statements succeed because the -# SET PKGSET control statement
tells DSNTEP2 to run them at application compatibility level V12R1M503. Another -# SET PKGSET
control statement changes the application compatibility level to V12R1M508 because ALTER
TABLESPACE statements must run at this level or higher to specify the MOVE TABLE clause.
Example: changing the SQL terminator
Suppose that you specify the parameter SQLTERM(#) to indicate that the character # is the statement
terminator. Then a CREATE TRIGGER statement with embedded semicolons looks like this:
A CREATE PROCEDURE statement with embedded semicolons looks like the following statement:
Be careful to choose a character for the statement terminator that is not used within the statement.
Example: changing the SQL terminator within a series of SQL statements
Suppose that you have an existing set of SQL statements to which you want to add a CREATE
TRIGGER statement that has embedded semicolons. You can use the --#SET TERMINATOR control
statement. You can use the default SQLTERM value, which is a semicolon, for all of the existing SQL
statements.
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1021
Before you execute the CREATE TRIGGER statement, include the --#SET TERMINATOR # control
statement to change the SQL terminator to the character #:
See the following discussion of the SYSIN data set for more information about the --#SET control
statement.
Organization application:
The organization application manages the following company information:
• Department administrative structure
• Individual departments
• Individual employees.
Management of information about department administrative structures involves how departments relate
to other departments. You can view or change the organizational structure of an individual department,
and the information about individual employees in any department. The organization application runs
interactively in the ISPF/TSO, IMS, and CICS environments and is available in PL/I and COBOL.
Project application:
The project application manages information about a company's project activities, including the following:
1022 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
• Project structures
• Project activity listings
• Individual project processing
• Individual project activity estimate processing
• Individual project staffing processing.
Each department works on projects that contain sets of related activities. Information available about
these activities includes staffing assignments, completion-time estimates for the project as a whole, and
individual activities within a project. The project application runs interactively in IMS and CICS and is
available in PL/I only.
Phone application:
The phone application lets you view or update individual employee phone numbers. There are different
versions of the application for ISPF/TSO, CICS, IMS, and batch:
• ISPF/TSO applications use COBOL and PL/I.
• CICS and IMS applications use PL/I.
• Batch applications use C, C++, COBOL, FORTRAN, and PL/I.
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1023
User-defined function applications:
The user-defined function applications consist of a client program that invokes the sample user-defined
functions and a set of user-defined functions that perform the following functions:
• Convert the current date to a user-specified format
• Convert a date from one format to another
• Convert the current time to a user-specified format
• Convert a date from one format to another
• Return the day of the week for a user-specified date
• Return the month for a user-specified date
• Format a floating point number as a currency value
• Return the table name for a table, view, or alias
• Return the qualifier for a table, view or alias
• Return the location for a table, view or alias
• Return a table of weather information
All programs are written in C or C++ and run in the TSO batch environment.
LOB application:
The LOB application demonstrates how to perform the following tasks:
• Define Db2 objects to hold LOB data
• Populate Db2 tables with LOB data using the LOAD utility, or using INSERT and UPDATE statements
when the data is too large for use with the LOAD utility
• Manipulate the LOB data using LOB locators
The programs that create and populate the LOB objects use DSNTIAD and run in the TSO batch
environment. The program that manipulates the LOB data is written in C and runs under ISPF/TSO.
1024 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 181. Application languages and environments (continued)
Programs ISPF/TSO IMS CICS Batch SPUFI
Project PL/I PL/I
SQLCA Assembler Assembler Assembler Assembler
formatting
routines
Stored COBOL PL/I
procedures C
SQL
User-defined C
functions C++
LOBs C
Notes:
1. Assembler subroutine DSN8CA.
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1025
Table 182. Sample Db2 applications for TSO (continued)
Application Program Preparation Attachment Description
name JCL member facility
name
Phone DSN8SP3 DSNTEJ3P DSNALI This PL/I ISPF program lists employee
telephone numbers and updates them if
requested.
UNLOAD DSNTIAUL DSNTEJ2A DSNELI This assembler language program unloads the
data from a table or view and to produce LOAD
utility control statements for the data.
Dynamic SQL DSNTIAD DSNTIJTM DSNELI This assembler language program dynamically
executes non-SELECT statements read in from
SYSIN; that is, it uses dynamic SQL to execute
non-SELECT SQL statements.
Dynamic SQL DSNTEP2 DSNTEJ1P or DSNELI This PL/I program dynamically executes
DSNTEJ1L SQL statements read in from SYSIN. Unlike
DSNTIAD, this application can also execute
SELECT statements.
Stored DSN8EP1 DSNTEJ6P DSNELI The jobs DSNTEJ6P and DSNTEJ6S prepare
procedures1 a PL/I version of the application. This
sample executes Db2 commands using the
Stored DSN8EP2 DSNTEJ6S DSNRLI instrumentation facility interface (IFI).
procedure1
Stored DSN8EPU DSNTEJ6U DSNELI The sample that is prepared by job DSNTEJ6U
procedures1 invokes the utilities stored procedure.
Stored DSN8ED1 DSNTEJ6D DSNELI The jobs DSNTEJ6D and DSNTEJ6T prepare
procedures1 a C version of the application. The C stored
procedure uses result sets to return commands
Stored DSN8ED2 DSNTEJ6T DSNRLI to the client. This sample executes Db2
procedures1 commands using the instrumentation facility
interface (IFI).
Stored DSN8EC1 DSNTEJ61 DSNRLI The sample that is prepared by jobs
procedures1 DSNTEJ61 and DSNTEJ62 demonstrates a
stored procedure that accesses IMS databases
Stored DSN8EC2 DSNTEJ62 DSNELI through the ODBA interface.
procedures1
Stored DSN8ES1 DSNTEJ63 DSNRLI The sample that is prepared by jobs DSNTEJ63
procedures1 and DSNTEJ64 demonstrates how to prepare
an SQL procedure using JCL.
Stored DSN8ED3 DSNTEJ64 DSNELI
procedures1
Stored DSN8ES2 DSNTEJ65 DSNRLI The sample that is prepared by job DSNTEJ65
procedures1 demonstrates how to prepare an SQL
procedure using the SQL procedure processor.
Stored DSN8ED6 DSNTEJ6W DSNELI The sample that is prepared by job DSNTEJ6W
procedures1 demonstrates how to prepare and run a client
program that calls a Db2–supplied stored
procedure to refresh a WLM environment.
1026 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Table 182. Sample Db2 applications for TSO (continued)
Application Program Preparation Attachment Description
name JCL member facility
name
Stored DSN8ED7 DSNTEJ6Z DSNELI The sample that is prepared by job DSNTEJ6Z
procedures1 demonstrates how to prepare and run a client
program that calls a Db2–supplied stored
procedure to display the current settings of
system parameters.
Stored DSN8ED9 DSNTEJ66 DSNELI The sample that is prepared by job DSNTEJ66
procedures1 demonstrates how to prepare and run a client
program that calls a native SQL procedure,
Stored DSN8ES3 DSNTEJ66 not applicable manages versions of that procedure, and
procedures1 optionally, deploys that procedure to a remote
server. DSN8ES3 is the sample native SQL
procedure and DSN8ED9 is the sample C
language caller of DSN8ES3.
User-defined DSN8DUAD DSNTEJ2U DSNRLI These C applications consist of a set of user-
functions defined scalar functions that can be invoked
through SPUFI or DSNTEP2.
User-defined DSN8DUAT DSNTEJ2U DSNRLI
functions
User-defined DSN8DUCD DSNTEJ2U DSNRLI
functions
User-defined DSN8DUCT DSNTEJ2U DSNRLI
functions
User-defined DSN8DUCY DSNTEJ2U DSNRLI
functions
User-defined DSN8DUTI DSNTEJ2U DSNRLI
functions
User-defined DSN8DUWC DSNTEJ2U DSNRLI The user-defined table function DSN8DUWF
functions can be invoked by the C client program
DSN8DUWC.
User-defined DSN8DUWF DSNTEJ2U DSNRLI
functions
User-defined DSN8EUDN DSNTEJ2U DSNRLI These C++ applications consist of a set of user-
functions defined scalar functions that can be invoked
through SPUFI or DSNTEP2.
User-defined DSN8EUMN DSNTEJ2U DSNRLI
functions
User-defined DSN8HDFS DSNTEJBI DSNRLI The user-defined table function HDFS_READ,
functions which is prepared by DSNTEJBI, reads data
from a delimiter-separated file in the Hadoop
Distributed File System (HDFS). This user-
defined function can be invoked through SPUFI
or DSNTEP2.
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1027
Table 182. Sample Db2 applications for TSO (continued)
Application Program Preparation Attachment Description
name JCL member facility
name
User-defined DSN8JAQL DSNTEJBI DSNRLI The user-defined scalar function
functions JAQL_SUBMIT, which is prepared by
DSNTEJBI, invokes an IBM InfoSphere
BigInsights Jaql query. This user-defined
function can be invoked through SPUFI or
DSNTEP2.
LOBs DSN8DLPL DSNTEJ71 DSNELI These applications demonstrate how to
populate a LOB column that is greater than 32
LOBs DSN8DLCT DSNTEJ71 DSNELI KB, manipulate the data using the POSSTR and
LOBs DSN8DLRV DSNTEJ73 DSNELI SUBSTR built-in functions, and display the data
in ISPF using GDDM.
LOBs DSN8DLPV DSNTEJ75 DSNELI
Note:
1. All of the stored procedure applications consist of a calling program, a stored procedure program, or
both.
Related reference
Data sets that the precompiler uses
When you invoke the precompiler you need to provide data sets that contain input for the precompiler,
such as the host programming statements and SQL statements. You also need to provide data sets where
the precompiler can store its output, such as the modified source code and diagnostics messages.
DSN8BC3
THIS MODULE LISTS EMPLOYEE PHONE NUMBERS AND UPDATES THEM IF DESIRED.
IDENTIFICATION DIVISION.
*-----------------------
PROGRAM-ID. DSN8BC3.
1028 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* SYMBOLIC LABEL/NAME = CARDIN *
* DESCRIPTION = INPUT REQUEST FILE *
* *
* SYMBOLIC LABEL/NAME = VPHONE *
* DESCRIPTION = VIEW OF TELEPHONE *
* INFORMATION *
* *
* *
* OUTPUT = *
* *
* SYMBOLIC LABEL/NAME = REPORT *
* DESCRIPTION = REPORT OF EMPLOYEE *
* PHONE NUMBERS *
* *
* SYMBOLIC LABEL/NAME = VEMPLP *
* DESCRIPTION = VIEW OF EMPLOYEE *
* INFORMATION *
* *
* EXIT-NORMAL = RETURN CODE 0 NORMAL COMPLETION *
* *
* EXIT-ERROR = *
* *
* RETURN CODE = NONE *
* *
* ABEND CODES = NONE *
* *
* ERROR-MESSAGES = *
* DSN8004I - EMPLOYEE SUCCESSFULLY UPDATED *
* DSN8007E - EMPLOYEE DOES NOT EXIST, UPDATE NOT DONE*
* DSN8008I - NO EMPLOYEE FOUND IN TABLE *
* DSN8053I - ROLLBACK SUCCESSFUL, ALL UPDATES REMOVED*
* DSN8060E - SQL ERROR, RETURN CODE IS: *
* DSN8061E - ROLLBACK FAILED, RETURN CODE IS: *
* DSN8068E - INVALID REQUEST, SHOULD BE 'L' OR 'U' *
* DSN8075E - MESSAGE FORMAT ROUTINE ERROR, *
* RETURN CODE IS: *
* *
* EXTERNAL REFERENCES = *
* ROUTINES/SERVICES = *
* DSNTIAR - TRANSLATE SQLCA INTO MESSAGES *
* DSN8MCG - ERROR MESSAGE ROUTINE *
* *
* DATA-AREAS = NONE *
* *
* CONTROL-BLOCKS = *
* SQLCA - SQL COMMUNICATION AREA *
* *
* TABLES = NONE *
* *
* *
* CHANGE-ACTIVITY = NONE *
* *
* *
* *PSEUDOCODE* *
* *
* PROCEDURE *
* GET FIRST INPUT *
* DO WHILE MORE INPUT *
* CREATE REPORT HEADING *
* *
* CASE (ACTION) *
* *
* SUBCASE ('L') *
* IF LASTNAME IS '*' THEN *
* LIST ALL EMPLOYEES *
* ELSE *
* IF LASTNAME CONTAINS '%' THEN *
* LIST EMPLOYEES GENERIC *
* ELSE *
* LIST EMPLOYEES SPECIFIC *
* ENDSUB *
* *
* SUBCASE ('U') *
* UPDATE PHONENUMBER FOR EMPLOYEE *
* WRITE CONFIRMATION MESSAGE *
* OTHERWISE *
* INVALID REQUEST *
* ENDSUB *
* *
* ENDCASE *
* GET NEXT INPUT *
* END *
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1029
* *
* IF SQL ERROR OCCURS THEN *
* DO *
* FORMAT ERROR MESSAGE *
* ROLLBACK *
* END *
* END. *
*---------------------------------------------------------------*
/
ENVIRONMENT DIVISION.
*--------------------
CONFIGURATION SECTION.
SPECIAL-NAMES. C01 IS TO-TOP-OF-PAGE.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT CARDIN
ASSIGN TO DA-S-CARDIN.
SELECT REPOUT
ASSIGN TO UT-S-REPORT.
DATA DIVISION.
*-------------
FILE SECTION.
FD CARDIN
RECORD CONTAINS 80 CHARACTERS
BLOCK CONTAINS 0 RECORDS
LABEL RECORDS ARE OMITTED.
01 CARDREC PIC X(80).
FD REPOUT
RECORD CONTAINS 120 CHARACTERS
LABEL RECORDS ARE OMITTED
DATA RECORD IS REPREC.
01 REPREC PIC X(120).
/
WORKING-STORAGE SECTION.
*****************************************************
* STRUCTURE FOR INPUT *
*****************************************************
01 IOAREA.
02 ACTION PIC X(01).
02 LNAME PIC X(15).
02 FNAME PIC X(12).
02 ENO PIC X(06).
02 NEWNO PIC X(04).
02 FILLER PIC X(42).
*****************************************************
* REPORT HEADER STRUCTURE *
*****************************************************
01 REPHDR1.
02 FILLER PIC X(29)
VALUE '-----------------------------'.
02 FILLER PIC X(21)
VALUE ' TELEPHONE DIRECTORY '.
02 FILLER PIC X(29)
VALUE '-----------------------------'.
01 REPHDR2.
02 FILLER PIC X(09) VALUE 'LAST NAME'.
02 FILLER PIC X(07) VALUE SPACES.
02 FILLER PIC X(10) VALUE 'FIRST NAME'.
02 FILLER PIC X(03) VALUE SPACES.
02 FILLER PIC X(08) VALUE 'INITIAL'.
02 FILLER PIC X(07) VALUE 'PHONE'.
02 FILLER PIC X(09) VALUE 'EMPLOYEE'.
02 FILLER PIC X(05) VALUE 'WORK'.
02 FILLER PIC X(04) VALUE 'WORK'.
01 REPHDR3.
02 FILLER PIC X(37) VALUE SPACES.
02 FILLER PIC X(07) VALUE 'NUMBER'.
02 FILLER PIC X(09) VALUE 'NUMBER'.
02 FILLER PIC X(05) VALUE 'DEPT'.
02 FILLER PIC X(05) VALUE 'DEPT'.
02 FILLER PIC X(04) VALUE 'NAME'.
*****************************************************
* REPORT STRUCTURE *
*****************************************************
01 REPDATA.
1030 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
02 RLNAME PIC X(15).
02 FILLER PIC X(01) VALUE SPACES.
02 RFNAME PIC X(12).
02 FILLER PIC X(04) VALUE SPACES.
02 RMIDINIT PIC X(01).
02 FILLER PIC X(04) VALUE SPACES.
02 RPHONE PIC X(04).
02 FILLER PIC X(03) VALUE SPACES.
02 REMPNO PIC X(06).
02 FILLER PIC X(03) VALUE SPACES.
02 RDEPTNO PIC X(03).
02 FILLER PIC X(02) VALUE SPACES.
02 RDEPTNAME PIC X(36).
*****************************************************
* WORKAREAS *
*****************************************************
01 LNAME-WORK.
49 LNAME-WORKL PIC S9(4) COMP.
49 LNAME-WORKC PIC X(15).
01 FNAME-WORK.
49 FNAME-WORKL PIC S9(4) COMP.
49 FNAME-WORKC PIC X(12).
77 INPUT-SWITCH PIC X VALUE 'Y'.
88 NOMORE-INPUT VALUE 'N'.
77 NOT-FOUND PIC S9(9) COMP VALUE +100.
*****************************************************
* VARIABLES FOR ERROR-HANDLING *
*****************************************************
01 ERROR-MESSAGE.
02 ERROR-LEN PIC S9(4) COMP VALUE +960.
02 ERROR-TEXT PIC X(120) OCCURS 10 TIMES
INDEXED BY ERROR-INDEX.
77 ERROR-TEXT-LEN PIC S9(9) COMP VALUE +120.
/****************************************************
* SQL INCLUDE FOR SQLCA *
*****************************************************
EXEC SQL INCLUDE SQLCA END-EXEC.
*****************************************************
* SQL DECLARATION FOR VIEW VPHONE *
*****************************************************
EXEC SQL DECLARE VPHONE TABLE
(LASTNAME VARCHAR(15) NOT NULL,
FIRSTNAME VARCHAR(12) NOT NULL,
MIDDLEINITIAL CHAR(01) NOT NULL,
PHONENUMBER CHAR(04) ,
EMPLOYEENUMBER CHAR(06) NOT NULL,
DEPTNUMBER CHAR(03) NOT NULL,
DEPTNAME VARCHAR(36) NOT NULL)
END-EXEC.
*****************************************************
* STRUCTURE FOR PPHONE RECORD *
*****************************************************
01 PPHONE.
02 LASTNAME.
49 LASTNAMEL PIC S9(4) COMP.
49 LASTNAMEC PIC X(15) VALUE SPACES.
02 FIRSTNAME.
49 FIRSTNAMEL PIC S9(4) COMP.
49 FIRSTNAMEC PIC X(12) VALUE SPACES.
02 MIDDLEINITIAL PIC X(01).
02 PHONENUMBER PIC X(04).
02 EMPLOYEENUMBER PIC X(06).
02 DEPTNUMBER PIC X(03).
02 DEPTNAME.
49 DEPTNAMEL PIC S9(4) COMP.
49 DEPTNAMEC PIC X(36) VALUE SPACES.
*
77 PERCENT-COUNTER PIC S9(4) COMP.
*****************************************************
* SQL DECLARATION FOR VIEW VEMPLP *
*****************************************************
EXEC SQL DECLARE VEMPLP TABLE
(EMPLOYEENUMBER CHAR(06) NOT NULL,
PHONENUMBER CHAR(04) )
END-EXEC.
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1031
*****************************************************
* SQL CURSORS *
*****************************************************
*** CURSOR LISTS ALL EMPLOYEE NAMES
*** CURSOR LISTS ALL EMPLOYEE NAMES WITH A PATTERN (%) OR (_)
*** FOR LAST NAME
01 MSG-REC1.
02 OUTMSG1 PIC X(69).
02 RETCODE PIC S9(9).
01 MSG-REC2.
02 OUTMSG2 PIC X(69).
PROCEDURE DIVISION.
*------------------
*****************************************************
* SQL RETURN CODE HANDLING *
*****************************************************
EXEC SQL WHENEVER SQLERROR GOTO DBERROR END-EXEC.
EXEC SQL WHENEVER SQLWARNING GOTO DBERROR END-EXEC.
EXEC SQL WHENEVER NOT FOUND CONTINUE END-EXEC.
*****************************************************
* MAIN PROGRAM ROUTINE *
*****************************************************
PROG-START.
* **OPEN FILES
OPEN INPUT CARDIN
OUTPUT REPOUT.
* **MAIN ROUTINE
PERFORM PROCESS-INPUT
UNTIL NOMORE-INPUT.
PROG-END.
* **CLOSE FILES
CLOSE CARDIN
REPOUT.
GOBACK.
*****************************************************
* CREATE REPORT HEADING *
* SELECT ACTION *
*****************************************************
1032 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
PROCESS-INPUT.
* **PRINT HEADING
WRITE REPREC FROM REPHDR1
AFTER ADVANCING TO-TOP-OF-PAGE.
WRITE REPREC FROM REPHDR2
AFTER ADVANCING 2 LINES.
WRITE REPREC FROM REPHDR3.
* **SELECT ACTION
IF ACTION = 'L'
PERFORM LIST-FUNCTION
ELSE
IF ACTION = 'U'
PERFORM TELEPHONE-UPDATE
ELSE
* **INVALID REQUEST
* **PRINT ERROR MESSAGE
MOVE '068E' TO MSGCODE
CALL 'DSN8MCG' USING MAJOR MSGCODE OUTMSG
MOVE OUTMSG TO OUTMSG2
WRITE REPREC FROM MSG-REC2
AFTER ADVANCING 2 LINES.
READ CARDIN RECORD INTO IOAREA
AT END MOVE 'N' TO INPUT-SWITCH.
/
*****************************************************
* DETERMINE FORM OF NAME USED TO LIST EMPLOYEES *
*****************************************************
LIST-FUNCTION.
* **NO LAST NAME GIVEN
IF LNAME = SPACES
MOVE '%' TO LNAME.
* **NO FIRST NAME GIVEN
IF FNAME = SPACES
MOVE '%' TO FNAME.
* **LIST ALL EMPLOYEES
IF LNAME = '*'
PERFORM LIST-ALL
ELSE
* **UNSTRING LAST NAME
UNSTRING LNAME
DELIMITED BY SPACE
INTO LNAME-WORKC
COUNT IN LNAME-WORKL
* **UNSTRING FIRST NAME
UNSTRING FNAME
DELIMITED BY SPACE
INTO FNAME-WORKC
COUNT IN FNAME-WORKL
* **COUNT %'S
MOVE ZERO TO PERCENT-COUNTER
INSPECT LNAME
TALLYING PERCENT-COUNTER FOR ALL '%'
IF PERCENT-COUNTER > ZERO
* **IF NO %'S THEN
* **LIST SPECIFIC NAME(S)
* **ELSE
* **LIST GENERIC NAME(S)
PERFORM LIST-GENERIC
ELSE
PERFORM LIST-SPECIFIC.
/
*****************************************************
* LIST ALL EMPLOYEES *
*****************************************************
LIST-ALL.
* **OPEN CURSOR
EXEC SQL OPEN TELE1 END-EXEC.
* **GET EMPLOYEES
EXEC SQL FETCH TELE1 INTO :PPHONE END-EXEC.
IF SQLCODE = NOT-FOUND
* **NO EMPLOYEE FOUND
* **PRINT ERROR MESSAGE
MOVE '008I' TO MSGCODE
CALL 'DSN8MCG' USING MAJOR MSGCODE OUTMSG
MOVE OUTMSG TO OUTMSG2
WRITE REPREC FROM MSG-REC2
AFTER ADVANCING 2 LINES
ELSE
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1033
* **LIST ALL EMPLOYEES
PERFORM PRINT-AND-GET1
UNTIL SQLCODE IS NOT EQUAL TO ZERO.
* **CLOSE CURSOR
EXEC SQL CLOSE TELE1 END-EXEC.
PRINT-AND-GET1.
PERFORM PRINT-A-LINE.
EXEC SQL FETCH TELE1 INTO :PPHONE END-EXEC.
/
*****************************************************
* LIST GENERIC EMPLOYEES *
*****************************************************
LIST-GENERIC.
* **OPEN CURSOR
EXEC SQL OPEN TELE2 END-EXEC.
* **GET EMPLOYEES
EXEC SQL FETCH TELE2 INTO :PPHONE END-EXEC.
IF SQLCODE = NOT-FOUND
* **NO EMPLOYEE FOUND
* **PRINT ERROR MESSAGE
MOVE '008I' TO MSGCODE
CALL 'DSN8MCG' USING MAJOR MSGCODE OUTMSG
MOVE OUTMSG TO OUTMSG2
WRITE REPREC FROM MSG-REC2
AFTER ADVANCING 2 LINES
ELSE
* **LIST GENERIC EMPLOYEE(S)
PERFORM PRINT-AND-GET2
UNTIL SQLCODE IS NOT EQUAL TO ZERO.
* **CLOSE CURSOR
EXEC SQL CLOSE TELE2 END-EXEC.
PRINT-AND-GET2.
PERFORM PRINT-A-LINE.
EXEC SQL FETCH TELE2 INTO :PPHONE END-EXEC.
/
*****************************************************
* LIST SPECIFIC EMPLOYEES *
*****************************************************
LIST-SPECIFIC.
* **OPEN CURSOR
EXEC SQL OPEN TELE3 END-EXEC.
* **GET EMPLOYEES
EXEC SQL FETCH TELE3 INTO :PPHONE END-EXEC.
IF SQLCODE = NOT-FOUND
* **NO EMPLOYEE FOUND
* **PRINT ERROR MESSAGE
MOVE '008I' TO MSGCODE
CALL 'DSN8MCG' USING MAJOR MSGCODE OUTMSG
MOVE OUTMSG TO OUTMSG2
WRITE REPREC FROM MSG-REC2
AFTER ADVANCING 2 LINES
ELSE
* **LIST SPECIFIC EMPLOYEE(S)
PERFORM PRINT-AND-GET3
UNTIL SQLCODE IS NOT EQUAL TO ZERO.
* **CLOSE CURSOR
EXEC SQL CLOSE TELE3 END-EXEC.
PRINT-AND-GET3.
PERFORM PRINT-A-LINE.
EXEC SQL FETCH TELE3 INTO :PPHONE END-EXEC.
/
*****************************************************
* PRINT A LINE OF INFORMATION FROM DIRECTORY *
*****************************************************
PRINT-A-LINE.
* **GET INFORMATION
MOVE LASTNAMEC TO RLNAME.
MOVE FIRSTNAMEC TO RFNAME.
MOVE MIDDLEINITIAL TO RMIDINIT.
MOVE PHONENUMBER OF PPHONE TO RPHONE.
MOVE EMPLOYEENUMBER OF PPHONE TO REMPNO.
MOVE DEPTNUMBER TO RDEPTNO.
1034 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
MOVE DEPTNAMEC TO RDEPTNAME.
* **PRINT INFORMATION
WRITE REPREC FROM REPDATA
AFTER ADVANCING 2 LINES.
* **MESSAGE FORMAT
* **ROUTINE ERROR
* **PRINT ERROR MESSAGE
MOVE '075E' TO MSGCODE
CALL 'DSN8MCG' USING MAJOR MSGCODE OUTMSG
MOVE OUTMSG TO OUTMSG1 OF MSG-REC1
MOVE RETURN-CODE TO RETCODE OF MSG-REC1
WRITE REPREC FROM MSG-REC1
AFTER ADVANCING 2 LINES.
***********************************************************
* SQL RETURN CODE HANDLING WHEN PROCESSING CANNOT PROCEED *
***********************************************************
EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
EXEC SQL WHENEVER SQLWARNING CONTINUE END-EXEC.
EXEC SQL WHENEVER NOT FOUND CONTINUE END-EXEC.
* **PERFORM ROLLBACK
EXEC SQL ROLLBACK END-EXEC.
IF SQLCODE = ZERO
* **ROLLBACK SUCCESSFUL
* **PRINT CONFIRMATION
* **MESSAGE
MOVE '053I' TO MSGCODE
ELSE
* **ROLLBACK FAILED
* **PRINT ERROR MESSAGE
MOVE '061E' TO MSGCODE.
CALL 'DSN8MCG' USING MAJOR MSGCODE OUTMSG.
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1035
MOVE OUTMSG TO OUTMSG1 OF MSG-REC1.
MOVE SQLCODE TO RETCODE OF MSG-REC1.
WRITE REPREC FROM MSG-REC1
AFTER ADVANCING 2 LINES.
GO TO PROG-END.
*****************************************************
* PRINT MESSAGE TEXT *
*****************************************************
ERROR-PRINT.
WRITE REPREC FROM ERROR-TEXT (ERROR-INDEX)
AFTER ADVANCING 1 LINE.
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSN8BD3
This module lists employee phone numbers and optionally updates them.
/**********************************************************************/
/* */
/* Module name = DSN8BD3 */
/* */
/* Descriptive name = DB2 SAMPLE APPLICATION */
/* PHONE APPLICATION */
/* BATCH */
/* C LANGUAGE */
/* */
/* LICENSED MATERIALS - PROPERTY OF IBM */
/* 5695-DB2 */
/* (C) COPYRIGHT 1982, 1995 IBM CORP. ALL RIGHTS RESERVED. */
/* */
/* STATUS = VERSION 4 */
/* */
/* Function = This module lists employee phone numbers and */
/* optionally updates them. */
/* */
/* Notes = none */
/* */
/* */
/* Module type = C program */
/* Processor = DB2 precompiler, C compiler */
/* Module size = see link edit */
/* Attributes = not reentrant or reusable */
/* */
/* Entry point = DSN8BD3 */
/* Purpose = see function */
/* Linkage = invoked from DSN command processor subcommand RUN */
/* Input = */
/* */
/* symbolic label/name = CARDIN */
/* description = INPUT REQUEST FILE */
/* */
/* symbolic label/name = VPHONE */
/* description = VIEW OF TELEPHONE TABLE: PHONE */
/* */
/* Output = */
/* */
/* symbolic label/name = REPORT */
/* description = PRINTED REPORT AND RESULTS */
/* */
/* symbolic label/name = VEMPLP */
/* description = VIEW OF EMPLOYEE INFORMATION */
/* */
/* */
/* Exit-normal = return code 0 normal completion */
/* */
/* Exit-error = */
/* */
/* Return code = none */
/* */
/* Abend codes = none */
/* */
/* Error-messages = */
/* DSN8000I - REQUEST IS: ... */
/* DSN8004I - EMPLOYEE SUCCESSFULLY UPDATED */
1036 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
/* DSN8007E - EMPLOYEE DOES NOT EXIST, UPDATE NOT DONE */
/* DSN8008I - NO EMPLOYEE FOUND IN TABLE */
/* DSN8053I - ROLLBACK SUCCESSFUL, ALL UPDATES REMOVED */
/* DSN8060E - SQL ERROR, RETURN CODE IS: */
/* DSN8061E - ROLLBACK FAILED, RETURN CODE IS: */
/* DSN8068E - INVALID REQUEST, SHOULD BE 'L' OR 'U' */
/* DSN8075E - MESSAGE FORMAT ROUTINE ERROR, */
/* RETURN CODE IS: */
/* */
/* External references = */
/* Routines/services = */
/* DSNTIAR - translate sqlca into messages */
/* */
/* Data-areas = none */
/* */
/* Control-blocks = */
/* SQLCA - sql communication area */
/* */
/* Tables = none */
/* */
/* Change-activity = */
/* 10/03/94 Updated cardin statement to prevent looping. KEW1351 @51*/
/* PN61293 @51*/
/* */
/* *Pseudocode* */
/* */
/* main: */
/* do while more input */
/* get input */
/* display request */
/* process request */
/* end */
/* */
/* Do_req: */
/* case (action) */
/* */
/* subcase ('L') */
/* create report heading */
/* if lastname is '*' then */
/* list all employees */
/* else */
/* if lastname contains '%' then */
/* list employees generic */
/* else */
/* list employees specific */
/* endsub */
/* */
/* subcase ('U') */
/* update phonenumber for employee */
/* write confirmation message */
/* */
/* otherwise */
/* invalid request */
/* endsub */
/* */
/* endcase */
/* */
/* Prt_row: */
/* print a row of the report */
/* */
/* Sql_err: */
/* if sql error occurs then */
/* rollback */
/* */
/**********************************************************************/
/**********************************************************************/
/* Include C library definitions */
/**********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/**********************************************************************/
/* General declarations */
/**********************************************************************/
#define NOTFOUND 100
/**********************************************************************/
/* Input / Output files */
/**********************************************************************/
FILE *cardin; /* Input control cards */
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1037
FILE *report; /* Output phone report */
/**********************************************************************/
/* Input record structure */
/**********************************************************************/
EXEC SQL BEGIN DECLARE SECTION;
struct {
char action[2]; /* L for list or U for update */
char lname[16]; /* last name or pattern- L mode*/
char fname[13]; /* first name or pattern-L mode*/
char eno[7]; /* employee number- U mode */
char newno[5]; /* new phone number- U mode */
} ioarea;
/**********************************************************************/
/* Report headings */
/**********************************************************************/
struct {
char hdr011[30];
char hdr012[32];
} hdr0 = {
" REQUEST LAST NAME ",
"FIRST NAME EMPNO NEW XT.NO"};
#define rpthdr0 hdr0.hdr011
struct {
char hdr111[29];
char hdr112[21];
char hdr113[30];
} hdr1 = {
"-----------------------------",
" TELEPHONE DIRECTORY ",
"-----------------------------"};
#define rpthdr1 hdr1.hdr111
struct {
char hdr211[10];
char hdr212[11];
char hdr213[ 8];
char hdr214[ 6];
char hdr215[ 9];
char hdr216[ 5];
char hdr217[ 5];
char hdr221[ 7];
char hdr222[ 7];
char hdr223[ 5];
char hdr224[ 5];
char hdr225[ 5];
} hdr2 = {
"LAST NAME",
"FIRST NAME",
"INITIAL",
"PHONE",
"EMPLOYEE",
"WORK",
"WORK",
"NUMBER",
"NUMBER",
"DEPT",
"DEPT",
"NAME"
};
#define rpthdr2 hdr2.hdr211,hdr2.hdr212,hdr2.hdr213,hdr2.hdr214,\
hdr2.hdr215,hdr2.hdr216,hdr2.hdr217,hdr2.hdr221,\
hdr2.hdr222,hdr2.hdr223,hdr2.hdr224,hdr2.hdr225
/**********************************************************************/
/* Report formats */
/**********************************************************************/
static char fmt1[] = "\n %s\n";
static char fmt2[] = " %9s%17s%10s%6s%10s%5s%5s\n%43s%7s%7s%5s%5s\n";
static char fmt3[] = " %-16s%-16s%-5s%-7s%-9s%-5s%-36s\n";
static char fmt4[] = " %1c%15c%12c%6c%4c%43c";
static char fmt5[] =
"\n\n %s\n %s\n --%-7s--%-15s--%-12s--%-5s--%-9s--\n";
/**********************************************************************/
/* Fields sent to message routine */
1038 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
/**********************************************************************/
char outmsg[70]; /* error/information msg buffer*/
char module[ 8] = "DSN8BD3"; /* module name for message rtn */
/**********************************************************************/
/* SQL communication area */
/**********************************************************************/
EXEC SQL INCLUDE SQLCA;
/**********************************************************************/
/* SQL declaration for view VPHONE */
/**********************************************************************/
EXEC SQL DECLARE VPHONE TABLE
(LASTNAME VARCHAR(15) NOT NULL,
FIRSTNAME VARCHAR(12) NOT NULL,
MIDDLEINITIAL CHAR( 1) NOT NULL,
PHONENUMBER CHAR( 4) ,
EMPLOYEENUMBER CHAR( 6) NOT NULL,
DEPTNUMBER CHAR( 3) NOT NULL,
DEPTNAME VARCHAR(36) NOT NULL);
/**********************************************************************/
/* Structure for pphone record */
/**********************************************************************/
/* Note: since the sample program data does not contain imbedded */
/* nulls, the C language null terminated string can be used to */
/* receive the varchar fields from DB2. */
/**********************************************************************/
/* SQL declaration for view VEMPLP (used for update processing) */
/**********************************************************************/
EXEC SQL DECLARE VEMPLP TABLE
(EMPLOYEENUMBER CHAR( 6) NOT NULL,
PHONENUMBER CHAR( 4) );
/**********************************************************************/
/* Structure for pemplp record */
/**********************************************************************/
EXEC SQL BEGIN DECLARE SECTION;
struct {
char employeenumber[7];
char phonenumber[5];
} pemplp;
EXEC SQL END DECLARE SECTION;
/**********************************************************************/
/* SQL cursors */
/**********************************************************************/
/* cursor to list all employee names */
EXEC SQL DECLARE TELE1 CURSOR FOR
SELECT *
FROM VPHONE;
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1039
/**********************************************************************/
/* SQL return code handling */
/**********************************************************************/
EXEC SQL WHENEVER SQLERROR GOTO DBERROR;
EXEC SQL WHENEVER SQLWARNING GOTO DBERROR;
EXEC SQL WHENEVER NOT FOUND CONTINUE;
/**********************************************************************/
/* main program routine */
/**********************************************************************/
extern main()
{
/* Open the input and output files */
cardin = fopen("DD:CARDIN","r,recfm=FB,lrecl=80,blksize=80"); /*@51*/
report = fopen("DD:REPORT","w");
/**********************************************************************/
/* Process the current request */
/**********************************************************************/
Do_req()
{
char *blankloc; /* string translation pointer */
strcpy(slname, ioarea.lname); /* save untranslated last name */
while (blankloc = strpbrk(ioarea.lname, " "))
*blankloc = '%'; /* translate blanks into % */
while (blankloc = strpbrk(ioarea.fname, " "))
*blankloc = '%'; /* translate blanks into % */
1040 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
if (strpbrk(slname, "%")) {
EXEC SQL OPEN TELE2;
EXEC SQL FETCH TELE2 INTO :pphone;
if (sqlca.sqlcode == NOTFOUND){ /* If no employees */
DSN8MDG(module, "008I", outmsg); /* found, display */
fprintf(report, " %s\n", outmsg); /* error message */
} else {
while (sqlca.sqlcode == 0){
Prt_row();
EXEC SQL FETCH TELE2 INTO :pphone;
} /* endwhile */
} /* endif */
EXEC SQL CLOSE TELE2;
DBERROR:
Sql_err();
} /* end Do_req */
/**********************************************************************/
/* Print a single employee on the report */
/**********************************************************************/
Prt_row()
{
fprintf(report, fmt3, pphone.lastname,
pphone.firstname,
pphone.middleinitial,
pphone.phonenumber,
pphone.employeenumber,
pphone.deptnumber,
pphone.deptname);
}
/**********************************************************************/
/* SQL error handler */
/**********************************************************************/
#pragma linkage(dsntiar, OS)
Sql_err() {
#define data_len 120
#define data_dim 10
struct error_struct {
short int error_len;
char error_text[data_dim][data_len];
} error_message = {data_dim * data_len};
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1041
extern short int dsntiar(struct sqlca *sqlca,
struct error_struct *msg,
int *len);
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSN8BE3
This module uses the class emp_db2 to list or update employee phone numbers from a Db2 database .
/*********************************************************************/
/* */
/* Module name = DSN8BD3 */
/* */
/* Descriptive name = DB2 SAMPLE APPLICATION */
/* PHONE APPLICATION */
/* BATCH */
/* C++ LANGUAGE */
/* */
/* LICENSED MATERIALS - PROPERTY OF IBM */
/* 5625-DB2 */
/* (C) COPYRIGHT 1982, 2003 IBM CORP. ALL RIGHTS RESERVED. */
/* */
/* STATUS = VERSION 8 */
/* */
/* Function = This module uses the class emp_db2 to list or update */
/* employee phone numbers from a DB2 database */
/* */
/* Module type = C++ program */
/* Processor = DB2 precompiler, C++ compiler */
/* Module size = see link edit */
/* Attributes = not reentrant or reusable */
/* */
/* Entry point = DSN8BD3 */
/* Purpose = see function */
/* Linkage = invoked from DSN command processor subcommand RUN */
/* */
/* Input = symbolic label/name = CARDIN */
/* description = INPUT REQUEST FILE */
/* */
/* Output = symbolic label/name = REPORT */
/* description = PRINTED REPORT AND RESULTS */
/* */
1042 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
/* Exit-normal = return code 0 normal completion */
/* */
/* Exit-error = */
/* */
/* Return code = none */
/* */
/* Abend codes = none */
/* */
/* Error-messages = */
/* DSN8000I - REQUEST IS: ... */
/* DSN8068E - INVALID REQUEST, SHOULD BE 'L' OR 'U' */
/* RETURN CODE IS: */
/* */
/* External references = */
/* Routines/services = none */
/* */
/* Data-areas = none */
/* */
/* Control-blocks = none */
/* */
/* Tables = none */
/* */
/* Change-activity = */
/* 02/05/96 Katja KFD0024 C++ sample (D9031) */
/* Created based on C sample */
/* */
/*********************************************************************/
#include <string.h>
/*********************************************************************/
/* Include emp_db2 C++ class definition */
/* (includes other global declarations) */
/*********************************************************************/
#include "DSN8BEH"
/*******************************************************************/
/* Input record structure */
/*******************************************************************/
struct {
char action[2]; /* L for list or U for update */
char lname[16]; /* last name or pattern- L mode */
char fname[13]; /* first name or pattern-L mode */
char eno[7]; /* employee number- U mode */
char newno[5]; /* new phone number- U mode */
} ioarea;
/*******************************************************************/
/* Function to process the current request */
/*******************************************************************/
void Do_req(FILE *outfile)
{
char *blankloc; /* string translation pointer */
/*****************************************************************/
/* Report headings */
/*****************************************************************/
struct
{
char hdr111[30];
char hdr112[22];
char hdr113[30];
} hdr1 = {
"-----------------------------",
" TELEPHONE DIRECTORY ",
"-----------------------------"};
#define rpthdr1 hdr1.hdr111,hdr1.hdr112,hdr1.hdr113
struct
{
char hdr211[10];
char hdr212[11];
char hdr213[ 8];
char hdr214[ 6];
char hdr215[ 9];
char hdr216[ 5];
char hdr217[ 5];
char hdr221[ 7];
char hdr222[ 7];
char hdr223[ 5];
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1043
char hdr224[ 5];
char hdr225[ 5];
} hdr2 = {
"LAST NAME",
"FIRST NAME",
"INITIAL",
"PHONE",
"EMPLOYEE",
"WORK",
"WORK",
"NUMBER",
"NUMBER",
"DEPT",
"DEPT",
"NAME"};
#define rpthdr2 hdr2.hdr211,hdr2.hdr212,hdr2.hdr213,hdr2.hdr214,\
hdr2.hdr215,hdr2.hdr216,hdr2.hdr217,hdr2.hdr221,\
hdr2.hdr222,hdr2.hdr223,hdr2.hdr224,hdr2.hdr225
/*****************************************************************/
/* Report formats */
/*****************************************************************/
static char fmt1[] = "\n %s\n %s\n %s\n";
static char fmt2[] =
" %9s%17s%10s%6s%10s%5s%5s\n%43s%8s%7s%5s%5s\n";
/*****************************************************************/
/* Start processing input record */
/*****************************************************************/
strcpy(slname, ioarea.lname); /* save untranslated last name */
while (blankloc = strpbrk(ioarea.lname, " "))
*blankloc = '%'; /* translate blanks into % */
while (blankloc = strpbrk(ioarea.fname, " "))
*blankloc = '%'; /* translate blanks into % */
if (!strcmp(slname,"* "))
/* List all employees */
proc1.Listall(outfile);
else
{
if (strpbrk(slname, "%"))
/* List generic employees */
proc1.Listsome(outfile,ioarea.lname);
else
/* List specific employee */
proc1.Listone(outfile,slname,ioarea.fname);
} /* else - list selected employees */
break; /* end 'L' request */
/*******************************************************************/
/* Function to read a request from an open file */
/*******************************************************************/
int Read_req(FILE *infile)
{
static char fmt4[] = " %1c%15c%12c%6c%4c%43c"; /* input format */
char trail[43]; /* unused part of input record */
char *newlloc; /* addr of newline char in field */
strcpy(ioarea.action," ");
1044 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
strcpy(ioarea.lname," ");
strcpy(ioarea.fname," ");
strcpy(ioarea.eno," ");
strcpy(ioarea.newno," ");
/* Read the next request */
if (fscanf(infile, fmt4,
ioarea.action,
ioarea.lname,
ioarea.fname,
ioarea.eno,
ioarea.newno,
trail) == 6)
{
if ((newlloc = strpbrk(ioarea.lname, "\n")) != NULL)
*newlloc = ' '; /* change to blank for now */
if ((newlloc = strpbrk(ioarea.fname, "\n")) != NULL)
*newlloc = ' '; /* change to blank for now */
ioarea.eno[6] = '\0';
ioarea.newno[4] = '\0';
return 0;
}
else
return 1;
} /* end Read_req */
/*******************************************************************/
/* Function to echo a request */
/*******************************************************************/
void Echo_req(FILE *outfile)
{
/* Local declarations */
struct /* report header */
{
char hdr011[31];
char hdr012[33];
} hdr0 = {
" REQUEST LAST NAME ",
"FIRST NAME EMPNO NEW XT.NO"};
#define rpthdr0 hdr0.hdr011
/*********************************************************************/
/* main program routine */
/*********************************************************************/
extern main()
{
int retcode;
FILE *cardin; /* Input control cards */
FILE *report; /* Output phone report */
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1045
}
} /* endwhile */
fclose(report);
} /* end main */
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSN8BP3
THIS MODULE LISTS EMPLOYEE PHONE NUMBERS AND UPDATES THEM IF DESIRED.
1046 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* *
* EXTERNAL REFERENCES = *
* ROUTINES/SERVICES = *
* DSN8MPG - ERROR MESSAGE ROUTINE *
* *
* DATA-AREAS = NONE *
* *
* CONTROL-BLOCKS = *
* SQLCA - SQL COMMUNICATION AREA *
* *
* TABLES = NONE *
* *
* CHANGE-ACTIVITY = NONE *
* *
* *
* *PSEUDOCODE* *
* *
* PROCEDURE *
* GET FIRST INPUT *
* DO WHILE MORE INPUT *
* CREATE REPORT HEADING *
* CASE (ACTION) *
* *
* SUBCASE ('L') *
* IF LASTNAME IS '*' THEN *
* LIST ALL EMPLOYEES *
* ELSE *
* IF LASTNAME CONTAINS '%' THEN *
* LIST EMPLOYEES GENERIC *
* ELSE *
* LIST EMPLOYEES SPECIFIC *
* ENDSUB *
* *
* SUBCASE ('U') *
* UPDATE PHONENUMBER FOR EMPLOYEE *
* WRITE CONFIRMATION MESSAGE *
* OTHERWISE *
* INVALID REQUEST *
* ENDSUB *
* *
* ENDCASE *
* GET NEXT INPUT *
* END *
* *
* IF SQL ERROR OCCURS THEN *
* ROLLBACK *
* END. *
* *
*-------------------------------------------------------------------*/
1/**********************/
/* INPUT/OUTPUT FILES */
/**********************/
/********************/
/* ENDFILE HANDLING */
/********************/
/***********************/
/* STRUCTURE FOR INPUT */
/***********************/
DCL 1 IOAREA,
2 ACTION CHAR( 1), /* ACTION */
2 LNAME CHAR(15), /* LAST NAME */
2 FNAME CHAR(12), /* FIRST NAME */
2 ENO CHAR( 6), /* EMPLOYEE NUMBER */
2 NEWNO CHAR( 4); /* PHONE NUMBER */
/***********************/
/* WORK VARIABLES */
/***********************/
/***************************/
/* REPORT HEADER STRUCTURE */
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1047
/***************************/
/******************/
/* REPORT FORMATS */
/******************/
/*********************************/
/* FIELDS SENT TO MESSAGE ROUTINE*/
/*********************************/
/********************/
/* GENERAL DECLARES */
/********************/
DCL (ADDR,
DIM,
PLIRETV,
TRANSLATE,
INDEX) BUILTIN;
DCL EOF BIT(1) INIT ('0'B);
DCL I BIN FIXED(15);
DCL ZERO BIN FIXED(15) STATIC INIT(0);
DCL ONE BIN FIXED(15) STATIC INIT(1);
DCL NOTFOUND BIN FIXED(15) STATIC INIT(100);
1/***********************************/
/* SQL DECLARATION FOR VIEW VPHONE */
/***********************************/
/**************************/
/* SQL COMMUNICATION AREA */
/**************************/
/*******************************/
/* STRUCTURE FOR PPHONE RECORD */
/*******************************/
DCL 1 PPHONE,
2 LASTNAME CHAR(15) VAR,
2 FIRSTNAME CHAR(12) VAR,
1048 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
2 MIDDLEINITIAL CHAR( 1),
2 PHONENUMBER CHAR( 4),
2 EMPLOYEENUMBER CHAR( 6),
2 DEPTNUMBER CHAR( 3),
2 DEPTNAME CHAR(36) VAR;
/***********************************/
/* SQL DECLARATION FOR VIEW VEMPLP */
/***********************************/
/*******************************/
/* STRUCTURE FOR PEMPLP RECORD */
/*******************************/
DCL 1 PEMPLP,
2 EMPLOYEENUMBER CHAR(6),
2 PHONENUMBER CHAR(4);
/***************/
/* SQL CURSORS */
/***************/
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1049
SELECT (ACTION); /* DETERMINE INPUT REQUEST */
/**************************************/
/* LIST ALL EMPLOYEES */
/**************************************/
WHEN ('L') DO; /* LIST EMPLOYEES */
IF LNAME = '*' THEN /* LIST ALL EMPLOYEES */
DO;
EXEC SQL OPEN TELE1; /* OPEN CURSOR FOR SEARCH */
EXEC SQL FETCH TELE1 INTO :PPHONE;/* GET FIRST RECORD */
/**************************************/
/* LIST GENERIC EMPLOYEES */
/**************************************/
ELSE /* SELECT EMPLOYEES BY NAME */
DO; /* SEARCH ON PART OF NAME? */
IF INDEX(LNAMEWK,'%') > ZERO THEN
DO; /* YES: SEARCH ON PART OF */
/* LAST NAME */
EXEC SQL OPEN TELE2; /* OPEN CURSOR FOR SEARCH */
EXEC SQL FETCH TELE2 INTO :PPHONE;/* GET 1ST RECORD */
/**************************************/
/* LIST SPECIFIC EMPLOYEES */
/**************************************/
ELSE /* NO - SEARCH ON LAST NAME */
DO; /* & OPTIONALLY FIRST NAME */
/* SEE IF FIRST NAME ENTERED */
/* IF NOT SET UP FOR ALL NAMES*/
EXEC SQL OPEN TELE3; /* OPEN CURSOR FOR SEARCH */
EXEC SQL FETCH TELE3 INTO :PPHONE;/* GET 1ST RECORD */
/***************************************/
/* UPDATES PHONE NUMBERS FOR EMPLOYEES */
/***************************************/
WHEN ('U') DO; /* TELEPHONE UPDATE */
EXEC SQL UPDATE VEMPLP
1050 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
SET PHONENUMBER = :NEWNO /* CHANGE PHONE NO.*/
WHERE EMPLOYEENUMBER = :ENO;
/***************************/
/* SQL ERROR CODE HANDLING */
/***************************/
DCL
DSNTIAR ENTRY OPTIONS(ASM,INTER,RETCODE);
DCL
DATA_LEN FIXED BIN(31) INIT(120);
DCL
DATA_DIM FIXED BIN(31) INIT(10);
DCL
1 ERROR_MESSAGE AUTOMATIC,
3 ERROR_LEN FIXED BIN(15) UNAL INIT((DATA_LEN*DATA_DIM)),
3 ERROR_TEXT(DATA_DIM) CHAR(DATA_LEN);
/*****************************************/
/* SQL ERROR OCCURRED - GET ERROR MESSAGE*/
/*****************************************/
DBERROR:
/* SQL ERROR */
/* PRINT ERROR MESSAGE*/
CALL DSN8MPG (MODULE, '060E', OUTMSG);
PUT FILE (REPORT) EDIT (OUTMSG,SQLCODE) (SKIP(2),A,F(10));
CALL DSNTIAR( SQLCA , ERROR_MESSAGE , DATA_LEN );
ELSE
DO;
CALL DSN8MPG (MODULE, '075E', OUTMSG);
PUT FILE (REPORT) EDIT /*NON-ZERO RETURN CODE FROM DSNTIAR*/
/*PRINT ERROR MESSAGE */
( OUTMSG, PLIRETV ) ( SKIP(2), A, F(10)) ;
END;
/**********************************************************/
/* SQL RETURN CODE HANDLING WHEN PROCESSING CANNOT PROCEED*/
/**********************************************************/
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1051
END;
ELSE
DO; /* ROLLBACK FAILED,*/
/* RETURN CODE IS: */
CALL DSN8MPG (MODULE, '061E', OUTMSG);
PUT FILE (REPORT) EDIT (OUTMSG,SQLCODE) (SKIP(2),A,F(10));
END;
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSN8BF3
THIS MODULE LISTS EMPLOYEE PHONE NUMBERS AND UPDATES THEM IF DESIRED.
PROGRAM DSN8B3
**********************************************************************
* *
* MODULE NAME = DSN8BF3, PROGRAM DSN8B3 *
* *
* DESCRIPTIVE NAME = DB2 SAMPLE APPLICATION *
* PHONE APPLICATION *
* BATCH *
* FORTRAN *
* *
* LICENSED MATERIALS - PROPERTY OF IBM *
* 5695-DB2 *
* (C) COPYRIGHT 1982, 1995 IBM CORP. ALL RIGHTS RESERVED. *
* *
* STATUS = VERSION 4 *
* *
* FUNCTION = THIS MODULE LISTS EMPLOYEE PHONE NUMBERS AND *
* UPDATES THEM IF DESIRED. *
* *
* NOTES = NONE *
* *
* *
* MODULE TYPE = FORTRAN PROGRAM *
* PROCESSOR = DB2 PRECOMPILER, VS FORTRAN *
* MODULE SIZE = SEE LINK EDIT *
* ATTRIBUTES = NOT REENTRANT OR REUSABLE *
* *
* ENTRY POINT = DSN8BF3 *
* PURPOSE = SEE FUNCTION *
* LINKAGE = INVOKED FROM DSN RUN *
* INPUT = *
* *
* SYMBOLIC LABEL/NAME = FT05F001 *
* DESCRIPTION = INPUT REQUEST FILE *
* *
* SYMBOLIC LABEL/NAME = VPHONE *
* DESCRIPTION = VIEW OF TELEPHONE INFORMATION *
* *
* OUTPUT = *
* *
* SYMBOLIC LABEL/NAME = FT06F001 *
* DESCRIPTION = = PRINTED REPORT AND RESULTS *
* *
* SYMBOLIC LABEL/NAME = VEMPLP *
* DESCRIPTION = VIEW OF EMPLOYEE INFORMATION *
* *
* *
* EXIT-NORMAL = RETURN CODE 0 NORMAL COMPLETION *
* *
* EXIT-ERROR = *
* *
* RETURN CODE = NONE *
* *
* ABEND CODES = NONE *
* *
* ERROR-MESSAGES = *
* DSN8000I - REQUEST IS: ... *
* DSN8004I - EMPLOYEE SUCCESSFULLY UPDATED *
1052 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* DSN8007E - EMPLOYEE DOES NOT EXIST, UPDATE NOT DONE *
* DSN8008I - NO EMPLOYEE FOUND IN TABLE *
* DSN8051I - PROGRAM ENDED *
* DSN8053I - ROLLBACK SUCCESSFUL, ALL UPDATES REMOVED *
* DSN8060E - SQL ERROR, RETURN CODE IS: *
* DSN8061E - ROLLBACK FAILED, RETURN CODE IS: *
* DSN8068E - INVALID REQUEST, SHOULD BE 'L' OR 'U' *
* DSN8075E - MESSAGE FORMAT ERROR, *
* RETURN CODE IS: *
* *
* EXTERNAL REFERENCES = *
* ROUTINES/SERVICES = *
* DSNTIR - TRANSLATE SQLCA INTO MESSAGES *
* *
* DATA-AREAS = NONE *
* *
* CONTROL-BLOCKS = *
* SQLCA - SQL COMMUNICATION AREA *
* *
* TABLES = NONE *
* *
* CHANGE-ACTIVITY = NONE *
* *
* *
* *PSEUDOCODE* *
* *
* PROCEDURE *
* DO WHILE MORE INPUT *
* GET INPUT *
* CREATE REPORT HEADING *
* CASE (ACTION) *
* *
* SUBCASE ('L') *
* IF LASTNAME IS '*' THEN *
* LIST ALL EMPLOYEES *
* ELSE *
* IF LASTNAME CONTAINS '%' THEN *
* LIST EMPLOYEES GENERIC *
* ELSE *
* LIST EMPLOYEES SPECIFIC *
* ENDSUB *
* *
* SUBCASE ('U') *
* UPDATE PHONENUMBER FOR EMPLOYEE *
* WRITE CONFIRMATION MESSAGE *
* *
* OTHERWISE *
* INVALID REQUEST *
* ENDSUB *
* *
* ENDCASE *
* GET NEXT INPUT *
* END *
* *
* IF SQL ERROR OCCURS THEN *
* ROLLBACK *
* END. *
* *
*--------------------------------------------------------------------*
*************************************
* SQL DECLARATION FOR VIEW VPHONE *
*************************************
*************************************
* SQL DECLARATION FOR VIEW VEMPLP *
*************************************
*************************************
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1053
* PPHONE FIELDS *
*************************************
CHARACTER * 15 LASTNM
CHARACTER * 12 FIRSTN
CHARACTER * 1 MIDINI
CHARACTER * 4 PHONEN
CHARACTER * 6 EMPNO
CHARACTER * 3 DEPTNO
CHARACTER * 36 DEPTNM
*************************************
* INPUT FIELDS *
*************************************
CHARACTER * 1 ACTION
CHARACTER * 15 LNAME
CHARACTER * 12 FNAME
CHARACTER * 6 ENO
CHARACTER * 4 NEWNO
CHARACTER * 15 LNAMEW
CHARACTER * 12 FNAMEW
*************************************
* SQL CURSORS *
*************************************
*************************************
* SQL RETURN CODES: OK/NOTFOUND *
*************************************
INTEGER OK/0/,NOTFND/100/
*************************************
* REPORT FORMATS AND INPUT *
*************************************
*************************************
* MESSAGES *
*************************************
CHARACTER * 30 DSN800
CHARACTER * 48 DSN804
CHARACTER * 60 DSN868
CHARACTER * 59 DSN807
CHARACTER * 45 DSN860
CHARACTER * 59 DSN853
CHARACTER * 51 DSN861
CHARACTER * 45 DSN808
CHARACTER * 64 DSN875
CHARACTER * 32 DSN851
1054 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
*************************************
* VARIABLES USED WITH DSNTIR *
*************************************
*************************************
* MISCELLANEOUS VARIABLES *
*************************************
INTEGER I, ICODE
CHARACTER * 15 PERC15
*************************************
* SQL COMMUNICATION AREA *
*************************************
*************************************
* DATA STATEMENTS *
*************************************
DATA PERC15
C/'%%%%%%%%%%%%%%%'/
DATA DSN800
C/'DSN8000I: DSN8BF3-REQUEST IS:'/
DATA DSN804
C/'DSN8004I: DSN8BF3-EMPLOYEE SUCCESSFULLY UPDATED'/
DATA DSN868
C/'DSN8068E: DSN8BF3-INVALID REQUEST, SHOULD BE ''L'' OR ''U'''/
DATA DSN807
C/'DSN8007E: DSN8BF3-EMPLOYEE DOES NOT EXIST, UPDATE NOT DONE'/
DATA DSN860
C/'DSN8060E: DSN8BF3-SQL ERROR, RETURN CODE IS:'/
DATA DSN853
C/'DSN8053I: DSN8BF3-ROLLBACK SUCCESSFUL, ALL UPDATES REMOVED'/
DATA DSN861
C/'DSN8061E: DSN8BF3-ROLLBACK FAILED, SQLCODE IS:'/
DATA DSN808
C/'DSN8008I: DSN8BF3-NO EMPLOYEE FOUND IN TABLE'/
DATA DSN875
C/'DSN8075E: DSN8BF3-MESSAGE FORMAT ROUTINE ERROR, RETURN CODE IS:
C'/
DATA DSN851
C/'DSN8051I: DSN8BF3-PROGRAM ENDED'/
*************************************
* SQL RETURN CODE HANDLING *
*************************************
*************************************
* START OF PROGRAM *
*************************************
*************************************
* CONTINUE WHILE MORE INPUT *
*************************************
1000 CONTINUE
*************************************
* GET NEXT INPUT *
*************************************
*************************************
* CREATE REPORT HEADING *
* SELECT ACTION *
*************************************
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1055
C ' TELEPHONE DIRECTORY ',
C '----------------------------'
WRITE (UNIT=06,FMT=200) 'LAST NAME', 'FIRST NAME', 'INITIAL',
C 'PHONE', 'EMPLOYEE', 'WORK', 'WORK', 'NUMBER',
C 'NUMBER', 'DEPT', 'DEPT', 'NAME'
* **SELECT ACTION
* **LIST EMPLOYEES
IF (ACTION .EQ. 'L') THEN
GOTO 1010
* **PERFORM UPDATE
ELSE IF (ACTION .EQ. 'U') THEN
GOTO 1700
* **INVALID REQUEST
ELSE
GOTO 1800
END IF
1010 CONTINUE
************************************
* ACTION - LIST *
************************************
***************************************
* LIST ALL EMPLOYEES *
***************************************
* **OPEN CURSOR
EXEC SQL OPEN TELE1
NBRETR = 0
1100 CONTINUE
* **GET EMPLOYEE
EXEC SQL FETCH TELE1 INTO
C :LASTNM,:FIRSTN,:MIDINI,
C :PHONEN,:EMPNO,:DEPTNO,:DEPTNM
* **CLOSE CURSOR
EXEC SQL CLOSE TELE1
GO TO 1000
*************************************
* ELSE DETERMINE IF LASTNAME *
* OR FIRSTNAME IS GIVEN *
*************************************
1300 CONTINUE
IPOS=INDEX(LNAME,'%')
********************************************
* REPLACE FIRST BLANK AND FOLLOWING *
* CHARACTERS IN LASTNAME WORK (LNAMEW) *
* WITH CHARACTER % FOR LIKE PREDICATE. *
********************************************
IBLANK=INDEX(LNAME,' ')
IF (IBLANK .GT. 1 ) THEN
LNAMEW = LNAME(1:IBLANK-1)//PERC15(1:15-IBLANK+1)
ELSE IF (IBLANK .EQ. 1) THEN
LNAMEW=PERC15
IPOS = 1
1056 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
ELSE
END IF
********************************************
* REPLACE FIRST BLANK AND FOLLOWING *
* CHARACTERS IN FIRSTNAME WORK (FNAMEW) *
* WITH CHARACTER % FOR LIKE PREDICATE. *
********************************************
IBLANK=INDEX(FNAME,' ')
IF (IBLANK .GT. 1 ) THEN
FNAMEW = FNAME(1:IBLANK-1)//PERC15(1:12-IBLANK+1)
ELSE IF (IBLANK .EQ. 1) THEN
FNAMEW=PERC15(1:12)
ELSE
END IF
********************************************
* LIST GENERIC EMPLOYEES *
********************************************
* **OPEN CURSOR
EXEC SQL OPEN TELE2
NBRETR = 0
1400 CONTINUE
* **GET EMPLOYEES
EXEC SQL FETCH TELE2 INTO
C :LASTNM,:FIRSTN,:MIDINI,
C :PHONEN,:EMPNO,:DEPTNO,:DEPTNM
* **CLOSE CURSOR
EXEC SQL CLOSE TELE2
GOTO 1000
********************************************
* LIST SPECIFIC EMPLOYEES *
********************************************
1600 CONTINUE
* **OPEN CURSOR
EXEC SQL OPEN TELE3
NBRETR = 0
1620 CONTINUE
* **GET EMPLOYEES
EXEC SQL FETCH TELE3 INTO
C :LASTNM,:FIRSTN,:MIDINI,
C :PHONEN,:EMPNO,:DEPTNO,:DEPTNM
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1057
* **CLOSE CURSOR
EXEC SQL CLOSE TELE3
GO TO 1000
************************************************
* UPDATE PHONE NUMBERS FOR EMPLOYEES *
************************************************
1700 CONTINUE
* **PERFORM UPDATE
EXEC SQL UPDATE VEMPLP
C SET PHONENUMBER = :NEWNO
C WHERE EMPLOYEENUMBER = :ENO
* ** INVALID REQUEST
* ** PRINT ERROR MESSAGE
1800 CONTINUE
WRITE (UNIT=06,FMT=500) DSN868
GO TO 1000
******************
* END OF LOOP *
* FOR MORE INPUT *
******************
* ** THIS LABEL IS
* ** BRANCHED TO FOR
* ** END OF DATA
3000 CONTINUE
WRITE (UNIT=06,FMT=800)
WRITE (UNIT=06,FMT=500) DSN851
RETURN
*********************************************
* IF SQL ERROR OCCURRED - GET ERROR MESSAGE*
*********************************************
4000 CONTINUE
* **SQL ERROR
* **PRINT ERROR MESSAGE
WRITE (UNIT=06,FMT=600) DSN860, SQLCOD
CALL DSNTIR ( ERRLEN, ERRTXT, ICODE )
DO 4100 I=1, 10
WRITE (UNIT=06,FMT=500) ERRTXT(I)
4100 CONTINUE
ELSE
* **ERROR DETECTED BY
* **MESSAGE FORMAT
* **ROUTINE
* **PRINT ERROR MESSAGE
END IF
* **PERFORM ROLLBACK
EXEC SQL ROLLBACK
IF (SQLCOD .EQ. OK) THEN
1058 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* **ROLLBACK SUCCESSFUL
* **PRINT CONFIRMATION
* **MESSAGE
WRITE (UNIT=06,FMT=500) DSN853
ELSE
* **ROLLBACK FAILED
* **PRINT ERROR MESSAGE
WRITE (UNIT=06,FMT=600) DSN861, SQLCOD
END IF
RETURN
END
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSN8HC3
THIS MODULE DISPLAYS THE Db2 DEPARTMENT AND EMPLOYEE TABLES AND UPDATES THEM IF
DESIRED.
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1059
* * 00005700
* SYMBOLIC LABEL/NAME = DSN8SSH5 * 00005800
* DESCRIPTION = EMPLOYEE PANEL * 00005900
* * 00006000
* SYMBOLIC LABEL/NAME = VHDEPT * 00006100
* DESCRIPTION = VIEW OF DEPARTMENT DATA * 00006200
* * 00006300
* SYMBOLIC LABEL/NAME = VEMP * 00006400
* DESCRIPTION = VIEW OF EMPLOYEE DATA * 00006500
* * 00006600
* OUTPUT = PARAMETERS EXPLICITLY RETURNED: * 00006700
* OUTPUT-MESSAGE: * 00006800
* * 00006900
* SYMBOLIC LABEL/NAME = DSN8SSH * 00007000
* DESCRIPTION = MAIN MENU PANEL * 00007100
* * 00007200
* SYMBOLIC LABEL/NAME = DSN8SSH1 * 00007300
* DESCRIPTION = DEPARTMENT STRUCTURE PANEL * 00007400
* * 00007500
* SYMBOLIC LABEL/NAME = DSN8SSH2 * 00007600
* DESCRIPTION = DEPARTMENT PANEL * 00007700
* * 00007800
* SYMBOLIC LABEL/NAME = DSN8SSH3 * 00007900
* DESCRIPTION = SELECTION LIST PANEL * 00008000
* * 00008100
* SYMBOLIC LABEL/NAME = DSN8SSH4 * 00008200
* DESCRIPTION = SELECTION LIST PANEL * 00008300
* * 00008400
* SYMBOLIC LABEL/NAME = DSN8SSH5 * 00008500
* DESCRIPTION = EMPLOYEE PANEL * 00008600
* * 00008700
* EXIT-NORMAL = RETURN CODE 0 NORMAL COMPLETION * 00008800
* * 00008900
* EXIT-ERROR = * 00009000
* * 00009100
* RETURN CODE = NONE * 00009200
* * 00009300
* ABEND CODES = NONE * 00009400
* * 00009500
* * 00009600
* ERROR-MESSAGES = * 00009700
* DSN8001I - EMPLOYEE NOT FOUND * 00009800
* DSN8002I - EMPLOYEE SUCCESSFULLY ADDED * 00009900
* DSN8003I - EMPLOYEE SUCCESSFULLY ERASED * 00010000
* DSN8004I - EMPLOYEE SUCCESSFULLY UPDATED * 00010100
* DSN8005E - EMPLOYEE EXISTS ALREADY, ADD NOT DONE * 00010200
* DSN8006E - EMPLOYEE DOES NOT EXIST, ERASE NOT DONE * 00010300
* DSN8007E - EMPLOYEE DOES NOT EXIST, UPDATE NOT DONE* 00010400
* DSN8011I - DEPARTMENT NOT FOUND * 00010500
* DSN8012I - DEPARTMENT SUCCESSFULLY ADDED * 00010600
* DSN8013I - DEPARTMENT SUCCESSFULLY ERASED * 00010700
* DSN8014I - DEPARTMENT SUCCESSFULLY UPDATED * 00010800
* DSN8015E - DEPARTMENT EXISTS ALREADY, ADD NOT DONE * 00010900
* DSN8016E - DEPARTMENT DOES NOT EXIST, ERASE NOT * 00011000
* DONE * 00011100
* DSN8017E - DEPARTMENT DOES NOT EXIST, UPDATE NOT * 00011200
* DONE * 00011300
* DSN8060E - SQL ERROR, RETURN CODE IS: * 00011400
* DSN8074E - DATA IS TOO LONG FOR SEARCH CRITERIA * 00011500
* DSN8079E - CONNECTION NOT ESTABLISHED * 00011600
* DSN8200E - INVALID DEPARTMENT NUMBER, EMPLOYEE NOT * 00011700
* ADDED * 00011800
* DSN8203E - INVALID WORK DEPT, EMPLOYEE NOT UPDATED * 00011900
* DSN8210E - INVALID MGRNO, DEPARTMENT NOT ADDED * 00012000
* DSN8213E - INVALID ADMIN DEPT ID, DEPARTMENT NOT * 00012100
* ADDED * 00012200
* DSN8214E - INVALID MANAGER ID, DEPARTMENT NOT * 00012300
* UPDATED * 00012400
* DSN8215E - INVALID ADMIN DEPT ID, DEPARTMENT NOT * 00012500
* UPDATED * 00012600
* DSN8216E - DEPT NOT AT SPECIFIED LOCATION, EMPLOYEE* 00012700
* NOT ADDED * 00012800
* DSN8217E - DEPT NOT AT SPECIFIED LOCATION, EMP NOT * 00012900
* UPDATED * 00013000
* * 00013100
* EXTERNAL REFERENCES = * 00013200
* ROUTINES/SERVICES = * 00013300
* DSN8MCG - ERROR MESSAGE ROUTINE * 00013400
* ISPLINK - ISPF SERVICES ROUTINE * 00013500
* * 00013600
* DATA-AREAS = * 00013700
* NONE * 00013800
1060 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* * 00013900
* CONTROL-BLOCKS = * 00014000
* SQLCA - SQL COMMUNICATION AREA * 00014100
* * 00014200
* TABLES = NONE * 00014300
* * 00014400
* * 00014500
* CHANGE-ACTIVITY = NONE * 00014600
* * 00014700
* *PSEUDOCODE* * 00014800
* * 00014900
* SET UP RETURN CODE HANDLING 0000-PROGRAM-START* 00015000
* SET PREVIOUS LOCATION TO LOCAL * 00015100
* DO UNTIL NO MORE TERMINAL INPUT * 00015200
* GET PANEL INPUT 1000-MAIN-LOOP * 00015300
* IF CURRENT AND PREVIOUS LOCATION DIFFER THEN * 00015400
* IF REMOTE LOCATION THEN * 00015500
* CONNECT TO REMOTE LOCATION * 00015600
* ELSE RESET TO LOCAL LOCATION * 00015700
* DETERMINE PROCESSING REQUEST * 00015800
* IF ACTION FIELD ADD: * 00015900
* IF OBJECT FIELD IS DE: * 00016000
* ADD RECORD TO VHDEPT TABLES 2000-ADDDEPT * 00016100
* AT ALL LOCATIONS * 00016200
* ELSE IF OBJECT FIELD IS EM: * 00016300
* ADD RECORD TO VEMP TABLE 3000-ADDEMP * 00016400
* ELSE: * 00016500
* ELSE: * 00016600
* IF OBJECT FIELD DE OR DS: 5000-DEPARTMENT * 00016700
* IF "LIST GENERIC": 5100-GENDEPT * 00016800
* CHOOSE CURSOR BASED ON 5110-GETDEPTTAB * 00016900
* SEARCH CRITERIA AND DATA * 00017000
* CREATE ISPF TABLE * 00017100
* DO UNTIL NO MORE RECORDS: * 00017200
* FETCH RECORD * 00017300
* STORE RECORD IN TABLE * 00017400
* DISPLAY DEPARTMENT LIST 5121-GETDEPT * 00017500
* ON SCREEN * 00017600
* STORE SELECTED DEPT ID IN * 00017700
* HOST VARIABLE * 00017800
* ELSE: * 00017900
* IF OBJFLD IS DE: 5200-DISPLAYDEPT * 00018000
* FETCH SELECTED DEPT * 00018100
* DISPLAY DEPT ON SCREEN 5210-DISDEPTACT * 00018200
* IF ACTION IS ERASE: 5220-ERASEDEPT * 00018300
* DELETE DEPARTMENT AT 5221-DELDEPTS * 00018400
* ALL LOCATIONS * 00018500
* PERFORM CASCADE DELETE 5223-DELDEPEND * 00018600
* OF DEPENDENT DEPTS * 00018700
* AT ALL LOCATIONS * 00018800
* ELSE IF ACTION IS UPDATE: 5230-UPDATEDEPT * 00018900
* UPDATE DEPARTMENT AT * 00019000
* ALL LOCATIONS * 00019100
* ELSE: * 00019200
* ELSE (OBJFLD IS DS): 5300-STRUCTURE * 00019300
* FETCH SELECTED DEPT * 00019400
* DISPLAY SELECTED DEPT * 00019500
* CREATE ISPF TABLE 5310-DISSTR * 00019600
* DO UNTIL NO MORE RECORDS: 5312-GETSTRTAB * 00019700
* FETCH DEPT REPORTING TO * 00019800
* SELECTED DEPT * 00019900
* STORE RECORD IN TABLE * 00020000
* DISPLAY DEPT LIST ON SCREEN * 00020100
* ELSE (OBJFLD IS EM): 6000-EMPLOYEE * 00020200
* IF "LIST GENERIC": 6100-GENEMP * 00020300
* CHOOSE CURSOR BASED ON 6110-GETEMPTAB * 00020400
* SEARCH CRITERIA AND DATA * 00020500
* CREATE ISPF TABLE * 00020600
* DO UNTIL NO MORE RECORDS: * 00020700
* FETCH RECORD * 00020800
* STORE RECORD IN TABLE * 00020900
* DISPLAY DEPARTMENT LIST 6121-GETEMP * 00021000
* ON SCREEN * 00021100
* STORE SELECTED DEPT ID IN * 00021200
* HOST VARIABLE * 00021300
* ELSE: * 00021400
* FETCH SELECTED EMPLOYEE 6200-DISPLAYEMP * 00021500
* DISPLAY EMPLOYEE ON SCREEN * 00021600
* IF ACTION IS ERASE: 6220-ERASEEMP * 00021700
* DELETE EMPLOYEE FROM VEMP * 00021800
* ELSE IF ACTION IS UPDATE: 6230-UPDATEEMP * 00021900
* UPDATE EMPLOYEE IN VEMP * 00022000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1061
* END-DO UNTIL NO MORE TERMINAL INPUT * 00022100
* RELEASE ALL CONNECTIONS * 00022200
*---------------------------------------------------------------* 00022300
ENVIRONMENT DIVISION. 00022400
*------------------------ 00022500
INPUT-OUTPUT SECTION. 00022600
FILE-CONTROL. 00022700
SELECT MSGOUT ASSIGN TO UT-S-SYSPRINT. 00022800
00022900
DATA DIVISION. 00023000
*------------------------ 00023100
FILE SECTION. 00023200
00023300
FD MSGOUT 00023400
RECORD CONTAINS 71 CHARACTERS 00023500
LABEL RECORDS ARE OMITTED. 00023600
01 MSGREC PIC X(71). 00023700
00023800
WORKING-STORAGE SECTION. 00023900
*---------------------------------------------------------------* 00024000
77 COIBM PIC X(54) VALUE IS 00024100
'COPYRIGHT = 5665-DB2 (C) COPYRIGHT IBM CORP 1982, 1990'. 00024200
77 MODULE PIC X(07) VALUE 'DSN8HC3'. 00024300
77 MSGS-VAR PIC X(08) VALUE 'DSN8MSGS'. 00024400
77 MSGCODE PIC X(06). 00024500
77 SEL-EXIT PIC X(01). 00024600
77 GEND-EXIT PIC X(01). 00024700
77 GENE-EXIT PIC X(01). 00024800
77 SPECIAL-EXIT PIC X(01). 00024900
77 ROWS-CHANGED PIC 9(04). 00025000
77 NUMROWS PIC 9(08). 00025100
77 PERCENT-COUNTER PIC S9(04) COMP. 00025200
77 LENGTH-COUNTER PIC S9(04) COMP. 00025300
77 W-BLANK PIC X(01) VALUE ' '. 00025400
*--------------------------------------------------------------* 00025500
* ISPF DIALOG VARIABLE NAMES * 00025600
*--------------------------------------------------------------* 00025700
EXEC SQL INCLUDE SQLCA END-EXEC. 00025800
01 LIST-PANEL-VARS. 00025900
03 CH-VAR PIC X(08) VALUE 'ZTDSELS '. 00026000
03 QROWS PIC X(08) VALUE 'QROWS '. 00026100
* 00026200
* ACTION PANEL VARIABLES 00026300
* 00026400
03 ACT-VAR PIC X(08) VALUE 'A '. 00026500
03 OBJ-VAR PIC X(08) VALUE 'OB '. 00026600
03 SEA-VAR PIC X(08) VALUE 'SE '. 00026700
03 LOC-VAR PIC X(08) VALUE 'LOCATION'. 00026800
03 DAT-VAR PIC X(08) VALUE 'NAMEID '. 00026900
* 00027000
* DEPARTMENT STRUCTURE VARIABLES 00027100
* 00027200
03 DN1M-VAR PIC X(08) VALUE 'MDEPIDP '. 00027300
03 DNAME1M-VAR PIC X(08) VALUE 'MDEPNAMP'. 00027400
03 DMGR1M-VAR PIC X(08) VALUE 'MMGRIDP '. 00027500
03 EFN1M-VAR PIC X(08) VALUE 'MMGNAMP '. 00027600
03 EMI1M-VAR PIC X(08) VALUE 'MMGMIP '. 00027700
03 ELN1M-VAR PIC X(08) VALUE 'MMGLNMP '. 00027800
03 DN1-VAR PIC X(08) VALUE 'DEPIDP '. 00027900
03 DNAME1-VAR PIC X(08) VALUE 'DEPNAMP '. 00028000
03 DMGR1-VAR PIC X(08) VALUE 'MGRIDP '. 00028100
03 EFN1-VAR PIC X(08) VALUE 'MGNAMP '. 00028200
03 EMI1-VAR PIC X(08) VALUE 'MGMIP '. 00028300
03 ELN1-VAR PIC X(08) VALUE 'MGLNMP '. 00028400
* 00028500
* DISPLAY PANEL VARIABLES 00028600
* 00028700
03 ACTL-VAR PIC X(08) VALUE 'PACTION '. 00028800
03 DN2-VAR PIC X(08) VALUE 'DEPID2 '. 00028900
03 DNAME2-VAR PIC X(08) VALUE 'DEPNAM2 '. 00029000
03 DMGR2-VAR PIC X(08) VALUE 'MGRID2 '. 00029100
03 DADM-VAR PIC X(08) VALUE 'MDEPID2 '. 00029200
03 DLOC-VAR PIC X(08) VALUE 'DEPLOC2 '. 00029300
03 EN2-VAR PIC X(08) VALUE 'EMPID2 '. 00029400
03 EFN2-VAR PIC X(08) VALUE 'EMPNAM2 '. 00029500
03 EMI2-VAR PIC X(08) VALUE 'EMPMI2 '. 00029600
03 ELN2-VAR PIC X(08) VALUE 'MLNM2 '. 00029700
03 EWD-VAR PIC X(08) VALUE 'DEPIDB2 '. 00029800
* 00029900
* SELECT DEPARTMENT VARIABLES 00030000
* 00030100
03 SD-VAR PIC X(08) VALUE 'SELECT '. 00030200
1062 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
03 DN3-VAR PIC X(08) VALUE 'DID '.
00030300
03 DNAME3-VAR PIC X(08) VALUE 'DEPNGEN '.
00030400
03 DMGR3-VAR PIC X(08) VALUE 'MID '.
00030500
03 MGRN-VAR PIC X(08) VALUE 'MNGEN '.
00030600
* 00030700
* SELECT EMPLOYEE VARIABLES 00030800
* 00030900
03 SEM-VAR PIC X(08) VALUE 'SELEC4 '. 00031000
03 EN4-VAR PIC X(08) VALUE 'EMPID4 '. 00031100
03 EMPN-VAR PIC X(08) VALUE 'EMPNM4 '. 00031200
03 DN4-VAR PIC X(08) VALUE 'DEPID4 '. 00031300
03 DNAME4-VAR PIC X(08) VALUE 'DPNAME4 '. 00031400
* 00031500
* TABLE VARIABLES 00031600
* 00031700
03 DEPT-TABLE PIC X(08) VALUE 'DSN8DTAB'. 00031800
03 DS-TABLE PIC X(08) VALUE 'DSN8STAB'. 00031900
03 EMP-TABLE PIC X(08) VALUE 'DSN8ESEL'. 00032000
* 00032100
* VARIABLE LISTS 00032200
* 00032300
03 ACTION-VARS PIC X(27) VALUE IS 00032400
'( A OB SE LOCATION NAMEID )'. 00032500
03 IDEN-VAR PIC X(19) VALUE IS 00032600
'( PACTION )'. 00032700
03 ADD-DEPT-VARS PIC X(40) VALUE IS 00032800
'( DEPID2 DEPNAM2 MGRID2 MDEPID2 DEPLOC2)'. 00032900
03 DEPT-VARS PIC X(77) VALUE IS 00033000
'( DEPID2 DEPNAM2 MGRID2 MDEPID2 DEPLOC2 EMPID2 EMPNAM2 EMPMI00033100
- '2 MLNM2 DEPIDB2 )'. 00033200
03 ADD-EMP-VARS PIC X(39) VALUE IS 00033300
'( EMPID2 EMPNAM2 EMPMI2 MLNM2 DEPIDB2 )'. 00033400
03 SEL-EMP-VARS PIC X(47) VALUE IS 00033500
'( ZTDSELS SELEC4 EMPID4 EMPNM4 DEPID4 DPNAME4 )'. 00033600
03 SEL-DEPT-VARS PIC X(40) VALUE IS 00033700
'( ZTDSELS SELECT DID DEPNGEN MID MNGEN )'. 00033800
03 HEAD-DEPT-VARS PIC X(51) VALUE IS 00033900
'( MDEPIDP MDEPNAMP MMGRIDP MMGNAMP MMGMIP MMGLNMP )'. 00034000
03 DS-VARS PIC X(45) VALUE IS 00034100
'( DEPIDP DEPNAMP MGRIDP MGNAMP MGMIP MGLNMP )'. 00034200
01 PANEL-VARIABLE-LENGTHS. 00034300
03 CH-VAR-STG PIC 9(06) COMP VALUE 04. 00034400
03 QROWS-STG PIC 9(06) COMP VALUE 08. 00034500
* 00034600
* ACTION PANEL VARIABLES 00034700
* 00034800
03 AC-VAR-STG PIC 9(06) COMP VALUE 01. 00034900
03 OB-VAR-STG PIC 9(06) COMP VALUE 02. 00035000
03 SE-VAR-STG PIC 9(06) COMP VALUE 02. 00035100
03 LO-VAR-STG PIC 9(06) COMP VALUE 16. 00035200
03 DT-VAR-STG PIC 9(06) COMP VALUE 36. 00035300
* 00035400
* DEPARTMENT STRUCTURE VARIABLES 00035500
* 00035600
03 DN1M-VAR-STG PIC 9(06) COMP VALUE 03. 00035700
03 DNAME1M-VAR-STG PIC 9(06) COMP VALUE 36. 00035800
03 DMGR1M-VAR-STG PIC 9(06) COMP VALUE 06. 00035900
03 EFN1M-VAR-STG PIC 9(06) COMP VALUE 12. 00036000
03 EMI1M-VAR-STG PIC 9(06) COMP VALUE 01. 00036100
03 ELN1M-VAR-STG PIC 9(06) COMP VALUE 15. 00036200
03 DN1-VAR-STG PIC 9(06) COMP VALUE 03. 00036300
03 DNAME1-VAR-STG PIC 9(06) COMP VALUE 36. 00036400
03 DMGR1-VAR-STG PIC 9(06) COMP VALUE 06. 00036500
03 EFN1-VAR-STG PIC 9(06) COMP VALUE 12. 00036600
03 EMI1-VAR-STG PIC 9(06) COMP VALUE 01. 00036700
03 ELN1-VAR-STG PIC 9(06) COMP VALUE 15. 00036800
* 00036900
* DISPLAY PANEL VARIABLES 00037000
* 00037100
03 ACL-VAR-STG PIC 9(06) COMP VALUE 07. 00037200
03 OCL-VAR-STG PIC 9(06) COMP VALUE 10. 00037300
03 DN2-VAR-STG PIC 9(06) COMP VALUE 03. 00037400
03 DNAME2-VAR-STG PIC 9(06) COMP VALUE 36. 00037500
03 DMGR2-VAR-STG PIC 9(06) COMP VALUE 06. 00037600
03 DADM-VAR-STG PIC 9(06) COMP VALUE 03. 00037700
03 DLOC-VAR-STG PIC 9(06) COMP VALUE 16. 00037800
03 EN2-VAR-STG PIC 9(06) COMP VALUE 06. 00037900
03 EFN2-VAR-STG PIC 9(06) COMP VALUE 12. 00038000
03 EMI2-VAR-STG PIC 9(06) COMP VALUE 01. 00038100
03 ELN2-VAR-STG PIC 9(06) COMP VALUE 15. 00038200
03 EWD-VAR-STG PIC 9(06) COMP VALUE 03. 00038300
* 00038400
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1063
* SELECT DEPARTMENT VARIABLES 00038500
* 00038600
03 SD-VAR-STG PIC 9(06) COMP VALUE 01. 00038700
03 DN3-VAR-STG PIC 9(06) COMP VALUE 03. 00038800
03 DNAME3-VAR-STG PIC 9(06) COMP VALUE 36. 00038900
03 DMGR3-VAR-STG PIC 9(06) COMP VALUE 06. 00039000
03 MGRN-VAR-STG PIC 9(06) COMP VALUE 18. 00039100
* 00039200
* SELECT EMPLOYEE VARIABLES 00039300
* 00039400
03 SEM-VAR-STG PIC 9(06) COMP VALUE 01. 00039500
03 EN4-VAR-STG PIC 9(06) COMP VALUE 06. 00039600
03 EMPN-VAR-STG PIC 9(06) COMP VALUE 17. 00039700
03 DN4-VAR-STG PIC 9(06) COMP VALUE 03. 00039800
03 DNAME4-VAR-STG PIC 9(06) COMP VALUE 36. 00039900
* 00040000
03 MSGS-VAR-STG PIC 9(06) COMP VALUE 79. 00040100
*---------------------------------------------------------------* 00040200
* ISPF DIALOG SERVICES DECLARATIONS * 00040300
*---------------------------------------------------------------* 00040400
01 I-VDEFINE PIC X(08) VALUE 'VDEFINE '. 00040500
01 I-VGET PIC X(08) VALUE 'VGET '. 00040600
01 I-VPUT PIC X(08) VALUE 'VPUT '. 00040700
01 I-DISPLAY PIC X(08) VALUE 'DISPLAY '. 00040800
01 I-TBDISPL PIC X(08) VALUE 'TBDISPL '. 00040900
01 I-TBTOP PIC X(08) VALUE 'TBTOP '. 00041000
01 I-TBCREATE PIC X(08) VALUE 'TBCREATE'. 00041100
01 I-TBCLOSE PIC X(08) VALUE 'TBCLOSE '. 00041200
01 I-TBADD PIC X(08) VALUE 'TBADD '. 00041300
01 I-TBGET PIC X(08) VALUE 'TBGET '. 00041400
01 I-TBQUERY PIC X(08) VALUE 'TBQUERY '. 00041500
*---------------------------------------------------------------* 00041600
* ISPF CALL MODIFIERS * 00041700
*---------------------------------------------------------------* 00041800
01 I-NOWRITE PIC X(08) VALUE 'NOWRITE '. 00041900
01 I-REPLACE PIC X(08) VALUE 'REPLACE '. 00042000
01 I-CHAR PIC X(08) VALUE 'CHAR '. 00042100
*---------------------------------------------------------------* 00042200
* ISPF PANEL NAMES * 00042300
*---------------------------------------------------------------* 00042400
01 SEL-PANEL PIC X(08) VALUE 'DSN8SSH '. 00042500
01 STR-PANEL PIC X(08) VALUE 'DSN8SSH1'. 00042600
01 DEPT-PANEL PIC X(08) VALUE 'DSN8SSH2'. 00042700
01 GEND-PANEL PIC X(08) VALUE 'DSN8SSH3'. 00042800
01 GENE-PANEL PIC X(08) VALUE 'DSN8SSH4'. 00042900
01 EMP-PANEL PIC X(08) VALUE 'DSN8SSH5'. 00043000
*---------------------------------------------------------------* 00043100
* LOCAL-VARIABLES * 00043200
*---------------------------------------------------------------* 00043300
01 LOCAL-VARIABLES. 00043400
03 DATAW PIC X(36). 00043500
03 GENDATA PIC X(36). 00043600
03 SEL-DEPT PIC X(01). 00043700
03 SEL-EMP PIC X(01). 00043800
03 MGR-NAME PIC X(18). 00043900
03 EMP-NAME PIC X(17). 00044000
03 TOKEN PIC X(70). 00044100
03 TEMPLOC PIC X(16). 00044200
03 PREVLOC PIC X(16). 00044300
03 TEMPDEPT PIC X(03). 00044400
03 CURDEPT PIC X(03). 00044500
03 DELDEPT PIC X(03). 00044600
03 STACKTOP PIC S9(04). 00044700
03 DEPTPTR PIC S9(04). 00044800
03 LISTPTR PIC S9(04). 00044900
03 LOCPTR PIC S9(04). 00045000
03 LOCTOP PIC S9(04). 00045100
03 CONVSQL PIC S9(15) COMP-3. 00045200
03 OUTMSG PIC X(69). 00045300
03 TMSG REDEFINES OUTMSG. 00045400
05 TMSGTXT PIC X(46). 00045500
05 FILLER PIC X(23). 00045600
03 MSGS PIC X(79) VALUE SPACES. 00045700
03 MSGS-DETAIL REDEFINES MSGS. 00045800
05 OUT-MESSAGE PIC X(46). 00045900
05 SQL-CODE PIC +(04). 00046000
05 FILLER PIC X(29). 00046100
00046200
01 CONV PIC S9(15) COMP-3. 00046300
01 DEPTS-TABLE. 00046400
03 DEPTS OCCURS 1000 TIMES. 00046500
05 DEPTS-ITEM PIC X(03). 00046600
1064 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
01 DEPTLIST-TABLE. 00046700
03 DEPTLIST OCCURS 1000 TIMES. 00046800
05 DEPTLIST-ITEM PIC X(03). 00046900
01 LOCLIST-TABLE. 00047000
03 LOCLIST OCCURS 1000 TIMES. 00047100
05 LOCLIST-ITEM PIC X(16). 00047200
*---------------------------------------------------------------* 00047300
* ACTION PANEL - IO AREA * 00047400
*---------------------------------------------------------------* 00047500
01 PGM-PANEL-VARS. 00047600
03 ACTION PIC X(01). 00047700
03 OBJFLD PIC X(02). 00047800
03 SEARCH-CRIT PIC X(02). 00047900
03 LOCATION PIC X(16). 00048000
03 NAMEID PIC X(36). 00048100
03 ACTION-LIST PIC X(07). 00048200
*---------------------------------------------------------------* 00048300
* EMPLOYEE RECORD - IO AREA * 00048400
*---------------------------------------------------------------* 00048500
01 EMP-RECORD. 00048600
02 EMP-NUMB PIC X(06). 00048700
02 EMP-FIRST-NAME PIC X(12). 00048800
02 EMP-MID-INIT PIC X(01). 00048900
02 EMP-LAST-NAME PIC X(15). 00049000
02 EMP-WORK-DEPT PIC X(03). 00049100
01 EMP-INDICATOR-TABLE. 00049200
02 WORK-DEPT-IND PIC S9(4) COMP. 00049300
*---------------------------------------------------------------* 00049400
* EMPLOYEE RECORD FOR DEPT STRUCTURE - IO AREA * 00049500
*---------------------------------------------------------------* 00049600
01 EMP1-RECORD. 00049700
02 EMP1-NUMB PIC X(06). 00049800
02 EMP1-FIRST-NAME PIC X(12). 00049900
02 EMP1-MID-INIT PIC X(01). 00050000
02 EMP1-LAST-NAME PIC X(15). 00050100
02 EMP1-WORK-DEPT PIC X(03). 00050200
01 EMP1-INDICATOR-TABLE. 00050300
02 WORK1-DEPT-IND PIC S9(4) COMP. 00050400
*---------------------------------------------------------------* 00050500
* DEPARTMENT RECORD - IO AREA * 00050600
*---------------------------------------------------------------* 00050700
01 DEPT-RECORD. 00050800
02 DEPT-NUMB PIC X(03). 00050900
02 DEPT-NAME PIC X(36). 00051000
02 DEPT-MGR PIC X(06). 00051100
02 DEPT-ADMR PIC X(03). 00051200
02 DEPT-LOC PIC X(16). 00051300
01 DEPT-INDICATOR-TABLE. 00051400
02 DEPT-MGR-IND PIC S9(4) COMP. 00051500
*---------------------------------------------------------------* 00051600
* DEPARTMENT RECORD FOR DEPT STRUCTURE - IO AREA * 00051700
*---------------------------------------------------------------* 00051800
01 DEPT1-RECORD. 00051900
02 DEPT1-NUMB PIC X(03). 00052000
02 DEPT1-NAME PIC X(36). 00052100
02 DEPT1-MGR PIC X(06). 00052200
02 DEPT1-ADMR PIC X(03). 00052300
02 DEPT1-LOC PIC X(16). 00052400
01 DEPT1-INDICATOR-TABLE. 00052500
02 DEPT1-MGR-IND PIC S9(4) COMP. 00052600
*---------------------------------------------------------------* 00052700
* SQLCA OUTPUT * 00052800
*---------------------------------------------------------------* 00052900
00053000
01 SQLCA-LINE0. 00053100
02 FILLER PIC X(45) VALUE 00053200
'DSN8060E DSN8HC3 SQL ERROR, RETURN CODE IS: '. 00053300
02 SQLCODE-MSG PIC +(16). 00053400
02 FILLER PIC X(11) VALUE SPACES. 00053500
00053600
01 SQLCA-LINE1. 00053700
02 FILLER PIC X(05) VALUE SPACES. 00053800
02 SQLCAID-NAME PIC X(13) VALUE 'SQLCAID = '. 00053900
02 SQLCAID-VALUE PIC X(08). 00054000
02 FILLER PIC X(14) VALUE SPACES. 00054100
02 SQLCABC-NAME PIC X(13) VALUE 'SQLABC = '. 00054200
02 SQLCABC-VALUE PIC Z(15). 00054300
02 FILLER PIC X(03) VALUE SPACES. 00054400
00054500
01 SQLCA-LINE2. 00054600
02 FILLER PIC X(05) VALUE SPACES. 00054700
02 SQLCODE-NAME PIC X(13) VALUE 'SQLCODE = '. 00054800
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1065
02 SQLCODE-VALUE PIC +(16). 00054900
02 FILLER PIC X(07) VALUE SPACES. 00055000
02 SQLERRML-NAME PIC X(13) VALUE 'SQLERRML = '. 00055100
02 SQLERRML-VALUE PIC Z(15). 00055200
02 FILLER PIC X(03) VALUE SPACES. 00055300
00055400
01 SQLCA-LINE3. 00055500
02 FILLER PIC X(05) VALUE SPACES. 00055600
02 SQLERRMC-NAME PIC X(13) VALUE 'SQLERRMC = '. 00055700
02 FILLER PIC X(53) VALUE SPACES. 00055800
00055900
01 SQLCA-LINE4. 00056000
02 FILLER PIC X(01) VALUE SPACES. 00056100
02 SQLERRMC-VALUE PIC X(70). 00056200
00056300
01 SQLCA-LINE5. 00056400
02 FILLER PIC X(05) VALUE SPACES. 00056500
02 SQLERRP-NAME PIC X(13) VALUE 'SQLERRP = '. 00056600
02 SQLERRP-VALUE PIC X(08). 00056700
02 FILLER PIC X(14) VALUE SPACES. 00056800
02 SQLERRD1-NAME PIC X(13) VALUE 'SQLERRD(1) = '. 00056900
02 SQLERRD1-VALUE PIC Z(14)9. 00057000
02 FILLER PIC X(03) VALUE SPACES. 00057100
00057200
01 SQLCA-LINE6. 00057300
02 FILLER PIC X(05) VALUE SPACES. 00057400
02 SQLERRD2-NAME PIC X(13) VALUE 'SQLERRD(2) = '. 00057500
02 SQLERRD2-VALUE PIC Z(14)9. 00057600
02 FILLER PIC X(07) VALUE SPACES. 00057700
02 SQLERRD3-NAME PIC X(13) VALUE 'SQLERRD(3) = '. 00057800
02 SQLERRD3-VALUE PIC Z(14)9. 00057900
02 FILLER PIC X(03) VALUE SPACES. 00058000
00058100
01 SQLCA-LINE7. 00058200
02 FILLER PIC X(05) VALUE SPACES. 00058300
02 SQLERRD4-NAME PIC X(13) VALUE 'SQLERRD(4) = '. 00058400
02 SQLERRD4-VALUE PIC Z(14)9. 00058500
02 FILLER PIC X(07) VALUE SPACES. 00058600
02 SQLERRD5-NAME PIC X(13) VALUE 'SQLERRD(5) = '. 00058700
02 SQLERRD5-VALUE PIC Z(14)9. 00058800
02 FILLER PIC X(03) VALUE SPACES. 00058900
00059000
01 SQLCA-LINE8. 00059100
02 FILLER PIC X(05) VALUE SPACES. 00059200
02 SQLERRD6-NAME PIC X(13) VALUE 'SQLERRD(6) = '. 00059300
02 SQLERRD6-VALUE PIC Z(14)9. 00059400
02 FILLER PIC X(07) VALUE SPACES. 00059500
02 SQLWARN0-NAME PIC X(13) VALUE 'SQLWARN0 = '. 00059600
02 SQLWARN0-VALUE PIC X. 00059700
02 FILLER PIC X(17) VALUE SPACES. 00059800
00059900
01 SQLCA-LINE9. 00060000
02 FILLER PIC X(05) VALUE SPACES. 00060100
02 SQLWARN1-NAME PIC X(13) VALUE 'SQLWARN1 = '. 00060200
02 SQLWARN1-VALUE PIC X. 00060300
02 FILLER PIC X(21) VALUE SPACES. 00060400
02 SQLWARN2-NAME PIC X(13) VALUE 'SQLWARN2 = '. 00060500
02 SQLWARN2-VALUE PIC X. 00060600
02 FILLER PIC X(17) VALUE SPACES. 00060700
00060800
01 SQLCA-LINE10. 00060900
02 FILLER PIC X(05) VALUE SPACES. 00061000
02 SQLWARN3-NAME PIC X(13) VALUE 'SQLWARN3 = '. 00061100
02 SQLWARN3-VALUE PIC X. 00061200
02 FILLER PIC X(21) VALUE SPACES. 00061300
02 SQLWARN4-NAME PIC X(13) VALUE 'SQLWARN4 = '. 00061400
02 SQLWARN4-VALUE PIC X. 00061500
02 FILLER PIC X(17) VALUE SPACES. 00061600
00061700
01 SQLCA-LINE11. 00061800
02 FILLER PIC X(05) VALUE SPACES. 00061900
02 SQLWARN5-NAME PIC X(13) VALUE 'SQLWARN5 = '. 00062000
02 SQLWARN5-VALUE PIC X. 00062100
02 FILLER PIC X(21) VALUE SPACES. 00062200
02 SQLWARN6-NAME PIC X(13) VALUE 'SQLWARN6 = '. 00062300
02 SQLWARN6-VALUE PIC X. 00062400
02 FILLER PIC X(17) VALUE SPACES. 00062500
00062600
01 SQLCA-LINE12. 00062700
02 FILLER PIC X(05) VALUE SPACES. 00062800
02 SQLWARN7-NAME PIC X(13) VALUE 'SQLWARN7 = '. 00062900
02 SQLWARN7-VALUE PIC X. 00063000
1066 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
02 FILLER PIC X(21) VALUE SPACES. 00063100
02 SQLWARN8-NAME PIC X(13) VALUE 'SQLWARN8 = '. 00063200
02 SQLWARN8-VALUE PIC X. 00063300
02 FILLER PIC X(17) VALUE SPACES. 00063400
00063500
01 SQLCA-LINE13. 00063600
02 FILLER PIC X(05) VALUE SPACES. 00063700
02 SQLWARN9-NAME PIC X(13) VALUE 'SQLWARN9 = '. 00063800
02 SQLWARN9-VALUE PIC X. 00063900
02 FILLER PIC X(21) VALUE SPACES. 00064000
02 SQLWARNA-NAME PIC X(13) VALUE 'SQLWARNA = '. 00064100
02 SQLWARNA-VALUE PIC X. 00064200
02 FILLER PIC X(17) VALUE SPACES. 00064300
00064400
01 SQLCA-LINE14. 00064500
02 FILLER PIC X(05) VALUE SPACES. 00064600
02 SQLSTATE-NAME PIC X(13) VALUE 'SQLSTATE = '. 00064700
02 SQLSTATE-VALUE PIC X(05). 00064800
02 FILLER PIC X(48) VALUE SPACES. 00064900
00065000
**************************************************************** 00065100
* LINKAGE SECTION * 00065200
**************************************************************** 00065300
00065400
LINKAGE SECTION. 00065500
00065600
*---------------------------------------------------------------* 00065700
* SQL DECLARATION FOR VIEW VHDEPT * 00065800
*---------------------------------------------------------------* 00065900
EXEC SQL DECLARE VHDEPT TABLE 00066000
(DEPTNO CHAR(3) NOT NULL, 00066100
DEPTNAME VARCHAR(36) NOT NULL, 00066200
MGRNO CHAR(6) , 00066300
ADMRDEPT CHAR(3) NOT NULL, 00066400
LOCATION CHAR(16)) END-EXEC. 00066500
*---------------------------------------------------------------* 00066600
* SQL DECLARATION FOR VIEW VEMP * 00066700
*---------------------------------------------------------------* 00066800
EXEC SQL DECLARE VEMP TABLE 00066900
(EMPNO CHAR(6) NOT NULL, 00067000
FIRSTNME VARCHAR(12) NOT NULL, 00067100
MIDINIT CHAR(1) NOT NULL, 00067200
LASTNAME VARCHAR(15) NOT NULL, 00067300
WORKDEPT CHAR(3)) END-EXEC. 00067400
*---------------------------------------------------------------* 00067500
* SQL CURSORS * 00067600
*---------------------------------------------------------------* 00067700
* 00067800
EXEC SQL DECLARE CURDEPTLOC CURSOR FOR 00067900
SELECT LOCATION 00068000
FROM VHDEPT 00068100
WHERE DEPTNO = :EMP-WORK-DEPT 00068200
AND LOCATION = CURRENT SERVER 00068300
END-EXEC. 00068400
* 00068500
EXEC SQL DECLARE DEPTLOC CURSOR FOR 00068600
SELECT LOCATION 00068700
FROM VHDEPT 00068800
WHERE DEPTNO = :EMP-WORK-DEPT 00068900
END-EXEC. 00069000
* 00069100
EXEC SQL DECLARE LOCS CURSOR FOR 00069200
SELECT DISTINCT LOCATION 00069300
FROM VHDEPT 00069400
WHERE LOCATION <> :LOCATION 00069500
AND LOCATION <> ' ' 00069600
AND LOCATION <> CURRENT SERVER 00069700
END-EXEC. 00069800
* 00069900
EXEC SQL DECLARE SUBDEPTS CURSOR FOR 00070000
SELECT DEPTNO 00070100
FROM VHDEPT 00070200
WHERE ADMRDEPT = :CURDEPT 00070300
AND DEPTNO <> :CURDEPT 00070400
END-EXEC. 00070500
* 00070600
EXEC SQL DECLARE DEPT1 CURSOR FOR 00070700
SELECT DEPTNO, DEPTNAME, MGRNO, ADMRDEPT, LOCATION, 00070800
EMPNO, FIRSTNME, MIDINIT, LASTNAME, WORKDEPT 00070900
FROM VHDEPT, VEMP 00071000
WHERE DEPTNO = :DATAW 00071100
AND MGRNO = EMPNO 00071200
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1067
UNION 00071300
SELECT DEPTNO, DEPTNAME, MGRNO, ADMRDEPT, LOCATION, 00071400
' ', ' ', ' ', ' ', ' ' 00071500
FROM VHDEPT 00071600
WHERE DEPTNO = :DATAW 00071700
AND MGRNO IS NULL 00071800
END-EXEC. 00071900
* 00072000
EXEC SQL DECLARE ALLDEPT1 CURSOR FOR 00072100
SELECT DEPTNO, DEPTNAME, MGRNO, 00072200
SUBSTR(FIRSTNME, 1, 1) || MIDINIT || ' ' || LASTNAME 00072300
FROM VHDEPT, VEMP 00072400
WHERE MGRNO = EMPNO 00072500
AND DEPTNO LIKE :GENDATA 00072600
UNION 00072700
SELECT DEPTNO, DEPTNAME, MGRNO, ' ' 00072800
FROM VHDEPT 00072900
WHERE MGRNO IS NULL 00073000
AND DEPTNO LIKE :GENDATA 00073100
ORDER BY 1 00073200
END-EXEC. 00073300
* 00073400
EXEC SQL DECLARE ALLDEPT2 CURSOR FOR 00073500
SELECT DEPTNO, DEPTNAME, MGRNO, 00073600
SUBSTR(FIRSTNME, 1, 1) || MIDINIT || ' ' || LASTNAME 00073700
FROM VHDEPT, VEMP 00073800
WHERE MGRNO = EMPNO 00073900
AND DEPTNAME LIKE :GENDATA 00074000
UNION 00074100
SELECT DEPTNO, DEPTNAME, MGRNO, ' ' 00074200
FROM VHDEPT 00074300
WHERE MGRNO IS NULL 00074400
AND DEPTNAME LIKE :GENDATA 00074500
ORDER BY 1 00074600
END-EXEC. 00074700
* 00074800
EXEC SQL DECLARE ALLDEPT3 CURSOR FOR 00074900
SELECT DEPTNO, DEPTNAME, MGRNO, 00075000
SUBSTR(FIRSTNME, 1, 1) || MIDINIT || ' ' || LASTNAME 00075100
FROM VHDEPT, VEMP 00075200
WHERE MGRNO = EMPNO 00075300
AND MGRNO LIKE :GENDATA 00075400
UNION 00075500
SELECT DEPTNO, DEPTNAME, MGRNO, ' ' 00075600
FROM VHDEPT 00075700
WHERE MGRNO IS NULL 00075800
AND MGRNO LIKE :GENDATA 00075900
ORDER BY 1 00076000
END-EXEC. 00076100
* 00076200
EXEC SQL DECLARE ALLDEPT4 CURSOR FOR 00076300
SELECT DEPTNO, DEPTNAME, MGRNO, 00076400
SUBSTR(FIRSTNME, 1, 1) || MIDINIT || ' ' || LASTNAME 00076500
FROM VHDEPT, VEMP 00076600
WHERE MGRNO = EMPNO 00076700
AND LASTNAME LIKE :GENDATA 00076800
ORDER BY 1 00076900
END-EXEC. 00077000
* 00077100
EXEC SQL DECLARE ALLDEPT5 CURSOR FOR 00077200
SELECT DEPTNO, DEPTNAME, MGRNO, 00077300
SUBSTR(FIRSTNME, 1, 1) || MIDINIT || ' ' || LASTNAME 00077400
FROM VHDEPT, VEMP 00077500
WHERE MGRNO = EMPNO 00077600
AND DEPTNAME = :GENDATA 00077700
UNION 00077800
SELECT DEPTNO, DEPTNAME, MGRNO, ' ' 00077900
FROM VHDEPT 00078000
WHERE MGRNO IS NULL 00078100
AND DEPTNAME = :GENDATA 00078200
ORDER BY 1 00078300
END-EXEC. 00078400
* 00078500
EXEC SQL DECLARE ALLDEPT6 CURSOR FOR 00078600
SELECT DEPTNO, DEPTNAME, MGRNO, 00078700
SUBSTR(FIRSTNME, 1, 1) || MIDINIT || ' ' || LASTNAME 00078800
FROM VHDEPT, VEMP 00078900
WHERE MGRNO = EMPNO 00079000
AND MGRNO = :GENDATA 00079100
UNION 00079200
SELECT DEPTNO, DEPTNAME, MGRNO, ' ' 00079300
FROM VHDEPT 00079400
1068 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
WHERE MGRNO IS NULL 00079500
AND MGRNO = :GENDATA 00079600
ORDER BY 1 00079700
END-EXEC. 00079800
* 00079900
EXEC SQL DECLARE ALLDEPT7 CURSOR FOR 00080000
SELECT DEPTNO, DEPTNAME, MGRNO, 00080100
SUBSTR(FIRSTNME, 1, 1) || MIDINIT || ' ' || LASTNAME 00080200
FROM VHDEPT, VEMP 00080300
WHERE MGRNO = EMPNO 00080400
AND LASTNAME = :GENDATA 00080500
ORDER BY 1 00080600
END-EXEC. 00080700
* 00080800
EXEC SQL DECLARE EMP1 CURSOR FOR 00080900
SELECT DEPTNO, DEPTNAME, MGRNO, ADMRDEPT, LOCATION, 00081000
EMPNO, FIRSTNME, MIDINIT, LASTNAME, WORKDEPT 00081100
FROM VHDEPT, VEMP 00081200
WHERE EMPNO = :DATAW 00081300
AND WORKDEPT = DEPTNO 00081400
UNION 00081500
SELECT ' ', ' ', ' ', ' ', ' ', 00081600
EMPNO, FIRSTNME, MIDINIT, LASTNAME, ' ' 00081700
FROM VEMP 00081800
WHERE EMPNO = :DATAW 00081900
AND WORKDEPT IS NULL 00082000
END-EXEC. 00082100
* 00082200
EXEC SQL DECLARE ALLEMP1 CURSOR FOR 00082300
SELECT EMPNO, SUBSTR(FIRSTNME, 1, 1) || ' ' || LASTNAME, 00082400
WORKDEPT, DEPTNAME 00082500
FROM VHDEPT, VEMP 00082600
WHERE DEPTNO = WORKDEPT 00082700
AND EMPNO LIKE :GENDATA 00082800
UNION 00082900
SELECT EMPNO, SUBSTR(FIRSTNME, 1, 1) || ' ' || LASTNAME, 00083000
WORKDEPT, ' ' 00083100
FROM VEMP 00083200
WHERE WORKDEPT IS NULL 00083300
AND EMPNO LIKE :GENDATA 00083400
ORDER BY 1 00083500
END-EXEC. 00083600
* 00083700
EXEC SQL DECLARE ALLEMP2 CURSOR FOR 00083800
SELECT EMPNO, SUBSTR(FIRSTNME, 1, 1) || ' ' || LASTNAME, 00083900
WORKDEPT, DEPTNAME 00084000
FROM VHDEPT, VEMP 00084100
WHERE DEPTNO = WORKDEPT 00084200
AND LASTNAME LIKE :GENDATA 00084300
UNION 00084400
SELECT EMPNO, SUBSTR(FIRSTNME, 1, 1) || ' ' || LASTNAME, 00084500
WORKDEPT, ' ' 00084600
FROM VEMP 00084700
WHERE WORKDEPT IS NULL 00084800
AND LASTNAME LIKE :GENDATA 00084900
ORDER BY 1 00085000
END-EXEC. 00085100
* 00085200
EXEC SQL DECLARE ALLEMP3 CURSOR FOR 00085300
SELECT EMPNO, SUBSTR(FIRSTNME, 1, 1) || ' ' || LASTNAME, 00085400
WORKDEPT, DEPTNAME 00085500
FROM VHDEPT, VEMP 00085600
WHERE DEPTNO = WORKDEPT 00085700
AND LASTNAME = :GENDATA 00085800
UNION 00085900
SELECT EMPNO, SUBSTR(FIRSTNME, 1, 1) || ' ' || LASTNAME, 00086000
WORKDEPT, ' ' 00086100
FROM VEMP 00086200
WHERE WORKDEPT IS NULL 00086300
AND LASTNAME = :GENDATA 00086400
ORDER BY 1 00086500
END-EXEC. 00086600
* 00086700
EXEC SQL DECLARE DEPTSTR CURSOR FOR 00086800
SELECT DEPTNO, DEPTNAME, MGRNO, ADMRDEPT, LOCATION, 00086900
FIRSTNME, MIDINIT, LASTNAME 00087000
FROM VHDEPT, VEMP 00087100
WHERE ADMRDEPT = :DATAW 00087200
AND MGRNO = EMPNO 00087300
UNION 00087400
SELECT DEPTNO, DEPTNAME, MGRNO, ADMRDEPT, LOCATION, 00087500
' ', ' ', ' ' 00087600
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1069
FROM VHDEPT 00087700
WHERE ADMRDEPT = :DATAW 00087800
AND MGRNO IS NULL 00087900
ORDER BY 1 00088000
END-EXEC. 00088100
* 00088200
EJECT 00088300
PROCEDURE DIVISION. 00088400
*---------------------------------------------------------------* 00088500
* SQL RETURN CODE HANDLING * 00088600
*---------------------------------------------------------------* 00088700
EXEC SQL WHENEVER SQLERROR GOTO L8000-P3-DBERROR END-EXEC. 00088800
EXEC SQL WHENEVER SQLWARNING GOTO L8000-P3-DBERROR END-EXEC. 00088900
EXEC SQL WHENEVER NOT FOUND CONTINUE END-EXEC. 00089000
* 00089100
*---------------------------------------------------------------* 00089200
* DEFINE COBOL - SPF VARIABLES * 00089300
*---------------------------------------------------------------* 00089400
0000-PROGRAM-START. 00089500
CALL 'ISPLINK' USING I-VDEFINE, CH-VAR, ROWS-CHANGED, 00089600
I-CHAR, CH-VAR-STG. 00089700
CALL 'ISPLINK' USING I-VDEFINE, QROWS, NUMROWS, 00089800
I-CHAR, QROWS-STG. 00089900
* 00090000
* ACTION PANEL 00090100
* 00090200
CALL 'ISPLINK' USING I-VDEFINE, ACT-VAR, ACTION, 00090300
I-CHAR, AC-VAR-STG. 00090400
CALL 'ISPLINK' USING I-VDEFINE, OBJ-VAR, OBJFLD, 00090500
I-CHAR, OB-VAR-STG. 00090600
CALL 'ISPLINK' USING I-VDEFINE, SEA-VAR, SEARCH-CRIT, 00090700
I-CHAR, SE-VAR-STG. 00090800
CALL 'ISPLINK' USING I-VDEFINE, LOC-VAR, LOCATION, 00090900
I-CHAR, LO-VAR-STG. 00091000
CALL 'ISPLINK' USING I-VDEFINE, DAT-VAR, NAMEID, 00091100
I-CHAR, DT-VAR-STG. 00091200
* 00091300
* DEPARTMENT STRUCTURE PANEL 00091400
* 00091500
CALL 'ISPLINK' USING I-VDEFINE, DN1M-VAR, DEPT1-NUMB, 00091600
I-CHAR, DN1M-VAR-STG. 00091700
CALL 'ISPLINK' USING I-VDEFINE, DNAME1M-VAR, DEPT1-NAME, 00091800
I-CHAR, DNAME1M-VAR-STG. 00091900
CALL 'ISPLINK' USING I-VDEFINE, DMGR1M-VAR, DEPT1-MGR, 00092000
I-CHAR, DMGR1M-VAR-STG. 00092100
CALL 'ISPLINK' USING I-VDEFINE, EFN1M-VAR, EMP1-FIRST-NAME, 00092200
I-CHAR, EFN1M-VAR-STG. 00092300
CALL 'ISPLINK' USING I-VDEFINE, EMI1M-VAR, EMP1-MID-INIT, 00092400
I-CHAR, EMI1M-VAR-STG. 00092500
CALL 'ISPLINK' USING I-VDEFINE, ELN1M-VAR, EMP1-LAST-NAME, 00092600
I-CHAR, ELN1M-VAR-STG. 00092700
CALL 'ISPLINK' USING I-VDEFINE, DN1-VAR, DEPT-NUMB, 00092800
I-CHAR, DN1-VAR-STG. 00092900
CALL 'ISPLINK' USING I-VDEFINE, DNAME1-VAR, DEPT-NAME, 00093000
I-CHAR, DNAME1-VAR-STG. 00093100
CALL 'ISPLINK' USING I-VDEFINE, DMGR1-VAR, DEPT-MGR, 00093200
I-CHAR, DMGR1-VAR-STG. 00093300
CALL 'ISPLINK' USING I-VDEFINE, EFN1-VAR, EMP-FIRST-NAME, 00093400
I-CHAR, EFN1-VAR-STG. 00093500
CALL 'ISPLINK' USING I-VDEFINE, EMI1-VAR, EMP-MID-INIT, 00093600
I-CHAR, EMI1-VAR-STG. 00093700
CALL 'ISPLINK' USING I-VDEFINE, ELN1-VAR, EMP-LAST-NAME, 00093800
I-CHAR, ELN1-VAR-STG. 00093900
* 00094000
* DISPLAY PANEL 00094100
* 00094200
CALL 'ISPLINK' USING I-VDEFINE, ACTL-VAR, ACTION-LIST, 00094300
I-CHAR, ACL-VAR-STG. 00094400
CALL 'ISPLINK' USING I-VDEFINE, DN2-VAR, DEPT-NUMB, 00094500
I-CHAR, DN2-VAR-STG. 00094600
CALL 'ISPLINK' USING I-VDEFINE, DNAME2-VAR, DEPT-NAME, 00094700
I-CHAR, DNAME2-VAR-STG. 00094800
CALL 'ISPLINK' USING I-VDEFINE, DMGR2-VAR, DEPT-MGR, 00094900
I-CHAR, DMGR2-VAR-STG. 00095000
CALL 'ISPLINK' USING I-VDEFINE, DADM-VAR, DEPT-ADMR, 00095100
I-CHAR, DADM-VAR-STG. 00095200
CALL 'ISPLINK' USING I-VDEFINE, DLOC-VAR, DEPT-LOC, 00095300
I-CHAR, DLOC-VAR-STG. 00095400
CALL 'ISPLINK' USING I-VDEFINE, EN2-VAR, EMP-NUMB, 00095500
I-CHAR, EN2-VAR-STG. 00095600
CALL 'ISPLINK' USING I-VDEFINE, EFN2-VAR, EMP-FIRST-NAME, 00095700
I-CHAR, EFN2-VAR-STG. 00095800
1070 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
CALL 'ISPLINK' USING I-VDEFINE, EMI2-VAR, EMP-MID-INIT, 00095900
I-CHAR, EMI2-VAR-STG. 00096000
CALL 'ISPLINK' USING I-VDEFINE, ELN2-VAR, EMP-LAST-NAME, 00096100
I-CHAR, ELN2-VAR-STG. 00096200
CALL 'ISPLINK' USING I-VDEFINE, EWD-VAR, EMP-WORK-DEPT, 00096300
I-CHAR, EWD-VAR-STG. 00096400
* 00096500
* SELECT DEPARTMENT PANEL 00096600
* 00096700
CALL 'ISPLINK' USING I-VDEFINE, SD-VAR, SEL-DEPT, 00096800
I-CHAR, SD-VAR-STG. 00096900
CALL 'ISPLINK' USING I-VDEFINE, DN3-VAR, DEPT-NUMB, 00097000
I-CHAR, DN3-VAR-STG. 00097100
CALL 'ISPLINK' USING I-VDEFINE, DNAME3-VAR, DEPT-NAME, 00097200
I-CHAR, DNAME3-VAR-STG. 00097300
CALL 'ISPLINK' USING I-VDEFINE, DMGR3-VAR, DEPT-MGR, 00097400
I-CHAR, DMGR3-VAR-STG. 00097500
CALL 'ISPLINK' USING I-VDEFINE, MGRN-VAR, MGR-NAME, 00097600
I-CHAR, MGRN-VAR-STG. 00097700
* 00097800
* SELECT EMPLOYEE PANEL 00097900
* 00098000
CALL 'ISPLINK' USING I-VDEFINE, SEM-VAR, SEL-EMP, 00098100
I-CHAR, SEM-VAR-STG. 00098200
CALL 'ISPLINK' USING I-VDEFINE, EN4-VAR, EMP-NUMB, 00098300
I-CHAR, EN4-VAR-STG. 00098400
CALL 'ISPLINK' USING I-VDEFINE, EMPN-VAR, EMP-NAME, 00098500
I-CHAR, EMPN-VAR-STG. 00098600
CALL 'ISPLINK' USING I-VDEFINE, DN4-VAR, EMP-WORK-DEPT, 00098700
I-CHAR, DN4-VAR-STG. 00098800
CALL 'ISPLINK' USING I-VDEFINE, DNAME4-VAR, DEPT-NAME, 00098900
I-CHAR, DNAME4-VAR-STG. 00099000
* 00099100
CALL 'ISPLINK' USING I-VDEFINE, MSGS-VAR, MSGS, 00099200
I-CHAR, MSGS-VAR-STG. 00099300
* 00099400
*---------------------------------------------------------------* 00099500
* MAIN PROGRAM * 00099600
*---------------------------------------------------------------* 00099700
MOVE 'N' TO SEL-EXIT. 00099800
MOVE SPACES TO PREVLOC. 00099900
PERFORM 1000-MAIN-LOOP THRU 1000-MAIN-LOOP-EXIT 00100000
UNTIL SEL-EXIT = 'Y'. 00100100
MOVE 0 TO RETURN-CODE. 00100200
MOVE SPACES TO MSGS. 00100300
CALL 'ISPLINK' USING I-VPUT, MSGS-VAR. 00100400
GOBACK. 00100500
* 00100600
1000-MAIN-LOOP. 00100700
CALL 'ISPLINK' USING I-DISPLAY, SEL-PANEL. 00100800
IF RETURN-CODE = 8 THEN 00100900
EXEC SQL COMMIT END-EXEC 00101000
EXEC SQL RELEASE ALL SQL END-EXEC 00101100
MOVE 'Y' TO SEL-EXIT 00101200
ELSE 00101300
MOVE SPACES TO MSGS 00101400
MOVE 'N' TO GEND-EXIT, GENE-EXIT 00101500
CALL 'ISPLINK' USING I-VGET, ACTION-VARS 00101600
MOVE NAMEID TO DATAW 00101700
MOVE 0 TO LENGTH-COUNTER 00101800
INSPECT DATAW 00101900
TALLYING LENGTH-COUNTER FOR CHARACTERS 00102000
BEFORE INITIAL SPACE 00102100
IF SEARCH-CRIT = 'DI' AND LENGTH-COUNTER > 3 OR 00102200
SEARCH-CRIT = 'MI' AND LENGTH-COUNTER > 6 OR 00102300
SEARCH-CRIT = 'EI' AND LENGTH-COUNTER > 6 THEN 00102400
MOVE '074E' TO MSGCODE 00102500
CALL 'DSN8MCG' USING MODULE, MSGCODE, OUTMSG 00102600
MOVE OUTMSG TO MSGS 00102700
ELSE 00102800
PERFORM 1100-CONNECT THRU 1100-CONNECT-EXIT 00102900
PERFORM 1200-DOACTION THRU 1200-DOACTION-EXIT. 00103000
1000-MAIN-LOOP-EXIT. 00103100
EXIT. 00103200
* 00103300
*---------------------------------------------------------------* 00103400
* CONNECT TO NEW LOCATION * 00103500
*---------------------------------------------------------------* 00103600
1100-CONNECT. 00103700
IF LOCATION NOT EQUAL TO PREVLOC THEN 00103800
MOVE LOCATION TO PREVLOC 00103900
IF LOCATION NOT EQUAL TO SPACES THEN 00104000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1071
EXEC SQL CONNECT TO :LOCATION END-EXEC 00104100
ELSE 00104200
EXEC SQL CONNECT RESET END-EXEC. 00104300
1100-CONNECT-EXIT. 00104400
EXIT. 00104500
* 00104600
*---------------------------------------------------------------* 00104700
* DETERMINE PROCESSING REQUEST * 00104800
*---------------------------------------------------------------* 00104900
1200-DOACTION. 00105000
IF ACTION = 'A' THEN 00105100
MOVE ' ADD' TO ACTION-LIST 00105200
IF OBJFLD = 'DE' THEN 00105300
PERFORM 2000-ADDDEPT THRU 2000-ADDDEPT-EXIT 00105400
ELSE 00105500
PERFORM 3000-ADDEMP THRU 3000-ADDEMP-EXIT 00105600
ELSE 00105700
PERFORM 4000-ACTION THRU 4000-ACTION-EXIT 00105800
IF OBJFLD = 'DE' OR OBJFLD = 'DS' THEN 00105900
PERFORM 5000-DEPARTMENT THRU 5000-DEPARTMENT-EXIT 00106000
ELSE 00106100
PERFORM 6000-EMPLOYEE THRU 6000-EMPLOYEE-EXIT. 00106200
1200-DOACTION-EXIT. 00106300
EXIT. 00106400
* 00106500
*---------------------------------------------------------------* 00106600
* ADD A DEPARTMENT * 00106700
*---------------------------------------------------------------* 00106800
2000-ADDDEPT. 00106900
CALL 'ISPLINK' USING I-VPUT, IDEN-VAR. 00107000
PERFORM 2100-DISDEPTDATA THRU 2100-DISDEPTDATA-EXIT. 00107100
CALL 'ISPLINK' USING I-VPUT, ADD-DEPT-VARS. 00107200
CALL 'ISPLINK' USING I-DISPLAY, DEPT-PANEL. 00107300
IF RETURN-CODE NOT EQUAL TO 8 THEN 00107400
EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC 00107500
MOVE SPACES TO SQLERRP 00107600
EXEC SQL INSERT INTO VHDEPT 00107700
VALUES (:DEPT-NUMB, :DEPT-NAME, :DEPT-MGR, 00107800
:DEPT-ADMR, :DEPT-LOC) 00107900
END-EXEC 00108000
PERFORM 2200-ADDDEPTCODES THRU 2200-ADDDEPTCODES-EXIT 00108100
EXEC SQL WHENEVER SQLERROR GOTO L8000-P3-DBERROR END-EXEC00108200
PERFORM 2300-GETEMPREC THRU 2300-GETEMPREC-EXIT 00108300
CALL 'ISPLINK' USING I-VPUT, DEPT-VARS 00108400
CALL 'ISPLINK' USING I-DISPLAY, DEPT-PANEL. 00108500
2000-ADDDEPT-EXIT. 00108600
EXIT. 00108700
* 00108800
*---------------------------------------------------------------* 00108900
* DISPLAY INPUT DATA ON PANEL * 00109000
*---------------------------------------------------------------* 00109100
2100-DISDEPTDATA. 00109200
MOVE SPACES TO DEPT-RECORD. 00109300
MOVE SPACES TO EMP-RECORD. 00109400
IF SEARCH-CRIT = 'DI' THEN 00109500
MOVE DATAW TO DEPT-NUMB 00109600
ELSE 00109700
IF SEARCH-CRIT = 'DN' THEN 00109800
MOVE DATAW TO DEPT-NAME 00109900
ELSE 00110000
IF SEARCH-CRIT = 'MI' THEN 00110100
MOVE DATAW TO DEPT-MGR. 00110200
2100-DISDEPTDATA-EXIT. 00110300
EXIT. 00110400
* 00110500
*---------------------------------------------------------------* 00110600
* CHECK RETURN CODE FROM INSERT. IF OK, ADD TO OTHER LOCATIONS.* 00110700
*---------------------------------------------------------------* 00110800
2200-ADDDEPTCODES. 00110900
IF SQLERRP = SPACES THEN 00111000
MOVE '079E' TO MSGCODE 00111100
CALL 'DSN8MCG' USING MODULE, MSGCODE, OUTMSG 00111200
MOVE OUTMSG TO MSGS 00111300
ELSE 00111400
IF SQLCODE = -803 THEN 00111500
MOVE '015E' TO MSGCODE 00111600
CALL 'DSN8MCG' USING MODULE, MSGCODE, OUTMSG 00111700
MOVE OUTMSG TO MSGS 00111800
ELSE 00111900
IF SQLCODE = -530 THEN 00112000
UNSTRING SQLERRMC 00112100
DELIMITED BY HIGH-VALUE 00112200
1072 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
INTO TOKEN 00112300
IF TOKEN = 'RDD' THEN 00112400
MOVE '213E' TO MSGCODE 00112500
CALL 'DSN8MCG' USING MODULE, MSGCODE, OUTMSG 00112600
MOVE OUTMSG TO MSGS 00112700
ELSE 00112800
IF TOKEN = 'RDE' THEN 00112900
MOVE '210E' TO MSGCODE 00113000
CALL 'DSN8MCG' USING MODULE, MSGCODE, 00113100
OUTMSG 00113200
MOVE OUTMSG TO MSGS 00113300
ELSE 00113400
GO TO L8000-P3-DBERROR 00113500
ELSE 00113600
IF SQLCODE NOT EQUAL TO 0 THEN 00113700
GO TO L8000-P3-DBERROR 00113800
ELSE 00113900
EXEC SQL OPEN LOCS END-EXEC 00114000
MOVE 0 TO LOCPTR 00114100
PERFORM 2210-BUILDLOCTABLE THRU 00114200
2210-BUILDLOCTABLE-EXIT 00114300
UNTIL SQLCODE NOT EQUAL TO 0 00114400
EXEC SQL CLOSE LOCS END-EXEC 00114500
MOVE LOCPTR TO LOCTOP 00114600
MOVE 0 TO LOCPTR 00114700
PERFORM 2220-ADDLOCS THRU 2220-ADDLOCS-EXIT 00114800
UNTIL LOCPTR = LOCTOP 00114900
MOVE '012I' TO MSGCODE 00115000
CALL 'DSN8MCG' USING MODULE, MSGCODE, 00115100
OUTMSG 00115200
MOVE OUTMSG TO MSGS 00115300
MOVE DEPT-LOC TO LOCATION 00115400
PERFORM 1100-CONNECT THRU 00115500
1100-CONNECT-EXIT. 00115600
2200-ADDDEPTCODES-EXIT. 00115700
EXIT. 00115800
* 00115900
*---------------------------------------------------------------* 00116000
* BUILD TABLE OF UNIQUE LOCATIONS IN VHDEPT * 00116100
*---------------------------------------------------------------* 00116200
2210-BUILDLOCTABLE. 00116300
EXEC SQL FETCH LOCS INTO :TEMPLOC END-EXEC. 00116400
IF SQLCODE = 0 THEN 00116500
ADD 1 TO LOCPTR 00116600
MOVE TEMPLOC TO LOCLIST (LOCPTR). 00116700
2210-BUILDLOCTABLE-EXIT. 00116800
EXIT. 00116900
* 00117000
*---------------------------------------------------------------* 00117100
* ADD NEW DEPARTMENT TO VHDEPT VIEWS AT ALL LOCATIONS * 00117200
*---------------------------------------------------------------* 00117300
2220-ADDLOCS. 00117400
IF LOCPTR < LOCTOP THEN 00117500
ADD 1 TO LOCPTR 00117600
MOVE LOCLIST (LOCPTR) TO TEMPLOC 00117700
EXEC SQL CONNECT TO :TEMPLOC END-EXEC 00117800
EXEC SQL INSERT INTO VHDEPT 00117900
VALUES (:DEPT-NUMB, :DEPT-NAME, :DEPT-MGR, 00118000
:DEPT-ADMR, :DEPT-LOC) 00118100
END-EXEC. 00118200
2220-ADDLOCS-EXIT. 00118300
EXIT. 00118400
* 00118500
*---------------------------------------------------------------* 00118600
* RETRIEVE MANAGER INFO FOR NEW DEPARTMENT * 00118700
*---------------------------------------------------------------* 00118800
2300-GETEMPREC. 00118900
CALL 'ISPLINK' USING I-VGET, ADD-DEPT-VARS. 00119000
EXEC SQL SELECT * 00119100
INTO :EMP-NUMB, :EMP-FIRST-NAME, 00119200
:EMP-MID-INIT, :EMP-LAST-NAME, 00119300
:EMP-WORK-DEPT:WORK-DEPT-IND 00119400
FROM VEMP 00119500
WHERE EMPNO = :DEPT-MGR 00119600
END-EXEC. 00119700
IF SQLCODE = 100 THEN 00119800
MOVE SPACES TO EMP-RECORD. 00119900
2300-GETEMPREC-EXIT. 00120000
EXIT. 00120100
* 00120200
*---------------------------------------------------------------* 00120300
* ADD AN EMPLOYEE * 00120400
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1073
*---------------------------------------------------------------* 00120500
3000-ADDEMP. 00120600
CALL 'ISPLINK' USING I-VPUT, IDEN-VAR. 00120700
PERFORM 3100-DISEMPDATA THRU 3100-DISEMPDATA-EXIT. 00120800
CALL 'ISPLINK' USING I-VPUT, ADD-EMP-VARS. 00120900
CALL 'ISPLINK' USING I-DISPLAY, EMP-PANEL. 00121000
IF RETURN-CODE NOT EQUAL TO 8 THEN 00121100
EXEC SQL OPEN CURDEPTLOC END-EXEC 00121200
PERFORM 3320-SETCURLOC THRU 3320-SETCURLOC-EXIT. 00121300
EXEC SQL CLOSE CURDEPTLOC END-EXEC 00121400
EXEC SQL OPEN DEPTLOC END-EXEC 00121500
EXEC SQL FETCH DEPTLOC INTO :DEPT-LOC END-EXEC 00121600
EXEC SQL CLOSE DEPTLOC END-EXEC 00121700
IF DEPT-LOC NOT EQUAL TO LOCATION THEN 00121800
MOVE '216E' TO MSGCODE 00121900
CALL 'DSN8MCG' USING MODULE, MSGCODE, OUTMSG 00122000
MOVE OUTMSG TO MSGS 00122100
ELSE 00122200
EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC 00122300
MOVE SPACES TO SQLERRP 00122400
EXEC SQL INSERT INTO VEMP 00122500
VALUES (:EMP-NUMB, :EMP-FIRST-NAME, 00122600
:EMP-MID-INIT, :EMP-LAST-NAME, 00122700
:EMP-WORK-DEPT) 00122800
END-EXEC 00122900
PERFORM 3200-ADDEMPCODES THRU 3200-ADDEMPCODES-EXIT 00123000
EXEC SQL WHENEVER SQLERROR GOTO L8000-P3-DBERROR 00123100
END-EXEC 00123200
PERFORM 3300-GETDEPTREC THRU 3300-GETDEPTREC-EXIT 00123300
CALL 'ISPLINK' USING I-VPUT, DEPT-VARS 00123400
CALL 'ISPLINK' USING I-DISPLAY, EMP-PANEL. 00123500
3000-ADDEMP-EXIT. 00123600
EXIT. 00123700
* 00123800
*---------------------------------------------------------------* 00123900
* DISPLAY INPUT DATA ON PANEL * 00124000
*---------------------------------------------------------------* 00124100
3100-DISEMPDATA. 00124200
MOVE SPACES TO DEPT-RECORD. 00124300
MOVE SPACES TO EMP-RECORD. 00124400
IF SEARCH-CRIT = 'EI' THEN 00124500
MOVE DATAW TO EMP-NUMB 00124600
ELSE 00124700
IF SEARCH-CRIT = 'EN' THEN 00124800
MOVE DATAW TO EMP-LAST-NAME. 00124900
3100-DISEMPDATA-EXIT. 00125000
EXIT. 00125100
* 00125200
*---------------------------------------------------------------* 00125300
* CHECK RETURN CODE FROM INSERT * 00125400
*---------------------------------------------------------------* 00125500
3200-ADDEMPCODES. 00125600
IF SQLERRP = SPACES THEN 00125700
MOVE '079E' TO MSGCODE 00125800
ELSE 00125900
IF SQLCODE = -803 THEN 00126000
MOVE '005E' TO MSGCODE 00126100
ELSE 00126200
IF SQLCODE = -530 THEN 00126300
MOVE '200E' TO MSGCODE 00126400
ELSE 00126500
IF SQLCODE = 0 THEN 00126600
MOVE '002I' TO MSGCODE 00126700
ELSE 00126800
GO TO L8000-P3-DBERROR. 00126900
CALL 'DSN8MCG' USING MODULE, MSGCODE, OUTMSG. 00127000
MOVE OUTMSG TO MSGS. 00127100
3200-ADDEMPCODES-EXIT. 00127200
EXIT. 00127300
* 00127400
*---------------------------------------------------------------* 00127500
* RETRIEVE DEPARTMENT INFO FOR NEW EMPLOYEE * 00127600
*---------------------------------------------------------------* 00127700
3300-GETDEPTREC. 00127800
CALL 'ISPLINK' USING I-VGET, ADD-EMP-VARS. 00127900
EXEC SQL SELECT * 00128000
INTO :DEPT-NUMB, :DEPT-NAME, 00128100
:DEPT-MGR:DEPT-MGR-IND, 00128200
:DEPT-ADMR, :DEPT-LOC 00128300
FROM VHDEPT 00128400
WHERE DEPTNO = :EMP-WORK-DEPT 00128500
END-EXEC. 00128600
1074 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
IF SQLCODE = 100 THEN 00128700
MOVE SPACES TO DEPT-RECORD 00128800
ELSE 00128900
PERFORM 3310-CHECKDEPTIND THRU 3310-CHECKDEPTIND-EXIT. 00129000
3300-GETDEPTREC-EXIT. 00129100
EXIT. 00129200
* 00129300
*---------------------------------------------------------------* 00129400
* IF MGRNO NULL, MOVE BLANKS INTO FIELD * 00129500
*---------------------------------------------------------------* 00129600
3310-CHECKDEPTIND. 00129700
IF DEPT-MGR-IND < 0 THEN 00129800
MOVE SPACES TO DEPT-MGR. 00129900
3310-CHECKDEPTIND-EXIT. 00130000
EXIT. 00130100
* 00130200
*---------------------------------------------------------------* 00130300
* SET LOCATION TO CURRENT SERVER * 00130400
*---------------------------------------------------------------* 00130500
3320-SETCURLOC. 00130600
IF LOCATION EQUAL TO SPACES THEN 00130700
EXEC SQL FETCH CURDEPTLOC 00130800
INTO :LOCATION 00130900
END-EXEC. 00131000
3320-SETCURLOC-EXIT. 00131100
EXIT. 00131200
* 00131300
*---------------------------------------------------------------* 00131400
* MOVE APPROPRIATE ACTION INTO ACTION-LIST * 00131500
*---------------------------------------------------------------* 00131600
4000-ACTION. 00131700
IF ACTION = 'E' THEN 00131800
MOVE ' ERASE' TO ACTION-LIST 00131900
ELSE 00132000
IF ACTION = 'U' THEN 00132100
MOVE ' UPDATE' TO ACTION-LIST 00132200
ELSE 00132300
MOVE 'DISPLAY' TO ACTION-LIST. 00132400
MOVE 0 TO PERCENT-COUNTER. 00132500
INSPECT DATAW 00132600
TALLYING PERCENT-COUNTER FOR ALL '%'. 00132700
IF PERCENT-COUNTER > 0 THEN 00132800
INSPECT DATAW 00132900
REPLACING ALL ' ' BY '%'. 00133000
4000-ACTION-EXIT. 00133100
EXIT. 00133200
* 00133300
*---------------------------------------------------------------* 00133400
* PERFORM ACTION ON DEPARTMENT OR DEPARTMENT STRUCTURE * 00133500
*---------------------------------------------------------------* 00133600
5000-DEPARTMENT. 00133700
IF NOT (SEARCH-CRIT = 'DI' AND PERCENT-COUNTER = 0) THEN 00133800
MOVE DATAW TO GENDATA 00133900
PERFORM 5100-GENDEPT THRU 5100-GENDEPT-EXIT 00134000
UNTIL GEND-EXIT = 'Y' 00134100
ELSE 00134200
IF OBJFLD = 'DE' THEN 00134300
PERFORM 5200-DISPLAYDEPT THRU 5200-DISPLAYDEPT-EXIT 00134400
ELSE 00134500
PERFORM 5300-STRUCTURE THRU 5300-STRUCTURE-EXIT. 00134600
5000-DEPARTMENT-EXIT. 00134700
EXIT. 00134800
* 00134900
*---------------------------------------------------------------* 00135000
* GENERIC LIST OF DEPARTMENTS * 00135100
*---------------------------------------------------------------* 00135200
5100-GENDEPT. 00135300
CALL 'ISPLINK' USING I-TBCREATE, DEPT-TABLE, W-BLANK, 00135400
SEL-DEPT-VARS, I-NOWRITE, I-REPLACE. 00135500
MOVE SPACE TO SEL-DEPT. 00135600
PERFORM 5110-GETDEPTTAB THRU 5110-GETDEPTTAB-EXIT. 00135700
CALL 'ISPLINK' USING I-TBQUERY, DEPT-TABLE, W-BLANK, 00135800
W-BLANK, QROWS. 00135900
IF NUMROWS = 1 AND GENDATA = DATAW THEN 00136000
MOVE 'Y' TO SPECIAL-EXIT 00136100
CALL 'ISPLINK' USING I-TBGET, DEPT-TABLE 00136200
MOVE DEPT-NUMB TO DATAW 00136300
ELSE 00136400
MOVE 'N' TO SPECIAL-EXIT 00136500
IF NUMROWS = 0 THEN 00136600
PERFORM 5120-DEPTMSG THRU 5120-DEPTMSG-EXIT 00136700
MOVE 'Y' TO GEND-EXIT 00136800
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1075
ELSE 00136900
CALL 'ISPLINK' USING I-VPUT, ACTL-VAR 00137000
CALL 'ISPLINK' USING I-TBTOP, DEPT-TABLE 00137100
CALL 'ISPLINK' USING I-TBDISPL, DEPT-TABLE, 00137200
GEND-PANEL 00137300
IF RETURN-CODE = 8 THEN 00137400
MOVE 'Y' TO GEND-EXIT 00137500
ELSE 00137600
IF ROWS-CHANGED > 0 THEN 00137700
CALL 'ISPLINK' USING I-TBGET, DEPT-TABLE 00137800
MOVE DEPT-NUMB TO DATAW 00137900
ELSE 00138000
MOVE 'Y' TO GEND-EXIT. 00138100
IF GEND-EXIT = 'N' THEN 00138200
IF OBJFLD = 'DE' THEN 00138300
PERFORM 5200-DISPLAYDEPT THRU 5200-DISPLAYDEPT-EXIT 00138400
ELSE 00138500
PERFORM 5300-STRUCTURE THRU 5300-STRUCTURE-EXIT. 00138600
IF SPECIAL-EXIT = 'Y' THEN 00138700
MOVE 'Y' TO GEND-EXIT. 00138800
CALL 'ISPLINK' USING I-TBCLOSE, DEPT-TABLE. 00138900
5100-GENDEPT-EXIT. 00139000
EXIT. 00139100
* 00139200
*---------------------------------------------------------------* 00139300
* CREATE TABLE OF DEPARTMENTS TO FIT SEARCH-CRIT * 00139400
*---------------------------------------------------------------* 00139500
5110-GETDEPTTAB. 00139600
IF SEARCH-CRIT = 'DI' THEN 00139700
EXEC SQL OPEN ALLDEPT1 END-EXEC 00139800
MOVE SPACES TO SQLERRP 00139900
PERFORM 5111-ALLDEPT1 THRU 5111-ALLDEPT1-EXIT 00140000
UNTIL SQLCODE NOT EQUAL TO 0 OR GEND-EXIT = 'Y' 00140100
EXEC SQL CLOSE ALLDEPT1 END-EXEC 00140200
ELSE 00140300
IF SEARCH-CRIT = 'DN' AND PERCENT-COUNTER > 0 THEN 00140400
EXEC SQL OPEN ALLDEPT2 END-EXEC 00140500
MOVE SPACES TO SQLERRP 00140600
PERFORM 5112-ALLDEPT2 THRU 5112-ALLDEPT2-EXIT 00140700
UNTIL SQLCODE NOT EQUAL TO 0 OR GEND-EXIT = 'Y' 00140800
EXEC SQL CLOSE ALLDEPT2 END-EXEC 00140900
ELSE 00141000
IF SEARCH-CRIT = 'DN' THEN 00141100
EXEC SQL OPEN ALLDEPT5 END-EXEC 00141200
MOVE SPACES TO SQLERRP 00141300
PERFORM 5113-ALLDEPT5 THRU 5113-ALLDEPT5-EXIT 00141400
UNTIL SQLCODE NOT EQUAL TO 0 OR 00141500
GEND-EXIT = 'Y' 00141600
EXEC SQL CLOSE ALLDEPT5 END-EXEC 00141700
ELSE 00141800
IF SEARCH-CRIT = 'MI' AND 00141900
PERCENT-COUNTER > 0 THEN 00142000
EXEC SQL OPEN ALLDEPT3 END-EXEC 00142100
MOVE SPACES TO SQLERRP 00142200
PERFORM 5114-ALLDEPT3 THRU 00142300
5114-ALLDEPT3-EXIT 00142400
UNTIL SQLCODE NOT EQUAL TO 0 OR 00142500
GEND-EXIT = 'Y' 00142600
EXEC SQL CLOSE ALLDEPT3 END-EXEC 00142700
ELSE 00142800
IF SEARCH-CRIT = 'MI' THEN 00142900
EXEC SQL OPEN ALLDEPT6 END-EXEC 00143000
MOVE SPACES TO SQLERRP 00143100
PERFORM 5115-ALLDEPT6 THRU 00143200
5115-ALLDEPT6-EXIT 00143300
UNTIL SQLCODE NOT EQUAL TO 0 OR 00143400
GEND-EXIT = 'Y' 00143500
EXEC SQL CLOSE ALLDEPT6 END-EXEC 00143600
ELSE 00143700
IF SEARCH-CRIT = 'MN' AND 00143800
PERCENT-COUNTER > 0 THEN 00143900
EXEC SQL OPEN ALLDEPT4 END-EXEC 00144000
MOVE SPACES TO SQLERRP 00144100
PERFORM 5116-ALLDEPT4 THRU 00144200
5116-ALLDEPT4-EXIT 00144300
UNTIL SQLCODE NOT EQUAL TO 0 00144400
OR GEND-EXIT = 'Y' 00144500
EXEC SQL CLOSE ALLDEPT4 END-EXEC 00144600
ELSE 00144700
IF SEARCH-CRIT = 'MN' THEN 00144800
EXEC SQL OPEN ALLDEPT7 END-EXEC 00144900
MOVE SPACES TO SQLERRP 00145000
1076 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
PERFORM 5117-ALLDEPT7 THRU 00145100
5117-ALLDEPT7-EXIT 00145200
UNTIL SQLCODE NOT EQUAL 00145300
TO 0 OR GEND-EXIT = 'Y' 00145400
EXEC SQL CLOSE ALLDEPT7 00145500
END-EXEC. 00145600
5110-GETDEPTTAB-EXIT. 00145700
EXIT. 00145800
* 00145900
5111-ALLDEPT1. 00146000
EXEC SQL FETCH ALLDEPT1 00146100
INTO :DEPT-NUMB, :DEPT-NAME, 00146200
:DEPT-MGR:DEPT-MGR-IND, 00146300
:MGR-NAME 00146400
END-EXEC. 00146500
IF SQLERRP = SPACES THEN 00146600
MOVE '079E' TO MSGCODE 00146700
MOVE 'Y' TO GEND-EXIT 00146800
ELSE 00146900
IF SQLCODE = 0 THEN 00147000
PERFORM 3310-CHECKDEPTIND THRU 00147100
3310-CHECKDEPTIND-EXIT 00147200
CALL 'ISPLINK' USING I-TBADD, DEPT-TABLE. 00147300
5111-ALLDEPT1-EXIT. 00147400
EXIT. 00147500
* 00147600
5112-ALLDEPT2. 00147700
EXEC SQL FETCH ALLDEPT2 00147800
INTO :DEPT-NUMB, :DEPT-NAME, 00147900
:DEPT-MGR:DEPT-MGR-IND, 00148000
:MGR-NAME 00148100
END-EXEC. 00148200
IF SQLERRP = SPACES THEN 00148300
MOVE '079E' TO MSGCODE 00148400
MOVE 'Y' TO GEND-EXIT 00148500
ELSE 00148600
IF SQLCODE = 0 THEN 00148700
PERFORM 3310-CHECKDEPTIND THRU 00148800
3310-CHECKDEPTIND-EXIT 00148900
CALL 'ISPLINK' USING I-TBADD, DEPT-TABLE. 00149000
5112-ALLDEPT2-EXIT. 00149100
EXIT. 00149200
* 00149300
5113-ALLDEPT5. 00149400
EXEC SQL FETCH ALLDEPT5 00149500
INTO :DEPT-NUMB, :DEPT-NAME, 00149600
:DEPT-MGR:DEPT-MGR-IND, 00149700
:MGR-NAME 00149800
END-EXEC. 00149900
IF SQLERRP = SPACES THEN 00150000
MOVE '079E' TO MSGCODE 00150100
MOVE 'Y' TO GEND-EXIT 00150200
ELSE 00150300
IF SQLCODE = 0 THEN 00150400
PERFORM 3310-CHECKDEPTIND THRU 00150500
3310-CHECKDEPTIND-EXIT 00150600
CALL 'ISPLINK' USING I-TBADD, DEPT-TABLE. 00150700
5113-ALLDEPT5-EXIT. 00150800
EXIT. 00150900
* 00151000
5114-ALLDEPT3. 00151100
EXEC SQL FETCH ALLDEPT3 00151200
INTO :DEPT-NUMB, :DEPT-NAME, 00151300
:DEPT-MGR:DEPT-MGR-IND, 00151400
:MGR-NAME 00151500
END-EXEC. 00151600
IF SQLERRP = SPACES THEN 00151700
MOVE '079E' TO MSGCODE 00151800
MOVE 'Y' TO GEND-EXIT 00151900
ELSE 00152000
IF SQLCODE = 0 THEN 00152100
PERFORM 3310-CHECKDEPTIND THRU 00152200
3310-CHECKDEPTIND-EXIT 00152300
CALL 'ISPLINK' USING I-TBADD, DEPT-TABLE. 00152400
5114-ALLDEPT3-EXIT. 00152500
EXIT. 00152600
* 00152700
5115-ALLDEPT6. 00152800
EXEC SQL FETCH ALLDEPT6 00152900
INTO :DEPT-NUMB, :DEPT-NAME, 00153000
:DEPT-MGR:DEPT-MGR-IND, 00153100
:MGR-NAME 00153200
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1077
END-EXEC. 00153300
IF SQLERRP = SPACES THEN 00153400
MOVE '079E' TO MSGCODE 00153500
MOVE 'Y' TO GEND-EXIT 00153600
ELSE 00153700
IF SQLCODE = 0 THEN 00153800
PERFORM 3310-CHECKDEPTIND THRU 00153900
3310-CHECKDEPTIND-EXIT 00154000
CALL 'ISPLINK' USING I-TBADD, DEPT-TABLE. 00154100
5115-ALLDEPT6-EXIT. 00154200
EXIT. 00154300
* 00154400
5116-ALLDEPT4. 00154500
EXEC SQL FETCH ALLDEPT4 00154600
INTO :DEPT-NUMB, :DEPT-NAME, 00154700
:DEPT-MGR:DEPT-MGR-IND, 00154800
:MGR-NAME 00154900
END-EXEC. 00155000
IF SQLERRP = SPACES THEN 00155100
MOVE '079E' TO MSGCODE 00155200
MOVE 'Y' TO GEND-EXIT 00155300
ELSE 00155400
IF SQLCODE = 0 THEN 00155500
PERFORM 3310-CHECKDEPTIND THRU 00155600
3310-CHECKDEPTIND-EXIT 00155700
CALL 'ISPLINK' USING I-TBADD, DEPT-TABLE. 00155800
5116-ALLDEPT4-EXIT. 00155900
EXIT. 00156000
* 00156100
5117-ALLDEPT7. 00156200
EXEC SQL FETCH ALLDEPT7 00156300
INTO :DEPT-NUMB, :DEPT-NAME, 00156400
:DEPT-MGR:DEPT-MGR-IND, 00156500
:MGR-NAME 00156600
END-EXEC. 00156700
IF SQLERRP = SPACES THEN 00156800
MOVE '079E' TO MSGCODE 00156900
MOVE 'Y' TO GEND-EXIT 00157000
ELSE 00157100
IF SQLCODE = 0 THEN 00157200
PERFORM 3310-CHECKDEPTIND THRU 00157300
3310-CHECKDEPTIND-EXIT 00157400
CALL 'ISPLINK' USING I-TBADD, DEPT-TABLE. 00157500
5117-ALLDEPT7-EXIT. 00157600
EXIT. 00157700
* 00157800
*---------------------------------------------------------------* 00157900
* PRINT CORRECT 'DEPARTMENT NOT FOUND' MESSAGE * 00158000
*---------------------------------------------------------------* 00158100
5120-DEPTMSG. 00158200
IF MSGCODE NOT EQUAL TO '079E' THEN 00158300
IF ACTION = 'E' THEN 00158400
MOVE '016E' TO MSGCODE 00158500
ELSE 00158600
IF ACTION = 'U' THEN 00158700
MOVE '017E' TO MSGCODE 00158800
ELSE 00158900
MOVE '011I' TO MSGCODE. 00159000
CALL 'DSN8MCG' USING MODULE, MSGCODE, OUTMSG 00159100
MOVE OUTMSG TO MSGS. 00159200
5120-DEPTMSG-EXIT. 00159300
EXIT. 00159400
* 00159500
*---------------------------------------------------------------* 00159600
* DISPLAY A DEPARTMENT * 00159700
*---------------------------------------------------------------* 00159800
5200-DISPLAYDEPT. 00159900
MOVE SPACES TO DEPT-RECORD. 00160000
MOVE SPACES TO EMP-RECORD. 00160100
EXEC SQL OPEN DEPT1 END-EXEC. 00160200
MOVE SPACES TO SQLERRP. 00160300
EXEC SQL FETCH DEPT1 INTO :DEPT-NUMB, :DEPT-NAME, 00160400
:DEPT-MGR:DEPT-MGR-IND, 00160500
:DEPT-ADMR, :DEPT-LOC, 00160600
:EMP-NUMB, :EMP-FIRST-NAME, 00160700
:EMP-MID-INIT, :EMP-LAST-NAME, 00160800
:EMP-WORK-DEPT:WORK-DEPT-IND 00160900
END-EXEC. 00161000
PERFORM 5210-DISDEPTACT THRU 5210-DISDEPTACT-EXIT. 00161100
5200-DISPLAYDEPT-EXIT. 00161200
EXIT. 00161300
* 00161400
1078 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
*---------------------------------------------------------------* 00161500
* DISPLAY, ERASE, OR UPDATE DEPARTMENT * 00161600
*---------------------------------------------------------------* 00161700
5210-DISDEPTACT. 00161800
IF SQLERRP = SPACES THEN 00161900
EXEC SQL CLOSE DEPT1 END-EXEC 00162000
MOVE '079E' TO MSGCODE 00162100
CALL 'DSN8MCG' USING MODULE, MSGCODE, OUTMSG 00162200
MOVE OUTMSG TO MSGS 00162300
ELSE 00162400
IF SQLCODE = 100 THEN 00162500
EXEC SQL CLOSE DEPT1 END-EXEC 00162600
PERFORM 5120-DEPTMSG THRU 5120-DEPTMSG-EXIT 00162700
ELSE 00162800
EXEC SQL CLOSE DEPT1 END-EXEC 00162900
PERFORM 3310-CHECKDEPTIND THRU 00163000
3310-CHECKDEPTIND-EXIT 00163100
CALL 'ISPLINK' USING I-DISPLAY, DEPT-PANEL 00163200
IF RETURN-CODE NOT EQUAL TO 8 THEN 00163300
IF ACTION = 'E' THEN 00163400
PERFORM 5220-ERASEDEPT THRU 00163500
5220-ERASEDEPT-EXIT 00163600
ELSE 00163700
IF ACTION = 'U' THEN 00163800
PERFORM 5230-UPDATEDEPT THRU 00163900
5230-UPDATEDEPT-EXIT. 00164000
5210-DISDEPTACT-EXIT. 00164100
EXIT. 00164200
* 00164300
*---------------------------------------------------------------* 00164400
* ERASE A DEPARTMENT * 00164500
*---------------------------------------------------------------* 00164600
5220-ERASEDEPT. 00164700
MOVE 1 TO DEPTPTR. 00164800
MOVE 0 TO LISTPTR. 00164900
MOVE DATAW TO DEPTS (DEPTPTR). 00165000
PERFORM 5221-DELDEPTS THRU 5221-DELDEPTS-EXIT 00165100
UNTIL DEPTPTR = 0. 00165200
MOVE LISTPTR TO STACKTOP. 00165300
PERFORM 5223-DELDEPEND THRU 5223-DELDEPEND-EXIT 00165400
UNTIL LISTPTR = 0. 00165500
EXEC SQL OPEN LOCS END-EXEC. 00165600
MOVE 0 TO LOCPTR. 00165700
PERFORM 2210-BUILDLOCTABLE THRU 2210-BUILDLOCTABLE-EXIT 00165800
UNTIL SQLCODE NOT EQUAL TO 0. 00165900
EXEC SQL CLOSE LOCS END-EXEC. 00166000
MOVE LOCPTR TO LOCTOP. 00166100
MOVE 0 TO LOCPTR. 00166200
PERFORM 5224-DELETELOCS THRU 5224-DELETELOCS-EXIT 00166300
UNTIL LOCPTR = LOCTOP. 00166400
MOVE '013I' TO MSGCODE. 00166500
CALL 'DSN8MCG' USING MODULE, MSGCODE, OUTMSG. 00166600
MOVE OUTMSG TO MSGS. 00166700
PERFORM 1100-CONNECT THRU 1100-CONNECT-EXIT. 00166800
5220-ERASEDEPT-EXIT. 00166900
EXIT. 00167000
* 00167100
*---------------------------------------------------------------* 00167200
* ERASE DEPARTMENT FROM OTHER LOCATIONS * 00167300
*---------------------------------------------------------------* 00167400
5221-DELDEPTS. 00167500
ADD 1 TO LISTPTR. 00167600
MOVE DEPTS (DEPTPTR) TO DEPTLIST (LISTPTR). 00167700
MOVE DEPTS (DEPTPTR) TO CURDEPT. 00167800
SUBTRACT 1 FROM DEPTPTR. 00167900
EXEC SQL OPEN SUBDEPTS END-EXEC. 00168000
PERFORM 5222-GETSUBDEPTS THRU 5222-GETSUBDEPTS-EXIT 00168100
UNTIL SQLCODE NOT EQUAL TO 0. 00168200
EXEC SQL CLOSE SUBDEPTS END-EXEC. 00168300
5221-DELDEPTS-EXIT. 00168400
EXIT. 00168500
* 00168600
*---------------------------------------------------------------* 00168700
* BUILD TABLE OF DEPARTMENTS DEPENDENT ON ERASED DEPARTMENTS * 00168800
* AND DEPARTMENTS DEPENDENT ON THOSE DEPARTMENTS ETC. * 00168900
*---------------------------------------------------------------* 00169000
5222-GETSUBDEPTS. 00169100
EXEC SQL FETCH SUBDEPTS INTO :TEMPDEPT END-EXEC. 00169200
IF SQLCODE = 0 THEN 00169300
ADD 1 TO DEPTPTR 00169400
MOVE TEMPDEPT TO DEPTS (DEPTPTR). 00169500
5222-GETSUBDEPTS-EXIT. 00169600
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1079
EXIT. 00169700
* 00169800
*---------------------------------------------------------------* 00169900
* ENOFORCE REFERENTIAL INTEGRITY RULE ON VHDEPT BY CASCADE * 00170000
* DELETING DEPARTMENTS DEPENDENT ON DELETED DEPARTMENTS * 00170100
*---------------------------------------------------------------* 00170200
5223-DELDEPEND. 00170300
MOVE DEPTLIST (LISTPTR) TO DELDEPT. 00170400
EXEC SQL DELETE FROM VHDEPT 00170500
WHERE DEPTNO = :DELDEPT 00170600
END-EXEC. 00170700
SUBTRACT 1 FROM LISTPTR. 00170800
5223-DELDEPEND-EXIT. 00170900
EXIT. 00171000
* 00171100
*---------------------------------------------------------------* 00171200
* PERFORM CASCADE DELETE AT ALL LOCATIONS * 00171300
*---------------------------------------------------------------* 00171400
5224-DELETELOCS. 00171500
IF LOCPTR < LOCTOP THEN 00171600
ADD 1 TO LOCPTR 00171700
MOVE LOCLIST (LOCPTR) TO TEMPLOC 00171800
EXEC SQL CONNECT TO :TEMPLOC END-EXEC 00171900
MOVE STACKTOP TO LISTPTR 00172000
PERFORM 5223-DELDEPEND THRU 5223-DELDEPEND-EXIT 00172100
UNTIL LISTPTR = 0. 00172200
5224-DELETELOCS-EXIT. 00172300
EXIT. 00172400
* 00172500
*---------------------------------------------------------------* 00172600
* UPDATE A DEPARTMENT * 00172700
*---------------------------------------------------------------* 00172800
5230-UPDATEDEPT. 00172900
PERFORM 2300-GETEMPREC THRU 2300-GETEMPREC-EXIT. 00173000
EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC. 00173100
EXEC SQL UPDATE VHDEPT 00173200
SET DEPTNAME = :DEPT-NAME, 00173300
MGRNO = :DEPT-MGR, 00173400
ADMRDEPT = :DEPT-ADMR, 00173500
LOCATION = :DEPT-LOC 00173600
WHERE DEPTNO = :DATAW 00173700
END-EXEC. 00173800
IF SQLCODE = -530 THEN 00173900
UNSTRING SQLERRMC 00174000
DELIMITED BY HIGH-VALUE 00174100
INTO TOKEN 00174200
IF TOKEN = 'RDD' THEN 00174300
MOVE '215E' TO MSGCODE 00174400
CALL 'DSN8MCG' USING MODULE, MSGCODE, OUTMSG 00174500
MOVE OUTMSG TO MSGS 00174600
ELSE 00174700
IF TOKEN = 'RDE' THEN 00174800
MOVE '214E' TO MSGCODE 00174900
CALL 'DSN8MCG' USING MODULE, MSGCODE, OUTMSG 00175000
MOVE OUTMSG TO MSGS 00175100
ELSE 00175200
GO TO L8000-P3-DBERROR 00175300
ELSE 00175400
IF SQLCODE NOT EQUAL TO 0 THEN 00175500
GO TO L8000-P3-DBERROR 00175600
ELSE 00175700
EXEC SQL WHENEVER SQLERROR GOTO L8000-P3-DBERROR 00175800
END-EXEC 00175900
EXEC SQL OPEN LOCS END-EXEC 00176000
MOVE 0 TO LOCPTR 00176100
PERFORM 2210-BUILDLOCTABLE THRU 00176200
2210-BUILDLOCTABLE-EXIT 00176300
UNTIL SQLCODE NOT EQUAL TO 0 00176400
EXEC SQL CLOSE LOCS END-EXEC 00176500
MOVE LOCPTR TO LOCTOP 00176600
MOVE 0 TO LOCPTR 00176700
PERFORM 5231-UPDATELOCS THRU 00176800
5231-UPDATELOCS-EXIT 00176900
UNTIL LOCPTR = LOCTOP 00177000
MOVE '014I' TO MSGCODE 00177100
CALL 'DSN8MCG' USING MODULE, MSGCODE, OUTMSG 00177200
MOVE OUTMSG TO MSGS 00177300
PERFORM 1100-CONNECT THRU 1100-CONNECT-EXIT 00177400
EXEC SQL WHENEVER SQLERROR GOTO L8000-P3-DBERROR END-EXEC. 00177500
CALL 'ISPLINK' USING I-DISPLAY, DEPT-PANEL. 00177600
5230-UPDATEDEPT-EXIT. 00177700
EXIT. 00177800
1080 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* 00177900
*---------------------------------------------------------------* 00178000
* UPDATE DEPARTMENT TO VHDEPT VIEWS AT ALL LOCATIONS * 00178100
*---------------------------------------------------------------* 00178200
5231-UPDATELOCS. 00178300
IF LOCPTR < LOCTOP THEN 00178400
ADD 1 TO LOCPTR 00178500
MOVE LOCLIST (LOCPTR) TO TEMPLOC 00178600
EXEC SQL CONNECT TO :TEMPLOC END-EXEC 00178700
EXEC SQL UPDATE VHDEPT 00178800
SET DEPTNAME = :DEPT-NAME, 00178900
MGRNO = :DEPT-MGR, 00179000
ADMRDEPT = :DEPT-ADMR, 00179100
LOCATION = :DEPT-LOC 00179200
WHERE DEPTNO = :DEPT-NUMB 00179300
END-EXEC. 00179400
5231-UPDATELOCS-EXIT. 00179500
EXIT. 00179600
* 00179700
*---------------------------------------------------------------* 00179800
* DISPLAY DEPARTMENT STRUCTURE * 00179900
*---------------------------------------------------------------* 00180000
5300-STRUCTURE. 00180100
MOVE SPACES TO DEPT-RECORD. 00180200
MOVE SPACES TO EMP-RECORD. 00180300
MOVE SPACES TO DEPT1-RECORD. 00180400
MOVE SPACES TO EMP1-RECORD. 00180500
EXEC SQL OPEN DEPT1 END-EXEC. 00180600
MOVE SPACES TO SQLERRP. 00180700
EXEC SQL FETCH DEPT1 INTO :DEPT1-NUMB, :DEPT1-NAME, 00180800
:DEPT1-MGR:DEPT1-MGR-IND, 00180900
:DEPT1-ADMR, :DEPT1-LOC, 00181000
:EMP-NUMB, 00181100
:EMP1-FIRST-NAME, 00181200
:EMP1-MID-INIT, 00181300
:EMP1-LAST-NAME, 00181400
:EMP1-WORK-DEPT:WORK1-DEPT-IND 00181500
END-EXEC. 00181600
PERFORM 5310-DISSTR THRU 5310-DISSTR-EXIT. 00181700
5300-STRUCTURE-EXIT. 00181800
EXIT. 00181900
* 00182000
*---------------------------------------------------------------* 00182100
* DISPLAY DEPARTMENTS REPORTING TO SELECTED DEPARTMENT * 00182200
*---------------------------------------------------------------* 00182300
5310-DISSTR. 00182400
IF SQLERRP = SPACES THEN 00182500
EXEC SQL CLOSE DEPT1 END-EXEC 00182600
MOVE '079E' TO MSGCODE 00182700
CALL 'DSN8MCG' USING MODULE, MSGCODE, OUTMSG 00182800
MOVE OUTMSG TO MSGS 00182900
ELSE 00183000
IF SQLCODE = 100 THEN 00183100
EXEC SQL CLOSE DEPT1 END-EXEC 00183200
MOVE '011I' TO MSGCODE 00183300
CALL 'DSN8MCG' USING MODULE, MSGCODE, OUTMSG 00183400
MOVE OUTMSG TO MSGS 00183500
ELSE 00183600
EXEC SQL CLOSE DEPT1 END-EXEC 00183700
PERFORM 5311-CHECKDEPT1IND THRU 00183800
5311-CHECKDEPT1IND-EXIT 00183900
CALL 'ISPLINK' USING I-TBCREATE, DS-TABLE, W-BLANK, 00184000
DS-VARS, I-NOWRITE, I-REPLACE 00184100
EXEC SQL OPEN DEPTSTR END-EXEC 00184200
PERFORM 5312-GETSTRTAB THRU 5312-GETSTRTAB-EXIT 00184300
UNTIL SQLCODE NOT EQUAL TO 0 00184400
EXEC SQL CLOSE DEPTSTR END-EXEC 00184500
CALL 'ISPLINK' USING I-TBTOP, DS-TABLE 00184600
CALL 'ISPLINK' USING I-TBDISPL, DS-TABLE, STR-PANEL 00184700
CALL 'ISPLINK' USING I-VPUT, HEAD-DEPT-VARS 00184800
CALL 'ISPLINK' USING I-TBCLOSE, DS-TABLE. 00184900
5310-DISSTR-EXIT. 00185000
EXIT. 00185100
* 00185200
*---------------------------------------------------------------* 00185300
* IF MGRNO NULL, MOVE BLANKS INTO FIELD * 00185400
*---------------------------------------------------------------* 00185500
5311-CHECKDEPT1IND. 00185600
IF DEPT1-MGR-IND < 0 THEN 00185700
MOVE SPACES TO DEPT1-MGR. 00185800
5311-CHECKDEPT1IND-EXIT. 00185900
EXIT. 00186000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1081
* 00186100
*---------------------------------------------------------------* 00186200
* CREATE LIST OF DEPARTMENTS REPORTING TO SELECTED DEPARTMENT * 00186300
*---------------------------------------------------------------* 00186400
5312-GETSTRTAB. 00186500
EXEC SQL FETCH DEPTSTR 00186600
INTO :DEPT-NUMB, :DEPT-NAME, 00186700
:DEPT-MGR:DEPT-MGR-IND, 00186800
:DEPT-ADMR, :DEPT-LOC, 00186900
:EMP-FIRST-NAME, :EMP-MID-INIT, 00187000
:EMP-LAST-NAME 00187100
END-EXEC. 00187200
IF SQLCODE = 0 THEN 00187300
PERFORM 3310-CHECKDEPTIND THRU 3310-CHECKDEPTIND-EXIT 00187400
CALL 'ISPLINK' USING I-TBADD, DS-TABLE. 00187500
5312-GETSTRTAB-EXIT. 00187600
EXIT. 00187700
* 00187800
*---------------------------------------------------------------* 00187900
* PERFORM ACTION ON EMPLOYEE * 00188000
*---------------------------------------------------------------* 00188100
6000-EMPLOYEE. 00188200
IF NOT (SEARCH-CRIT = 'EI' AND PERCENT-COUNTER = 0) THEN 00188300
MOVE DATAW TO GENDATA 00188400
PERFORM 6100-GENEMP THRU 6100-GENEMP-EXIT 00188500
UNTIL GENE-EXIT = 'Y' 00188600
ELSE 00188700
PERFORM 6200-DISPLAYEMP THRU 6200-DISPLAYEMP-EXIT. 00188800
6000-EMPLOYEE-EXIT. 00188900
EXIT. 00189000
* 00189100
*---------------------------------------------------------------* 00189200
* GENERIC LIST OF EMPLOYEES * 00189300
*---------------------------------------------------------------* 00189400
6100-GENEMP. 00189500
CALL 'ISPLINK' USING I-TBCREATE, EMP-TABLE, W-BLANK, 00189600
SEL-EMP-VARS, I-NOWRITE, I-REPLACE. 00189700
MOVE SPACE TO SEL-EMP. 00189800
PERFORM 6110-GETEMPTAB THRU 6110-GETEMPTAB-EXIT. 00189900
CALL 'ISPLINK' USING I-TBQUERY, EMP-TABLE, W-BLANK, W-BLANK, 00190000
QROWS. 00190100
IF NUMROWS = 1 AND DATAW = GENDATA THEN 00190200
MOVE 'Y' TO SPECIAL-EXIT 00190300
CALL 'ISPLINK' USING I-TBGET, EMP-TABLE 00190400
MOVE EMP-NUMB TO DATAW 00190500
ELSE 00190600
MOVE 'N' TO SPECIAL-EXIT 00190700
IF NUMROWS = 0 THEN 00190800
PERFORM 6120-EMPMSG THRU 6120-EMPMSG-EXIT 00190900
MOVE 'Y' TO GENE-EXIT 00191000
ELSE 00191100
CALL 'ISPLINK' USING I-VPUT, ACTL-VAR 00191200
CALL 'ISPLINK' USING I-TBTOP, EMP-TABLE 00191300
CALL 'ISPLINK' USING I-TBDISPL, EMP-TABLE, 00191400
GENE-PANEL 00191500
IF RETURN-CODE = 8 THEN 00191600
MOVE 'Y' TO GENE-EXIT 00191700
ELSE 00191800
IF ROWS-CHANGED > 0 THEN 00191900
CALL 'ISPLINK' USING I-TBGET, EMP-TABLE 00192000
MOVE EMP-NUMB TO DATAW 00192100
ELSE 00192200
MOVE 'Y' TO GENE-EXIT. 00192300
IF GENE-EXIT = 'N' THEN 00192400
PERFORM 6200-DISPLAYEMP THRU 6200-DISPLAYEMP-EXIT. 00192500
IF SPECIAL-EXIT = 'Y' THEN 00192600
MOVE 'Y' TO GENE-EXIT. 00192700
CALL 'ISPLINK' USING I-TBCLOSE, EMP-TABLE. 00192800
6100-GENEMP-EXIT. 00192900
EXIT. 00193000
* 00193100
*---------------------------------------------------------------* 00193200
* CREATE TABLE OF EMPLOYEES TO FIT SEARCH-CRIT * 00193300
*---------------------------------------------------------------* 00193400
6110-GETEMPTAB. 00193500
IF SEARCH-CRIT = 'EI' THEN 00193600
EXEC SQL OPEN ALLEMP1 END-EXEC 00193700
MOVE SPACES TO SQLERRP 00193800
PERFORM 6111-ALLEMP1 THRU 6111-ALLEMP1-EXIT 00193900
UNTIL SQLCODE NOT EQUAL TO 0 OR GENE-EXIT = 'Y' 00194000
EXEC SQL CLOSE ALLEMP1 END-EXEC 00194100
ELSE 00194200
1082 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
IF SEARCH-CRIT = 'EN' AND PERCENT-COUNTER > 0 THEN 00194300
EXEC SQL OPEN ALLEMP2 END-EXEC 00194400
MOVE SPACES TO SQLERRP 00194500
PERFORM 6112-ALLEMP2 THRU 6112-ALLEMP2-EXIT 00194600
UNTIL SQLCODE NOT EQUAL TO 0 OR GENE-EXIT = 'Y' 00194700
EXEC SQL CLOSE ALLEMP2 END-EXEC 00194800
ELSE 00194900
EXEC SQL OPEN ALLEMP3 END-EXEC 00195000
MOVE SPACES TO SQLERRP 00195100
PERFORM 6113-ALLEMP3 THRU 6113-ALLEMP3-EXIT 00195200
UNTIL SQLCODE NOT EQUAL TO 0 OR GENE-EXIT = 'Y' 00195300
EXEC SQL CLOSE ALLEMP3 END-EXEC. 00195400
6110-GETEMPTAB-EXIT. 00195500
EXIT. 00195600
* 00195700
6111-ALLEMP1. 00195800
EXEC SQL FETCH ALLEMP1 00195900
INTO :EMP-NUMB, :EMP-NAME, 00196000
:EMP-WORK-DEPT:WORK-DEPT-IND, 00196100
:DEPT-NAME 00196200
END-EXEC. 00196300
IF SQLERRP = SPACES THEN 00196400
MOVE '079E' TO MSGCODE 00196500
MOVE 'Y' TO GENE-EXIT 00196600
ELSE 00196700
IF SQLCODE = 0 THEN 00196800
PERFORM 6114-CHECKEMPIND THRU 6114-CHECKEMPIND-EXIT 00196900
CALL 'ISPLINK' USING I-TBADD, EMP-TABLE. 00197000
6111-ALLEMP1-EXIT. 00197100
EXIT. 00197200
* 00197300
6112-ALLEMP2. 00197400
EXEC SQL FETCH ALLEMP2 00197500
INTO :EMP-NUMB, :EMP-NAME, 00197600
:EMP-WORK-DEPT:WORK-DEPT-IND, 00197700
:DEPT-NAME 00197800
END-EXEC. 00197900
IF SQLERRP = SPACES THEN 00198000
MOVE '079E' TO MSGCODE 00198100
MOVE 'Y' TO GENE-EXIT 00198200
ELSE 00198300
IF SQLCODE = 0 THEN 00198400
PERFORM 6114-CHECKEMPIND THRU 6114-CHECKEMPIND-EXIT 00198500
CALL 'ISPLINK' USING I-TBADD, EMP-TABLE. 00198600
6112-ALLEMP2-EXIT. 00198700
EXIT. 00198800
* 00198900
6113-ALLEMP3. 00199000
EXEC SQL FETCH ALLEMP3 00199100
INTO :EMP-NUMB, :EMP-NAME, 00199200
:EMP-WORK-DEPT:WORK-DEPT-IND, 00199300
:DEPT-NAME 00199400
END-EXEC. 00199500
IF SQLERRP = SPACES THEN 00199600
MOVE '079E' TO MSGCODE 00199700
MOVE 'Y' TO GENE-EXIT 00199800
ELSE 00199900
IF SQLCODE = 0 THEN 00200000
PERFORM 6114-CHECKEMPIND THRU 6114-CHECKEMPIND-EXIT 00200100
CALL 'ISPLINK' USING I-TBADD, EMP-TABLE. 00200200
6113-ALLEMP3-EXIT. 00200300
EXIT. 00200400
* 00200500
*---------------------------------------------------------------* 00200600
* IF WORKDEPT NULL, MOVE BLANKS INTO FIELD * 00200700
*---------------------------------------------------------------* 00200800
6114-CHECKEMPIND. 00200900
IF WORK-DEPT-IND < 0 THEN 00201000
MOVE SPACES TO EMP-WORK-DEPT. 00201100
6114-CHECKEMPIND-EXIT. 00201200
EXIT. 00201300
* 00201400
*---------------------------------------------------------------* 00201500
* PRINT CORRECT 'EMPLOYEE NOT FOUND' MESSAGE * 00201600
*---------------------------------------------------------------* 00201700
6120-EMPMSG. 00201800
IF MSGCODE NOT EQUAL TO '079E' THEN 00201900
IF ACTION = 'E' THEN 00202000
MOVE '006E' TO MSGCODE 00202100
ELSE 00202200
IF ACTION = 'U' THEN 00202300
MOVE '007E' TO MSGCODE 00202400
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1083
ELSE 00202500
MOVE '001I' TO MSGCODE. 00202600
CALL 'DSN8MCG' USING MODULE, MSGCODE, OUTMSG 00202700
MOVE OUTMSG TO MSGS. 00202800
6120-EMPMSG-EXIT. 00202900
EXIT. 00203000
* 00203100
*---------------------------------------------------------------* 00203200
* DISPLAY AN EMPLOYEE * 00203300
*---------------------------------------------------------------* 00203400
6200-DISPLAYEMP. 00203500
MOVE SPACES TO DEPT-RECORD. 00203600
MOVE SPACES TO EMP-RECORD. 00203700
EXEC SQL OPEN EMP1 END-EXEC. 00203800
MOVE SPACES TO SQLERRP. 00203900
EXEC SQL FETCH EMP1 INTO :DEPT-NUMB, :DEPT-NAME, 00204000
:DEPT-MGR:DEPT-MGR-IND, 00204100
:DEPT-ADMR, :DEPT-LOC, 00204200
:EMP-NUMB, :EMP-FIRST-NAME, 00204300
:EMP-MID-INIT, :EMP-LAST-NAME, 00204400
:EMP-WORK-DEPT:WORK-DEPT-IND 00204500
END-EXEC. 00204600
PERFORM 6210-DISEMPACT THRU 6210-DISEMPACT-EXIT. 00204700
6200-DISPLAYEMP-EXIT. 00204800
EXIT. 00204900
* 00205000
*---------------------------------------------------------------* 00205100
* DISPLAY, ERASE, OR UPDATE EMPLOYEE * 00205200
*---------------------------------------------------------------* 00205300
6210-DISEMPACT. 00205400
IF SQLERRP = SPACES THEN 00205500
EXEC SQL CLOSE EMP1 END-EXEC 00205600
MOVE '079E' TO MSGCODE 00205700
CALL 'DSN8MCG' USING MODULE, MSGCODE, OUTMSG 00205800
MOVE OUTMSG TO MSGS 00205900
ELSE 00206000
IF SQLCODE = 100 THEN 00206100
EXEC SQL CLOSE EMP1 END-EXEC 00206200
PERFORM 6120-EMPMSG THRU 6120-EMPMSG-EXIT 00206300
ELSE 00206400
EXEC SQL CLOSE EMP1 END-EXEC 00206500
PERFORM 3310-CHECKDEPTIND THRU 00206600
3310-CHECKDEPTIND-EXIT 00206700
CALL 'ISPLINK' USING I-DISPLAY, EMP-PANEL 00206800
IF RETURN-CODE NOT EQUAL TO 8 THEN 00206900
IF ACTION = 'E' THEN 00207000
PERFORM 6220-ERASEEMP THRU 00207100
6220-ERASEEMP-EXIT 00207200
ELSE 00207300
IF ACTION = 'U' THEN 00207400
PERFORM 6230-UPDATEEMP THRU 00207500
6230-UPDATEEMP-EXIT. 00207600
6210-DISEMPACT-EXIT. 00207700
EXIT. 00207800
* 00207900
*---------------------------------------------------------------* 00208000
* ERASE AN EMPLOYEE * 00208100
*---------------------------------------------------------------* 00208200
6220-ERASEEMP. 00208300
EXEC SQL DELETE FROM VEMP 00208400
WHERE EMPNO = :DATAW 00208500
END-EXEC. 00208600
IF SQLCODE = 0 THEN 00208700
MOVE '003I' TO MSGCODE 00208800
CALL 'DSN8MCG' USING MODULE, MSGCODE, OUTMSG 00208900
MOVE OUTMSG TO MSGS. 00209000
6220-ERASEEMP-EXIT. 00209100
EXIT. 00209200
* 00209300
*---------------------------------------------------------------* 00209400
* UPDATE AN EMPLOYEE * 00209500
*---------------------------------------------------------------* 00209600
6230-UPDATEEMP. 00209700
PERFORM 3300-GETDEPTREC THRU 3300-GETDEPTREC-EXIT. 00209800
EXEC SQL OPEN CURDEPTLOC END-EXEC 00209900
PERFORM 3320-SETCURLOC THRU 3320-SETCURLOC-EXIT. 00210000
EXEC SQL CLOSE CURDEPTLOC END-EXEC 00210100
IF DEPT-LOC NOT EQUAL TO LOCATION THEN 00210200
MOVE '217E' TO MSGCODE 00210300
CALL 'DSN8MCG' USING MODULE, MSGCODE, OUTMSG 00210400
MOVE OUTMSG TO MSGS 00210500
ELSE 00210600
1084 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC 00210700
EXEC SQL UPDATE VEMP 00210800
SET FIRSTNME = :EMP-FIRST-NAME, 00210900
MIDINIT = :EMP-MID-INIT, 00211000
LASTNAME = :EMP-LAST-NAME, 00211100
WORKDEPT = :EMP-WORK-DEPT 00211200
WHERE EMPNO = :DATAW 00211300
END-EXEC 00211400
IF SQLCODE = -530 THEN 00211500
MOVE '203E' TO MSGCODE 00211600
CALL 'DSN8MCG' USING MODULE, MSGCODE, OUTMSG 00211700
MOVE OUTMSG TO MSGS 00211800
ELSE 00211900
IF SQLCODE = 0 THEN 00212000
MOVE '004I' TO MSGCODE 00212100
CALL 'DSN8MCG' USING MODULE, MSGCODE, OUTMSG 00212200
MOVE OUTMSG TO MSGS 00212300
ELSE 00212400
GO TO L8000-P3-DBERROR. 00212500
CALL 'ISPLINK' USING I-DISPLAY, EMP-PANEL. 00212600
6230-UPDATEEMP-EXIT. 00212700
EXIT. 00212800
* 00212900
*--------------------------------------------------------------* 00213000
* DB2 ERROR PROCESSING * 00213100
*--------------------------------------------------------------* 00213200
L8000-P3-DBERROR. 00213300
00213400
MOVE SQLCAID TO SQLCAID-VALUE. 00213500
MOVE SQLCABC TO CONV. 00213600
MOVE CONV TO SQLCABC-VALUE. 00213700
MOVE SQLCODE TO CONV. 00213800
MOVE CONV TO SQLCODE-VALUE, SQLCODE-MSG. 00213900
MOVE SQLERRML TO CONV. 00214000
MOVE CONV TO SQLERRML-VALUE. 00214100
MOVE SQLERRMC TO SQLERRMC-VALUE. 00214200
MOVE SQLERRP TO SQLERRP-VALUE. 00214300
MOVE SQLERRD (1) TO CONV. 00214400
MOVE CONV TO SQLERRD1-VALUE. 00214500
MOVE SQLERRD (2) TO CONV. 00214600
MOVE CONV TO SQLERRD2-VALUE. 00214700
MOVE SQLERRD (3) TO CONV. 00214800
MOVE CONV TO SQLERRD3-VALUE. 00214900
MOVE SQLERRD (4) TO CONV. 00215000
MOVE CONV TO SQLERRD4-VALUE. 00215100
MOVE SQLERRD (5) TO CONV. 00215200
MOVE CONV TO SQLERRD5-VALUE. 00215300
MOVE SQLERRD (6) TO CONV. 00215400
MOVE CONV TO SQLERRD6-VALUE. 00215500
MOVE SQLWARN0 TO SQLWARN0-VALUE. 00215600
MOVE SQLWARN1 TO SQLWARN1-VALUE. 00215700
MOVE SQLWARN2 TO SQLWARN2-VALUE. 00215800
MOVE SQLWARN3 TO SQLWARN3-VALUE. 00215900
MOVE SQLWARN4 TO SQLWARN4-VALUE. 00216000
MOVE SQLWARN5 TO SQLWARN5-VALUE. 00216100
MOVE SQLWARN6 TO SQLWARN6-VALUE. 00216200
MOVE SQLWARN7 TO SQLWARN7-VALUE. 00216300
MOVE SQLWARN8 TO SQLWARN8-VALUE. 00216400
MOVE SQLWARN9 TO SQLWARN9-VALUE. 00216500
MOVE SQLWARNA TO SQLWARNA-VALUE. 00216600
MOVE SQLSTATE TO SQLSTATE-VALUE. 00216700
00216800
OPEN OUTPUT MSGOUT. 00216900
WRITE MSGREC FROM SQLCA-LINE0. 00217000
WRITE MSGREC FROM SQLCA-LINE1. 00217100
WRITE MSGREC FROM SQLCA-LINE2. 00217200
WRITE MSGREC FROM SQLCA-LINE3. 00217300
WRITE MSGREC FROM SQLCA-LINE4. 00217400
WRITE MSGREC FROM SQLCA-LINE5. 00217500
WRITE MSGREC FROM SQLCA-LINE6. 00217600
WRITE MSGREC FROM SQLCA-LINE7. 00217700
WRITE MSGREC FROM SQLCA-LINE8. 00217800
WRITE MSGREC FROM SQLCA-LINE9. 00217900
WRITE MSGREC FROM SQLCA-LINE10. 00218000
WRITE MSGREC FROM SQLCA-LINE11. 00218100
WRITE MSGREC FROM SQLCA-LINE12. 00218200
WRITE MSGREC FROM SQLCA-LINE13. 00218300
WRITE MSGREC FROM SQLCA-LINE14. 00218400
CLOSE MSGOUT. 00218500
00218600
GOBACK. 00218700
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1085
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSN8SC3
THIS MODULE LISTS EMPLOYEE PHONE NUMBERS AND UPDATES THEM IF DESIRED.
1086 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* DSN8004I - EMPLOYEE SUCCESSFULLY UPDATED * 00007100
* DSN8008I - NO EMPLOYEE FOUND IN TABLE * 00007200
* DSN8060E - SQL ERROR, RETURN CODE IS: * 00007300
* DSN8079E - CONNECTION TO DB2 NOT ESTABLISHED * 00007400
* * 00007500
* EXTERNAL REFERENCES = * 00007600
* ROUTINES/SERVICES = * 00007700
* DSN8MCG - ERROR MESSAGE ROUTINE * 00007800
* ISPLINK - ISPF SERVICES ROUTINE * 00007900
* * 00008000
* DATA-AREAS = * 00008100
* NONE * 00008200
* * 00008300
* CONTROL-BLOCKS = * 00008400
* SQLCA - SQL COMMUNICATION AREA * 00008500
* * 00008600
* TABLES = NONE * 00008700
* * 00008800
* * 00008900
* CHANGE-ACTIVITY: * 00009000
* * 00009100
* CHECK SQLERRP FOR NON-BLANKS TO ENSURE CONNECTION V2R3 * 00009200
* HAS BEEN ESTABLISHED. ISSUE 079E IF NOT. * 00009300
* * 00009400
* *PSEUDOCODE* * 00009500
* * 00009600
* SET UP RETURN CODE HANDLING 0000-PROGRAM-START* 00009700
* DO UNTIL NO MORE TERMINAL INPUT * 00009800
* GET PANEL INPUT 1000-MAIN-LOOP * 00009900
* DETERMINE PROCESSING REQUEST 2000-GET-TYPE * 00010000
* -IF "LIST ALL" (*): 3000-LIST-ALL * 00010100
* FETCH FIRST RECORD * 00010200
* CREATE ISPF TABLE * 00010300
* DO UNTIL NO MORE RECORDS: * 00010400
* STORE RECORD IN TABLE 3500-LIST-AND-GET * 00010500
* GET ANOTHER RECORD * 00010600
* -IF "LIST GENERIC" (%): 4000-LIST-GENERIC * 00010700
* FETCH FIRST RECORD * 00010800
* CREATE ISPF TABLE * 00010900
* DO UNTIL NO MORE MATCHING RECORDS: * 00011000
* STORE RECORD IN TABLE 4500-LIST-AND-GET * 00011100
* GET ANOTHER RECORD * 00011200
* -IF "LIST SPECIFIC: 5000-LIST-SPECIFIC* 00011300
* FETCH FIRST RECORD * 00011400
* CREATE ISPF TABLE * 00011500
* DO UNTIL NO MORE MATCHING RECORDS: * 00011600
* STORE RECORD IN TABLE 5500-LIST-AND-GET * 00011700
* GET ANOTHER RECORD * 00011800
* DISPLAY PHONE LIST ON SCREEN 6000-DISPLAY-LIST * 00011900
* IF UPDATE REQUESTED 6500-UPDATE-LOOP * 00012000
* UPDATE PHONE RECORDS 7000-UPDATE * 00012100
*---------------------------------------------------------------* 00012200
ENVIRONMENT DIVISION. 00012300
DATA DIVISION. 00012400
WORKING-STORAGE SECTION. 00012500
*---------------------------------------------------------------* 00012600
77 COIBM PIC X(54) VALUE IS 00012700
'COPYRIGHT = 5740-XYR (C) COPYRIGHT IBM CORP 1982, 1987'. 00012800
77 SEL-EXIT PIC X(01). 00012900
77 DIS-EXIT PIC X(01). 00013000
77 DISPLAY-TABLE PIC X(01). 00013100
77 MORE-CHANGES PIC X(01). 00013200
77 ROWS-CHANGED PIC 9(04). 00013300
77 PERCENT-COUNTER PIC S9(4) COMP. 00013400
77 MODULE PIC X(07) VALUE 'DSN8SC3'. 00013500
77 MSGCODE PIC X(04). 00013600
77 W-BLANK PIC X(01) VALUE ' '. 00013700
77 MSGS-VAR PIC X(08) VALUE 'DSN8MSGS'. 00013800
77 FI-VAR PIC X(08) VALUE 'FNAMEI '. 00013900
77 LI-VAR PIC X(08) VALUE 'LNAMEI '. 00014000
*--------------------------------------------------------------* 00014100
* ISPF DIALOG VARIABLE NAMES * 00014200
*--------------------------------------------------------------* 00014300
EXEC SQL INCLUDE SQLCA END-EXEC. 00014400
01 LNAMEW PIC X(15). 00014500
01 FNAMEW PIC X(12). 00014600
01 LIST-PANEL-VARIABLES. 00014700
03 CH-VAR PIC X(08) VALUE 'ZTDSELS '. 00014800
03 FN-VAR PIC X(08) VALUE 'FNAMED '. 00014900
03 MI-VAR PIC X(08) VALUE 'MINITD '. 00015000
03 LN-VAR PIC X(08) VALUE 'LNAMED '. 00015100
03 PN-VAR PIC X(08) VALUE 'PNOD '. 00015200
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1087
03 EN-VAR PIC X(08) VALUE 'ENOD '. 00015300
03 WD-VAR PIC X(08) VALUE 'WDEPTD '. 00015400
03 WN-VAR PIC X(08) VALUE 'WNAMED '. 00015500
03 TABLE-NAME PIC X(08) VALUE 'DSN8TABL'. 00015600
03 SEL-VARS PIC X(20) VALUE IS 00015700
'( FNAMEI LNAMEI ) '. 00015800
03 DIS-VARS PIC X(56) VALUE IS 00015900
'( ZTDSELS FNAMED MINITD LNAMED PNOD ENOD WDEPTD WNAMED )'. 00016000
03 EMP-VARS PIC X(48) VALUE IS 00016100
'( FNAMED MINITD LNAMED PNOD ENOD WDEPTD WNAMED )'. 00016200
01 PANEL-VARIABLE-LENGTHS. 00016300
03 CH-VAR-STG PIC 9(06) COMP VALUE 04. 00016400
03 FN-VAR-STG PIC 9(06) COMP VALUE 12. 00016500
03 MI-VAR-STG PIC 9(06) COMP VALUE 01. 00016600
03 LN-VAR-STG PIC 9(06) COMP VALUE 15. 00016700
03 PN-VAR-STG PIC 9(06) COMP VALUE 04. 00016800
03 EN-VAR-STG PIC 9(06) COMP VALUE 06. 00016900
03 WD-VAR-STG PIC 9(06) COMP VALUE 03. 00017000
03 WN-VAR-STG PIC 9(06) COMP VALUE 36. 00017100
03 FI-VAR-STG PIC 9(06) COMP VALUE 12. 00017200
03 LI-VAR-STG PIC 9(06) COMP VALUE 15. 00017300
03 MSGS-VAR-STG PIC 9(06) COMP VALUE 79. 00017400
*---------------------------------------------------------------* 00017500
* ISPF DIALOG SERVICES DECLARATIONS * 00017600
*---------------------------------------------------------------* 00017700
01 I-VDEFINE PIC X(08) VALUE 'VDEFINE '. 00017800
01 I-VGET PIC X(08) VALUE 'VGET '. 00017900
01 I-VPUT PIC X(08) VALUE 'VPUT '. 00018000
01 I-DISPLAY PIC X(08) VALUE 'DISPLAY '. 00018100
01 I-TBDISPL PIC X(08) VALUE 'TBDISPL '. 00018200
01 I-TBTOP PIC X(08) VALUE 'TBTOP '. 00018300
01 I-TBCREATE PIC X(08) VALUE 'TBCREATE'. 00018400
01 I-TBCLOSE PIC X(08) VALUE 'TBCLOSE '. 00018500
01 I-TBADD PIC X(08) VALUE 'TBADD '. 00018600
01 I-TBPUT PIC X(08) VALUE 'TBPUT '. 00018700
*---------------------------------------------------------------* 00018800
* ISPF CALL MODIFIERS * 00018900
*---------------------------------------------------------------* 00019000
01 I-NOWRITE PIC X(08) VALUE 'NOWRITE '. 00019100
01 I-REPLACE PIC X(08) VALUE 'REPLACE '. 00019200
01 I-CHAR PIC X(08) VALUE 'CHAR '. 00019300
*---------------------------------------------------------------* 00019400
* ISPF PANEL NAMES * 00019500
*---------------------------------------------------------------* 00019600
01 SEL-PANEL PIC X(08) VALUE 'DSN8SSL '. 00019700
01 DIS-PANEL PIC X(08) VALUE 'DSN8SSN '. 00019800
*---------------------------------------------------------------* 00019900
* LOCAL-VARIABLES * 00020000
*---------------------------------------------------------------* 00020100
01 LOCAL-VARIABLES. 00020200
03 LNAMEI PIC X(15) VALUE SPACES. 00020300
03 FNAMEI PIC X(12) VALUE SPACES. 00020400
03 CONVSQL PIC S9(15) COMP-3. 00020500
03 OUTMSG PIC X(69). 00020600
03 TMSG REDEFINES OUTMSG. 00020700
05 TMSGTXT PIC X(46). 00020800
05 FILLER PIC X(23). 00020900
03 MSGS PIC X(79) VALUE SPACES. 00021000
03 MSGS-DETAIL REDEFINES MSGS. 00021100
05 OUT-MESSAGE PIC X(46). 00021200
05 SQL-CODE PIC +(04). 00021300
05 FILLER PIC X(29). 00021400
*---------------------------------------------------------------* 00021500
* EMPLOYEE RECORD - IO AREA * 00021600
*---------------------------------------------------------------* 00021700
01 EMP-RECORD. 00021800
02 EMPLAST PIC X(15). 00021900
02 EMP-FIRST-NAME PIC X(12). 00022000
02 EMP-MIDDLE-INITIAL PIC X(01). 00022100
02 EMPPHONE PIC X(04). 00022200
02 EMPNUMB PIC X(06). 00022300
02 EMP-DEPT-NUMBER PIC X(03). 00022400
02 EMP-DEPTNAME PIC X(36). 00022500
*---------------------------------------------------------------* 00022600
* SQL DECLARATION FOR VIEW PHONE * 00022700
*---------------------------------------------------------------* 00022800
EXEC SQL DECLARE VPHONE TABLE 00022900
(LASTNAME VARCHAR(15) , 00023000
FIRSTNAME VARCHAR(12) , 00023100
MIDDLEINITIAL CHAR(1) , 00023200
PHONENUMBER CHAR(4) , 00023300
EMPLOYEENUMBER CHAR(6) , 00023400
1088 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
DEPTNUMBER CHAR(3) NOT NULL, 00023500
DEPTNAME VARCHAR(36) NOT NULL) END-EXEC. 00023600
*---------------------------------------------------------------* 00023700
* STRUCTURE FOR PHONE RECORD * 00023800
*---------------------------------------------------------------* 00023900
01 PPHONE. 00024000
02 LAST-NAME PIC X(15). 00024100
02 FIRST-NAME PIC X(12). 00024200
02 MIDDLE-INITIAL PIC X(01). 00024300
02 PHONE-NUMBER PIC X(04). 00024400
02 EMPLOYEE-NUMBER PIC X(06). 00024500
02 DEPT-NUMBER PIC X(03). 00024600
02 DEPTNAME PIC X(36). 00024700
*---------------------------------------------------------------* 00024800
* SQL DECLARATION FOR VIEW VEMPLP * 00024900
*---------------------------------------------------------------* 00025000
EXEC SQL DECLARE VEMPLP TABLE 00025100
(EMPLOYEENUMBER CHAR(6) , 00025200
PHONENUMBER CHAR(4)) END-EXEC. 00025300
*---------------------------------------------------------------* 00025400
* SQL CURSORS * 00025500
*---------------------------------------------------------------* 00025600
EXEC SQL DECLARE TELE1 CURSOR FOR 00025700
SELECT * 00025800
FROM VPHONE 00025900
END-EXEC. 00026000
* 00026100
EXEC SQL DECLARE TELE2 CURSOR FOR 00026200
SELECT * 00026300
FROM VPHONE 00026400
WHERE LASTNAME LIKE :LNAMEW 00026500
AND FIRSTNAME LIKE :FNAMEW 00026600
END-EXEC. 00026700
* 00026800
EXEC SQL DECLARE TELE3 CURSOR FOR 00026900
SELECT * 00027000
FROM VPHONE 00027100
WHERE LASTNAME = :LNAMEW 00027200
AND FIRSTNAME LIKE :FNAMEW 00027300
END-EXEC. 00027400
* 00027500
EJECT 00027600
PROCEDURE DIVISION. 00027700
*---------------------------------------------------------------* 00027800
* SQL RETURN CODE HANDLING * 00027900
*---------------------------------------------------------------* 00028000
EXEC SQL WHENEVER SQLERROR GOTO L8000-P3-DBERROR END-EXEC. 00028100
EXEC SQL WHENEVER SQLWARNING GOTO L8000-P3-DBERROR END-EXEC. 00028200
EXEC SQL WHENEVER NOT FOUND CONTINUE END-EXEC. 00028300
* 00028400
*---------------------------------------------------------------* 00028500
* DEFINE COBOL - SPF VARIABLES * 00028600
*---------------------------------------------------------------* 00028700
0000-PROGRAM-START. 00028800
CALL 'ISPLINK' USING I-VDEFINE, CH-VAR, ROWS-CHANGED, 00028900
I-CHAR, CH-VAR-STG. 00029000
CALL 'ISPLINK' USING I-VDEFINE, FN-VAR, EMP-FIRST-NAME, 00029100
I-CHAR, FN-VAR-STG. 00029200
CALL 'ISPLINK' USING I-VDEFINE, MI-VAR, EMP-MIDDLE-INITIAL, 00029300
I-CHAR, MI-VAR-STG. 00029400
CALL 'ISPLINK' USING I-VDEFINE, LN-VAR, EMPLAST, 00029500
I-CHAR, LN-VAR-STG. 00029600
CALL 'ISPLINK' USING I-VDEFINE, PN-VAR, EMPPHONE, 00029700
I-CHAR, PN-VAR-STG. 00029800
CALL 'ISPLINK' USING I-VDEFINE, EN-VAR, EMPNUMB, 00029900
I-CHAR, EN-VAR-STG. 00030000
CALL 'ISPLINK' USING I-VDEFINE, WD-VAR, EMP-DEPT-NUMBER, 00030100
I-CHAR, WD-VAR-STG. 00030200
CALL 'ISPLINK' USING I-VDEFINE, WN-VAR, EMP-DEPTNAME, 00030300
I-CHAR, WN-VAR-STG. 00030400
CALL 'ISPLINK' USING I-VDEFINE, FI-VAR, FNAMEI, 00030500
I-CHAR, FI-VAR-STG. 00030600
CALL 'ISPLINK' USING I-VDEFINE, LI-VAR, LNAMEI, 00030700
I-CHAR, LI-VAR-STG. 00030800
CALL 'ISPLINK' USING I-VDEFINE, MSGS-VAR, MSGS, 00030900
I-CHAR, MSGS-VAR-STG. 00031000
* 00031100
*---------------------------------------------------------------* 00031200
* MAIN PROGRAM * 00031300
*---------------------------------------------------------------* 00031400
MOVE 'N' TO SEL-EXIT. 00031500
PERFORM 1000-MAIN-LOOP THRU 1000-MAIN-LOOP-EXIT 00031600
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1089
UNTIL SEL-EXIT = 'Y'. 00031700
MOVE 0 TO RETURN-CODE. 00031800
GOBACK. 00031900
* 00032000
1000-MAIN-LOOP. 00032100
CALL 'ISPLINK' USING I-DISPLAY, SEL-PANEL. 00032200
MOVE SPACES TO MSGS. 00032300
MOVE SPACES TO OUTMSG. 00032400
IF RETURN-CODE = 8 00032500
MOVE 'Y' TO SEL-EXIT 00032600
ELSE 00032700
MOVE 'N' TO DISPLAY-TABLE 00032800
CALL 'ISPLINK' USING I-VGET, SEL-VARS 00032900
MOVE LNAMEI TO LNAMEW 00033000
MOVE FNAMEI TO FNAMEW 00033100
PERFORM 2000-GET-TYPE THRU 2000-GET-TYPE-EXIT 00033200
IF DISPLAY-TABLE = 'Y' 00033300
PERFORM 6000-DISPLAY-LIST 00033400
THRU 6000-DISPLAY-LIST-EXIT. 00033500
CALL 'ISPLINK' USING I-VPUT MSGS-VAR. 00033600
1000-MAIN-LOOP-EXIT. 00033700
EXIT. 00033800
* 00033900
*---------------------------------------------------------------* 00034000
* DETERMINE PROCESSING REQUEST * 00034100
*---------------------------------------------------------------* 00034200
2000-GET-TYPE. 00034300
IF LNAMEW = '*' 00034400
PERFORM 3000-LIST-ALL 00034500
THRU 3000-LIST-ALL-EXIT 00034600
ELSE 00034700
UNSTRING LNAMEW 00034800
DELIMITED BY SPACE 00034900
INTO LNAMEW 00035000
UNSTRING FNAMEW 00035100
DELIMITED BY SPACE 00035200
INTO FNAMEW 00035300
INSPECT FNAMEW 00035400
REPLACING ALL ' ' BY '%' 00035500
MOVE 0 TO PERCENT-COUNTER 00035600
INSPECT LNAMEW 00035700
TALLYING PERCENT-COUNTER FOR ALL '%' 00035800
IF PERCENT-COUNTER > 0 00035900
INSPECT LNAMEW 00036000
REPLACING ALL ' ' BY '%' 00036100
PERFORM 4000-LIST-GENERIC 00036200
THRU 4000-LIST-GENERIC-EXIT 00036300
ELSE 00036400
PERFORM 5000-LIST-SPECIFIC 00036500
THRU 5000-LIST-SPECIFIC-EXIT. 00036600
2000-GET-TYPE-EXIT. 00036700
EXIT. 00036800
* 00036900
*---------------------------------------------------------------* 00037000
* LIST ALL EMPLOYEES * 00037100
*---------------------------------------------------------------* 00037200
3000-LIST-ALL. 00037300
EXEC SQL OPEN TELE1 END-EXEC. 00037400
MOVE SPACES TO SQLERRP. 00037500
EXEC SQL FETCH TELE1 INTO :PPHONE END-EXEC. 00037600
IF SQLERRP = SPACES 00037700
MOVE '079E' TO MSGCODE 00037800
CALL 'DSN8MCG' USING MODULE, MSGCODE, OUTMSG 00037900
MOVE OUTMSG TO MSGS 00038000
ELSE 00038100
IF SQLCODE = 100 00038200
MOVE '008I' TO MSGCODE 00038300
CALL 'DSN8MCG' USING MODULE, MSGCODE, OUTMSG 00038400
MOVE OUTMSG TO MSGS 00038500
ELSE 00038600
MOVE 'Y' TO DISPLAY-TABLE 00038700
CALL 'ISPLINK' USING I-TBCREATE, TABLE-NAME, 00038800
W-BLANK, EMP-VARS, I-NOWRITE, I-REPLACE 00038900
PERFORM 3500-LIST-AND-GET 00039000
THRU 3500-LIST-AND-GET-EXIT 00039100
UNTIL SQLCODE NOT EQUAL 0. 00039200
EXEC SQL CLOSE TELE1 END-EXEC. 00039300
3000-LIST-ALL-EXIT. 00039400
EXIT. 00039500
* 00039600
3500-LIST-AND-GET. 00039700
MOVE PPHONE TO EMP-RECORD. 00039800
1090 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
CALL 'ISPLINK' USING I-TBADD, TABLE-NAME. 00039900
EXEC SQL FETCH TELE1 INTO :PPHONE END-EXEC. 00040000
3500-LIST-AND-GET-EXIT. 00040100
EXIT. 00040200
* 00040300
*---------------------------------------------------------------* 00040400
* GENERIC LIST OF EMPLOYEES * 00040500
*---------------------------------------------------------------* 00040600
4000-LIST-GENERIC. 00040700
EXEC SQL OPEN TELE2 END-EXEC. 00040800
MOVE SPACES TO SQLERRP. 00040900
EXEC SQL FETCH TELE2 INTO :PPHONE END-EXEC. 00041000
IF SQLERRP = SPACES 00041100
MOVE '079E' TO MSGCODE 00041200
CALL 'DSN8MCG' USING MODULE, MSGCODE, OUTMSG 00041300
MOVE OUTMSG TO MSGS 00041400
ELSE 00041500
IF SQLCODE = 100 00041600
MOVE '008I' TO MSGCODE 00041700
CALL 'DSN8MCG' USING MODULE, MSGCODE, OUTMSG 00041800
MOVE OUTMSG TO MSGS 00041900
ELSE 00042000
MOVE 'Y' TO DISPLAY-TABLE 00042100
CALL 'ISPLINK' USING I-TBCREATE, TABLE-NAME, W-BLANK,00042200
EMP-VARS, I-NOWRITE, I-REPLACE 00042300
PERFORM 4500-LIST-AND-GET 00042400
THRU 4500-LIST-AND-GET-EXIT 00042500
UNTIL SQLCODE NOT EQUAL 0. 00042600
EXEC SQL CLOSE TELE2 END-EXEC. 00042700
4000-LIST-GENERIC-EXIT. 00042800
EXIT. 00042900
* 00043000
4500-LIST-AND-GET. 00043100
MOVE PPHONE TO EMP-RECORD. 00043200
CALL 'ISPLINK' USING I-TBADD, TABLE-NAME. 00043300
EXEC SQL FETCH TELE2 INTO :PPHONE END-EXEC. 00043400
4500-LIST-AND-GET-EXIT. 00043500
EXIT. 00043600
*---------------------------------------------------------------* 00043700
* SPECIFIC LIST OF EMPLOYEES * 00043800
*---------------------------------------------------------------* 00043900
5000-LIST-SPECIFIC. 00044000
EXEC SQL OPEN TELE3 END-EXEC. 00044100
MOVE SPACES TO SQLERRP. 00044200
EXEC SQL FETCH TELE3 INTO :PPHONE END-EXEC. 00044300
IF SQLERRP = SPACES 00044400
MOVE '079E' TO MSGCODE 00044500
CALL 'DSN8MCG' USING MODULE, MSGCODE, OUTMSG 00044600
MOVE OUTMSG TO MSGS 00044700
ELSE 00044800
IF SQLCODE = 100 00044900
MOVE '008I' TO MSGCODE 00045000
CALL 'DSN8MCG' USING MODULE, MSGCODE, OUTMSG 00045100
MOVE OUTMSG TO MSGS 00045200
ELSE 00045300
MOVE 'Y' TO DISPLAY-TABLE 00045400
CALL 'ISPLINK' USING I-TBCREATE, TABLE-NAME, 00045500
W-BLANK, EMP-VARS, I-NOWRITE, I-REPLACE 00045600
PERFORM 5500-LIST-AND-GET 00045700
THRU 5500-LIST-AND-GET-EXIT 00045800
UNTIL SQLCODE NOT EQUAL 0. 00045900
EXEC SQL CLOSE TELE3 END-EXEC. 00046000
5000-LIST-SPECIFIC-EXIT. 00046100
EXIT. 00046200
* 00046300
5500-LIST-AND-GET. 00046400
MOVE PPHONE TO EMP-RECORD. 00046500
CALL 'ISPLINK' USING I-TBADD, TABLE-NAME. 00046600
EXEC SQL FETCH TELE3 INTO :PPHONE END-EXEC. 00046700
5500-LIST-AND-GET-EXIT. 00046800
EXIT. 00046900
* 00047000
*---------------------------------------------------------------* 00047100
* DISPLAY EMPLOYEE PHONE NUMBERS * 00047200
*---------------------------------------------------------------* 00047300
6000-DISPLAY-LIST. 00047400
EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC. 00047500
EXEC SQL WHENEVER SQLWARNING CONTINUE END-EXEC. 00047600
CALL 'ISPLINK' USING I-TBTOP, TABLE-NAME. 00047700
CALL 'ISPLINK' USING I-TBDISPL, TABLE-NAME, DIS-PANEL. 00047800
IF RETURN-CODE NOT EQUAL 8 00047900
CALL 'ISPLINK' USING I-VGET, DIS-VARS 00048000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1091
PERFORM 6500-UPDATE-LOOP THRU 6500-UPDATE-LOOP-EXIT. 00048100
6000-DISPLAY-LIST-EXIT. 00048200
EXIT. 00048300
* 00048400
*---------------------------------------------------------------* 00048500
* DETERMINE IF UPDATE HAS BEEN REQUESTED * 00048600
*---------------------------------------------------------------* 00048700
6500-UPDATE-LOOP. 00048800
IF ROWS-CHANGED > 0 00048900
MOVE 'Y' TO MORE-CHANGES 00049000
PERFORM 7000-UPDATE THRU 7000-UPDATE-EXIT 00049100
UNTIL MORE-CHANGES = 'N'. 00049200
CALL 'ISPLINK' USING I-TBCLOSE, TABLE-NAME. 00049300
6500-UPDATE-LOOP-EXIT. 00049400
EXIT. 00049500
* 00049600
*---------------------------------------------------------------* 00049700
* UPDATE EMPLOYEE PHONE NUMBERS * 00049800
*---------------------------------------------------------------* 00049900
7000-UPDATE. 00050000
EXEC SQL UPDATE VEMPLP 00050100
SET PHONENUMBER = :EMPPHONE 00050200
WHERE EMPLOYEENUMBER = :EMPNUMB END-EXEC. 00050300
IF SQLCODE NOT EQUAL 0 00050400
MOVE '060E' TO MSGCODE 00050500
CALL 'DSN8MCG' USING MODULE, MSGCODE, OUTMSG 00050600
MOVE OUTMSG TO TMSG 00050700
MOVE TMSGTXT TO OUT-MESSAGE 00050800
MOVE SQLCODE TO CONVSQL 00050900
MOVE CONVSQL TO SQL-CODE 00051000
EXEC SQL ROLLBACK END-EXEC 00051100
MOVE 'N' TO MORE-CHANGES 00051200
ELSE 00051300
MOVE '004I' TO MSGCODE 00051400
CALL 'DSN8MCG' USING MODULE, MSGCODE, OUTMSG 00051500
MOVE OUTMSG TO MSGS 00051600
CALL 'ISPLINK' USING I-TBPUT, TABLE-NAME 00051700
IF ROWS-CHANGED > 1 00051800
CALL 'ISPLINK' USING I-TBDISPL, TABLE-NAME 00051900
CALL 'ISPLINK' USING I-VGET, DIS-VARS 00052000
ELSE MOVE 'N' TO MORE-CHANGES. 00052100
7000-UPDATE-EXIT. 00052200
EXIT. 00052300
* 00052400
*---------------------------------------------------------------* 00052500
* DB2 ERROR PROCESSING * 00052600
*---------------------------------------------------------------* 00052700
L8000-P3-DBERROR. 00052800
MOVE '060E' TO MSGCODE. 00052900
CALL 'DSN8MCG' USING MODULE, MSGCODE, OUTMSG. 00053000
MOVE OUTMSG TO TMSG. 00053100
MOVE TMSGTXT TO OUT-MESSAGE. 00053200
MOVE SQLCODE TO CONVSQL. 00053300
MOVE CONVSQL TO SQL-CODE. 00053400
CALL 'ISPLINK' USING I-VPUT, MSGS-VAR. 00053500
GOBACK. 00053600
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSN8SP3
THIS MODULE LISTS EMPLOYEE PHONE NUMBERS AND UPDATES THEM IF DESIRED.
1092 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* *
* STATUS = VERSION 2 RELEASE 3, LEVEL 0 *
* *
* FUNCTION = THIS MODULE LISTS EMPLOYEE PHONE NUMBERS AND *
* UPDATES THEM IF DESIRED. *
* *
* NOTES = *
* DEPENDENCIES = TWO ISPF PANELS ARE REQUIRED: *
* DSN8SSL AND DSN8SSN *
* RESTRICTIONS = NONE *
* *
* MODULE TYPE = PL/I PROC OPTIONS(MAIN) *
* PROCESSOR = DB2 PRECOMPILER, PL/I OPTIMIZER *
* MODULE SIZE = SEE LINKEDIT *
* ATTRIBUTES = REENTRANT *
* *
* ENTRY POINT = DSN8SP3 *
* PURPOSE = SEE FUNCTION *
* LINKAGE = INVOKED FROM ISPF *
* *
* INPUT = PARAMETERS EXPLICITLY PASSED TO THIS FUNCTION: *
* INPUT-MESSAGE: *
* *
* SYMBOLIC LABEL/NAME = DSN8SSL *
* DESCRIPTION = PHONE MENU 1 (SELECT) *
* *
* SYMBOLIC LABEL/NAME = DSN8SSN *
* DESCRIPTION = PHONE MENU 2 (LIST) *
* *
* SYMBOLIC LABEL/NAME = VPHONE *
* DESCRIPTION = VIEW OF TELEPHONE INFORMATION *
* *
* SYMBOLIC LABEL/NAME = VEMPLP *
* DESCRIPTION = VIEW OF EMPLOYEE INFORMATION *
* *
* OUTPUT = PARAMETERS EXPLICITLY RETURNED: *
* OUTPUT-MESSAGE: *
* *
* SYMBOLIC LABEL/NAME = DSN8SSL *
* DESCRIPTION = PHONE MENU 1 (SELECT) *
* *
* SYMBOLIC LABEL/NAME = DSN8SSN *
* DESCRIPTION = PHONE MENU 2 (LIST) *
* *
* EXIT-NORMAL = RETURN CODE 0 NORMAL COMPLETION *
* *
* EXIT-ERROR = *
* *
* RETURN CODE = NONE *
* *
* ABEND CODES = NONE *
* *
* *
* ERROR-MESSAGES = *
* DSN8004I - EMPLOYEE SUCCESSFULLY UPDATED *
* DSN8008I - NO EMPLOYEE FOUND IN TABLE *
* DSN8060E - SQL ERROR, RETURN CODE IS: *
* DSN8079E - CONNECTION TO DB2 NOT ESTABLISHED *
* *
* EXTERNAL REFERENCES = *
* ROUTINES/SERVICES = *
* DSN8MPG - ERROR MESSAGE ROUTINE *
* ISPLINK - ISPF SERVICES ROUTINE *
* *
* DATA-AREAS = *
* NONE *
* *
* CONTROL-BLOCKS = *
* SQLCA - SQL COMMUNICATION AREA *
* *
* TABLES = NONE *
* *
* *
* CHANGE-ACTIVITY: *
* *
* CHECK SQLERRP FOR NON-BLANKS TO ENSURE CONNECTION V2R3 *
* HAS BEEN ESTABLISHED. ISSUE 079E IF NOT. *
* *
* *PSEUDOCODE* *
* *
* PROCEDURE *
* DO WHILE NOT EXIT-PRESSED *
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1093
* CALL GET-TYPE *
* CALL GET-LIST *
* CALL DISPLAY-LIST *
* *
* GET_TYPE: *
* IF LASTNAME IS '*' *
* TYPE = 'ALL' *
* ELSE *
* IF LASTNAME CONTAINS '%' *
* TYPE = 'GENERIC' *
* ELSE *
* TYPE = 'SPECIFIC' *
* *
* GET_LIST: *
* CASE (TYPE) *
* SUBCASE ('ALL') *
* GET ALL EMPLOYEES *
* SUBCASE ('GENERIC') *
* GET GENERIC EMPLOYEES *
* SUBCASE ('GENERIC') *
* GET SPECIFIC EMPLOYEES *
* ENDSUB *
* *
* DISPLAY_LIST: *
* DISPLAY LIST *
* IF NOT EXIT-PRESSED *
* UPDATE PHONE NUMBER(S) *
* WRITE CONFIRMATION MESSAGE *
* *
* P3_DBERROR: *
* IF SQL ERROR OCCURS THEN *
* FORMAT ERROR MESSAGE *
* ROLLBACK *
* END *
* END. *
*********************************************************************/
/********************************************************************/
/* DECLARATION FOR BUILTIN FUNCTIONS */
/********************************************************************/
/********************************************************************/
/* MESSAGE ROUTINE DECLARATIONS */
/********************************************************************/
1/********************************************************************/
/* ISPF DIALOG VARIABLE NAMES */
/********************************************************************/
1094 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
INIT('( ZTDSELS FNAMED MINITD LNAMED PNOD ENOD WDEPTD WNAMED )');
DCL EMP_VARS CHAR(48) STATIC /*DISPLAY VARS */
INIT('( FNAMED MINITD LNAMED PNOD ENOD WDEPTD WNAMED )');
/********************************************************************/
/* ISPF DIALOG SERVICES DECLARATIONS */
/********************************************************************/
/* PROGRAM NAME */
DCL ISPLINK EXTERNAL ENTRY OPTIONS(ASM INTER RETCODE);
/* PANEL NAMES */
DCL SEL_PANEL CHAR(8) STATIC INIT('DSN8SSL'); /* SELECTION PANEL */
DCL DIS_PANEL CHAR(8) STATIC INIT('DSN8SSN'); /* LIST PANEL */
1/********************************************************************/
/* DECLARATION FOR PROGRAM LOGIC */
/********************************************************************/
/* CONSTANTS */
DCL YES BIT(1) STATIC INIT('1'B);
DCL NO BIT(1) STATIC INIT('0'B);
DCL ZERO FIXED BIN(31,0) STATIC INIT(0);
/* FLAGS */
DCL SEL_EXIT BIT(1); /* EXIT PRESSED? FLAG */
DCL DIS_EXIT BIT(1); /* EXIT PRESSED? FLAG */
DCL DIS_TABLE BIT(1); /* DISPLAY-TABLE? FLAG */
DCL MORE_CHANGES BIT(1); /* MORE CHANGES TO PROCESS? */
/* DATA VARIABLES */
DCL ROWS_CHANGED PIC'9999';
DCL TYPE CHAR(8); /* TYPE OF LIST */
DCL LNAMES CHAR(15); /* LAST NAME SELECTION VALUE */
DCL FNAMES CHAR(12); /* FIRST NAME SELECTION VALUE */
1/********************************************************************/
/* SQL DECLARATIONS */
/********************************************************************/
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1095
DEPTNUMBER CHAR(3) NOT NULL,
DEPTNAME VARCHAR(36) NOT NULL);
/* STUCTURE FOR PHONE RECORD */
DCL 1 PPHONE,
2 LASTNAME CHAR (15) VAR,
2 FIRSTNAME CHAR (12) VAR,
2 MIDDLEINITIAL CHAR (1),
2 PHONENUMBER CHAR (4),
2 EMPLOYEENUMBER CHAR (6),
2 DEPTNUMBER CHAR (3),
2 DEPTNAME CHAR (36) VAR;
/* SQL DECLARATION FOR VIEW VEMPLP*/
EXEC SQL DECLARE VEMPLP TABLE
(EMPLOYEENUMBER CHAR(6),
PHONENUMBER CHAR(4));
/********************************************************************/
/* CURSOR DECLARATIONS */
/********************************************************************/
1/********************************************************************/
/* SQL RETURN CODE HANDLING */
/********************************************************************/
/********************************************************************/
/* DEFINE PL/I - ISPF VARIABLES */
/********************************************************************/
CALL ISPLINK(I_VDEFINE, CH_VAR, ROWS_CHANGED,
I_CHAR, STG(ROWS_CHANGED));
CALL ISPLINK(I_VDEFINE, FN_VAR, EMP_RECORD.FIRSTNAME,
I_CHAR, STG(EMP_RECORD.FIRSTNAME));
CALL ISPLINK(I_VDEFINE, MI_VAR, EMP_RECORD.MIDDLEINITIAL,
I_CHAR, STG(EMP_RECORD.MIDDLEINITIAL));
CALL ISPLINK(I_VDEFINE, LN_VAR, EMP_RECORD.LASTNAME,
I_CHAR, STG(EMP_RECORD.LASTNAME));
CALL ISPLINK(I_VDEFINE, PN_VAR, EMP_RECORD.PHONENUMBER,
I_CHAR, STG(EMP_RECORD.PHONENUMBER));
CALL ISPLINK(I_VDEFINE, EN_VAR, EMP_RECORD.EMPLOYEENUMBER,
I_CHAR, STG(EMP_RECORD.EMPLOYEENUMBER));
CALL ISPLINK(I_VDEFINE, WD_VAR, EMP_RECORD.DEPTNUMBER,
I_CHAR, STG(EMP_RECORD.DEPTNUMBER));
CALL ISPLINK(I_VDEFINE, WN_VAR, EMP_RECORD.DEPTNAME,
I_CHAR, STG(EMP_RECORD.DEPTNAME));
CALL ISPLINK(I_VDEFINE, FI_VAR, FNAMEI,
I_CHAR, STG(FNAMEI));
CALL ISPLINK(I_VDEFINE, LI_VAR, LNAMEI,
I_CHAR, STG(LNAMEI));
CALL ISPLINK(I_VDEFINE, MSGS_VAR, MSGS,
I_CHAR, STG(MSGS));
1/********************************************************************/
/* MAIN PROGRAM */
/********************************************************************/
1096 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
/******************************************************************/
/* EXIT WAS NOT SPECIFIED SO PROCESS THE REQUEST */
/******************************************************************/
1/********************************************************************/
/* GET TYPE OF LIST */
/********************************************************************/
GET_TYPE: PROCEDURE;
END GET_TYPE;
1/********************************************************************/
/* GET LIST OF EMPLOYEES */
/********************************************************************/
GET_LIST: PROCEDURE;
/********************************************************************/
/* NO EMPLOYEE FULFILLED THE REQUEST */
/********************************************************************/
SELECT;
WHEN (SQLERRP = ' ') /* NO CONNECTION TO DB2 */
DO;
CALL DSN8MPG (MODULE, '079E', OUTMSG);
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1097
MSGS = OUTMSG; /* SET ISPF ERROR MESSAGE */
END; /* END NO EMPLOYEE FOUND */
WHEN (SQLCODE = 100)
DO;
CALL DSN8MPG (MODULE, '008I', OUTMSG);
MSGS = OUTMSG; /* SET ISPF ERROR MESSAGE */
END; /* END NO EMPLOYEE FOUND */
OTHERWISE
/********************************************************************/
/* EMPLOYEES EXIST THAT FULFILL THE REQUEST. DISPLAY THEM. */
/********************************************************************/
SELECT (TYPE);
WHEN ('ALL')
EXEC SQL CLOSE TELE1;
WHEN ('GENERIC')
EXEC SQL CLOSE TELE2;
OTHERWISE
EXEC SQL CLOSE TELE3;
END;
END GET_LIST;
1/********************************************************************/
/* DISPLAY/UPDATE EMPLOYEE PHONE NUMBERS */
/********************************************************************/
DISPLAY_LIST: PROCEDURE;
1098 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
CALL ISPLINK(I_TBDISPL, TABLE_NAME);
CALL ISPLINK(I_VGET, DIS_VARS);
END;
ELSE /* NO MORE CHANGES */
MORE_CHANGES = NO;
END; /* END SUCCESSFUL UPDATE */
END; /* DO WHILE MORE CHANGES */
CALL ISPLINK(I_TBCLOSE, TABLE_NAME); /* CLOSE ISPF TABLE */
END; /* END IF ^DIS_EXIT */
END DISPLAY_LIST;
1/********************************************************************/
/* ERROR HANDLING */
/********************************************************************/
P3_DBERROR:
END DSN8SP3;
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSN8EP1
PASS DB2 COMMANDS TO BE EXECUTED BY THE STORED PROCEDURE PROGRAM DSN8EP2.
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1099
* MAXPAGWD 125 PRINT LINE WIDTH CONTROLLER = * 00450000
* MAXIMUM WIDTH - 1 (FOR CONTROL * 00460000
* CHARACTER) - 6 (LENGTH OF THE * 00470000
* COLUMN DISPLAY) - 1 ( A '-' * 00480000
* BETWEEN THE COLUMN NUMBER DISPLAY * 00490000
* THE SQL OUTPUT DISPLAY). * 00500000
* * 00510000
* MAXPAGLN 60 MAXIMUM NUMBER OF LINES ON THE * 00520000
* PRINT OUTPUT PAGES 2 THRN N. PAGE * 00530000
* 1 WILL HAVE MAXPAGLN + 1 LINES. * 00540000
* * 00550000
* INPUTL 72 LENGTH OF THE INPUT RECORD * 00560000
* * 00570000
* INPUT = * 00580000
* * 00590000
* 1. INPUT STATEMENTS WILL BE TRANSFERRED * 00600000
* TO THE STATEMENT BUFFER WITH ONE BLANK BETWEEN * 00610000
* WORDS. * 00620000
* * 00630000
* 2. BLANKS IN DELIMITED STRINGS WILL BE * 00640000
* TRANSFERRED INTO THE STATEMENT BUFFER * 00650000
* EXACTLY AS THEY APPEAR IN THE INPUT * 00660000
* STATEMENT. * 00670000
* * 00680000
* 3. AN INPUT LINE CONSISTS OF CHARACTERS FROM * 00690000
* COLUMNS 1-INPUTL. IF AN INPUT STATEMENT SPANS * 00700000
* OVER MULITPLE LINES, THE LINES ARE CONCATENATED * 00710000
* AND BLANKS ARE REMOVED SUCH THAT ONLY ONE * 00720000
* BLANK OCCURS BETWEEN WORDS. * 00730000
* * 00740000
* MODULE TYPE = PROCEDURE * 00750000
* PROCESSOR = * 00760000
* ADMF PRECOMPILER * 00770000
* PL/I MVS/VM (FORMERLY PL/I SAA AD/CYCLE) * 00780000
* MODULE SIZE = 2K * 00790000
* ATTRIBUTES = RE-ENTERABLE * 00800000
* * 00810000
* ENTRY POINT = DSN8EP1 * 00820000
* PURPOSE = SEE FUNCTION * 00830000
* LINKAGE = STANDARD MVS PROGRAM INVOCATION, ONE PARAMETER. * 00840000
* INPUT = PARAMETERS EXPLICITLY PASSED TO THIS FUNCTION: * 00850000
* SYMBOLIC LABEL/NAME = SYSIN * 00860000
* DESCRIPTION = DDNAME OF SEQUENTIAL DATA SET CONTAINING * 00870000
* DB2 COMMANDS TO BE EXECUTED. * 00880000
* OUTPUT = PARAMETERS EXPLICITLY RETURNED: * 00890000
* SYMBOLIC LABEL/NAME = SYSPRINT * 00900000
* DESCRIPTION = DDNAME OF SEQUENTIAL OUTPUT DATA SET TO * 00910000
* CONTAIN RESULTS OF THE COMMANDS EXECUTED. * 00920000
* * 00930000
* EXIT NORMAL = * 00940000
* * 00950000
* NO ERRORS WERE FOUND IN THE SOURCE AND NO * 00960000
* ERRORS OCCURRED DURING PROCESSING. * 00970000
* * 00980000
* * 00990000
* NORMAL MESSAGES = * 01000000
* * 01010000
* 1. THE FOLLOWING MESSAGE WILL BE GENERATED FOR ALL INPUT * 01020000
* STATEMENTS: * 01030000
* * 01040000
* ***INPUT STATEMENT: DB2 COMMAND INPUT STATEMENT * 01050000
* * 01060000
* * 01070000
* EXIT-ERROR = * 01080000
* * 01090000
* ERRORS WERE FOUND IN THE SOURCE, OR OCCURRED DURING * 01100000
* PROCESSING. * 01110000
* * 01120000
* RETURN CODE = 4 - WARNING-LEVEL ERRORS DETECTED. * 01130000
* SQLWARNING OR IFI WARNING FOUND DURING EXECUTION. * 01140000
* REASON CODE = 0 OR IFI REASON CODE * 01150000
* * 01160000
* RETURN CODE = 8 - ERRORS DETECTED. * 01170000
* SQLERROR OR IFI ERROR FOUND DURING EXECUTION. * 01180000
* REASON CODE = 0 OR IFI REASON CODE * 01190000
* * 01200000
* RETURN CODE = 12 - SEVERE ERRORS DETECTED. * 01210000
* ONE OF THE FOLLOWING ERRORS OCCURRED: * 01220000
* UNABLE TO OPEN FILES. * 01230000
* INTERNAL ERROR, ERROR MESSAGE ROUTINE RETURN CODE. * 01240000
* STATEMENT IS TOO LONG. * 01250000
* SQL OR IFI BUFFER OVERFLOW. * 01260000
1100 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* REASON CODE = 0 OR IFI REASON CODE * 01270000
* * 01280000
* ABEND CODES = NONE * 01290000
* * 01300000
* ERROR MESSAGES = * 01310000
* * 01320000
* 1. THE FOLLOWING MESSAGE WILL BE GENERATED WHEN A DB2 * 01330000
* COMMAND DOES NOT BEGIN WITH A HYPHEN "-". * 01340000
* * 01350000
* *** SYNTAX FOR DB2 COMMAND IS NOT VALID. * 01360000
* A VALID COMMAND MUST BEGIN WITH A HYPHEN "-". * 01370000
* * 01380000
* 2. THE FOLLOWING MESSAGE WILL BE GENERATED WHEN AN INPUT * 01390000
* STATEMENT IS GREATER THAN STMTMAX SIZE: * 01400000
* * 01410000
* **ERROR: DB2 COMMAND GREATER THAN NNN CHARACTERS. * 01420000
* STMT: * 01430000
* DB2 COMMAND. * 01440000
* * 01450000
* NNN IS MAXIMUM COMMAND SIZE * 01460000
* DB2 COMMAND IS THE CURRENT DB2 COMMAND BEING * 01470000
* PROCESSED. * 01480000
* * 01490000
* EXTERNAL REFERENCES = * 01500000
* ROUTINES/SERVICES = NONE * 01510000
* DSNTIAR - SQL COMMUNICATION AREA FORMATTING * 01520000
* DATA-AREAS = NONE * 01530000
* CONTROL-BLOCKS = * 01540000
* SQLCA - SQL COMMUNICATION AREA * 01550000
* * 01560000
* PSEUDOCODE = * 01570000
* * 01580000
* DSN8EP1: PROCEDURE. * 01590000
* DECLARATIONS. * 01600000
* INITIALIZE VARIABLES. * 01610000
* CALL READRTN TO READ IN A DB2 COMMAND STATEMENT. * 01620000
* DO UNTIL END-OF-FILE. * 01630000
* CALL READRTN TO READ A NEW DB2 COMMAND STATEMENT. * 01640000
* END. * 01650000
* * 01660000
* HEX2CHAR: PROCEDURE. * 01670000
* CONVERT THE RETURN CODE AND REASON CODE THAT ARE RETURNED * 01680000
* FROM THE IFI CALL FROM BINARY TO HEXADECIMAL. * 01690000
* END HEX2CHAR. * 01700000
* * 01710000
* PRINTCA: PROCEDURE. * 01720000
* CALL DSNTIAR TO FORMAT ANY MESSAGES. * 01730000
* IF A RETURN CODE WAS PASSED FROM DSNTIAR, INDICATE IT. * 01740000
* PRINT THE DATA FORMATTED FORMATTED BY DSNTIAR. * 01750000
* SET THE RETURN CODE TO 8. * 01760000
* END PRINTCA. * 01770000
* * 01780000
* READRTN: PROCEDURE. * 01790000
* SET ENDSTR = "NO". * 01800000
* SET REREAD = "NO". * 01810000
* DO WHILE (ENDSTR = NO). * 01820000
* FILL THE STATEMENT BUFFER FROM THE CURRENT INPUT LINE. * 01830000
* AVOID INITIAL BLANKS. * 01840000
* TERMINATE A STATEMENT WHEN A SEMICOLON IS FOUND. * 01850000
* VERIFY THAT COMMAND IS VALID. * 01860000
* DO SQL TO CALL DSN8EP2. * 01870000
* PROCESS THE COMMAND RESULTS. * 01880000
* SET REREAD FLAG. * 01890000
* RETURN TO CALLER. * 01900000
* END COMMAND. * 01910000
* END READRTN. * 01920000
* * 01930000
* RESULTS: PROCEDURE. * 01940000
* PROCESS THE RETURN CODE, REASON CODE, THE NUMBER OF * 01950000
* BYTES IN THE RETURN BUFFER, AND THE RETURN BUFFER * 01960000
* THAT ARE RETURNED FROM THE IFI CALL. * 01970000
* END RESULTS. * 01980000
* * 01990000
* CHANGE ACTIVITY = * 02000000
* 6/29/95 UPDATED THE REMOTE LOCATION NAME VARIABLES (DB2LOC @03* 02010000
* & PARMS) TO ACCEPT A SIXTEEN CHARACTER NAME @03* 02020000
* (PN69303) @03 KFF0296* 02030000
* 7/05/95 CHANGED THE OUTPUT STRING LENGTH FROM VARYING @35* 02040000
* TO FIXED 80 BYTE STRINGS (PN72035) @35 KFF0347* 02050000
* 8/28/95 ADDED ROLLBACK WORK STATEMENT TO ENSURE THAT DB2 @42* 02060000
* WORK IS ROLLED BACK IN ERROR SITUATIONS @42* 02070000
* (PN74842) @42 KFF0580* 02080000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1101
* 04/17/00 INITIALIZE STORAGE TO PREVENT RETURN CODE=04, * 02090000
* REASON CODE=00E60804 FROM IFI PQ36800* 02100000
* 05/22/03 FIX CODE HOLE CLOSED BY VA AND ENTERPRISE PL/I PQ44916* 02110000
*******************************************************************/ 02120000
%PAGE; 02130000
/*******************************************************************/ 02140000
/* VARIABLE DECLARATIONS */ 02150000
/*******************************************************************/ 02160000
02170000
/*******************************************************************/ 02180000
/* DECLARE IFI-RELATED VARIABLES */ 02190000
/*******************************************************************/ 02200000
DCL 02210000
IFCA_RET_CODE CHAR(8) INIT(' '), /* RETURN CODE IN HEX */ 02220000
IFCA_RES_CODE CHAR(8) INIT(' '), /* REASON CODE IN HEX */ 02230000
INPUTCMD VAR CHAR(4096) INIT(' '),/* DB2 COMMAND */ 02240000
IFCA_RET_HEX FIXED BIN(31) INIT(0), /* RETURN CODE PARAMETER */ 02250000
IFCA_RES_HEX FIXED BIN(31) INIT(0), /* REASON CODE PARAMETER */ 02260000
BUFF_OVERFLOW FIXED BIN(31) INIT(0), /* BUFFER OVERFLOW IND@35*/ 02270000
REMBYTES FIXED BIN(15) INIT(0), /* BYTES REMAINING @35*/ 02280000
RETURN_BUFF VAR CHAR(8320) INIT(' '),/* COMMAND RESULT @35*/ 02290000
RETURN_IND FIXED BIN(15) INIT(0); /* INDICATOR VARIABLE @35*/ 02300000
/* FOR RETURN_BUFFER */ 02310000
02320000
02330000
/*******************************************************************/ 02340000
/* CHARACTER CONSTANTS */ 02350000
/*******************************************************************/ 02360000
02370000
DCL 02380000
ASTERISK CHAR(1) INIT('*') STATIC, /* COMMENT INDICATOR */ 02390000
BLANK CHAR(1) INIT(' ') STATIC, /* INITIALIZATION BLANKS */ 02400000
HYPHEN CHAR(1) INIT('-') STATIC, /* HYPHEN */ 02410000
NULLCHAR CHAR(1) VAR INIT('') STATIC, /* NULL CHARACTER */ 02420000
QUOTE CHAR(1) INIT('''') STATIC, /* QUOTATION MARK */ 02430000
DQUOTE CHAR(1) INIT('"') STATIC, /* DOUBLE QUOTATION MARK */ 02440000
SEMICOLON CHAR(1) INIT(';') STATIC; /* SQL STMT TERMINATOR */ 02450000
02460000
/*******************************************************************/ 02470000
/* PROGRAM INPUT/OUTPUT CONSTANTS */ 02480000
/*******************************************************************/ 02490000
02500000
DCL 02510000
INPUTL FIXED BIN(15) INIT(72) STATIC,
/* SYSIN LRECL */ 02520000
MAXPAGWD FIXED BIN(31) INIT(125) STATIC,
/* OUTPUT WIDTH */ 02530000
MAXPAGLN FIXED BIN(15) INIT(60) STATIC,
/* # LINES / PAGE */ 02540000
OUTLEN FIXED BIN(15) INIT(80) STATIC,
/* LENGTH OF AN @35*/ 02550000
/* OUTPUT LINE */ 02560000
PAGEWIDTH FIXED BIN(31) INIT(133) STATIC; /* SYSOUT LRECL */ 02570000
/* AREA LENGTH */ 02580000
02590000
/*******************************************************************/ 02600000
/* ERROR CODE CONSTANTS */ 02610000
/*******************************************************************/ 02620000
02630000
DCL 02640000
RETWRN FIXED BIN(15) INIT(4) STATIC, /* WARN RET COD @35*/ 02650000
RETERR FIXED BIN(15) INIT(8) STATIC, /* ERROR RET CODE */ 02660000
SEVERE FIXED BIN(15) INIT(12) STATIC; /* SEVERE ERROR */ 02670000
/* RETURN CODE */ 02680000
02690000
/*******************************************************************/ 02700000
/* NUMBER CONSTANTS */ 02710000
/*******************************************************************/ 02720000
02730000
DCL 02740000
ZERO FIXED BIN(15) INIT(0) STATIC, 02750000
ONE FIXED BIN(15) INIT(1) STATIC, 02760000
TWO FIXED BIN(15) INIT(2) STATIC, 02770000
FOUR FIXED BIN(15) INIT(4) STATIC, 02780000
FIVE FIXED BIN(15) INIT(5) STATIC, 02790000
EIGHT FIXED BIN(15) INIT(8) STATIC, 02800000
TEN FIXED BIN(15) INIT(10) STATIC; 02810000
02820000
/*******************************************************************/ 02830000
/* FLAG CONSTANTS */ 02840000
/*******************************************************************/ 02850000
02860000
DCL 02870000
YES BIT(1) INIT('1'B) STATIC, /* BIT FLAG ON */ 02880000
NO BIT(1) INIT('0'B) STATIC; /* BIT FLAG OFF */ 02890000
02900000
1102 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
/*******************************************************************/ 02910000
/* INPUT / OUTPUT BUFFER VARIABLES DECLARATION */ 02920000
/*******************************************************************/ 02930000
02940000
DCL 02950000
COMMENT BIT(1) INIT('0'B),
/* COMMENT ENCOUNTERED? */ 02960000
CURPTR FIXED BIN(15) INIT(0), /* CURR LOCN IN OUTPUT @35*/ 02970000
DB2LOC2 VAR CHAR(16) INIT(' '), /* REMOTE DB2 LOC NAME @03*/ 02980000
ENDSTR BIT(1) INIT('0'B),
/* END OF STATEMENT FLAG */ 02990000
EODIN BIT(1) INIT('0'B),
/* END OF INPUT DATA FLAG */ 03000000
ERR FIXED BIN(15) INIT(0), /* THE CURRENT RETURN CODE*/ 03010000
EXIT BIT(1) INIT('0'B),
/* PROGRAM EXIT INDICATOR */ 03020000
I FIXED BIN(15) INIT(0), /* LOOP COUNTER VARIABLE */ 03030000
INCOL FIXED BIN(15) INIT(0), /* CURRENT INPUT COLUMN */ 03040000
INPUT(INPUTL) CHAR(1), /* CURRENT INPUT DATA */ 03050000
J FIXED BIN(15) INIT(0), /* LOOP COUNTER VARIABLE */ 03060000
K FIXED BIN(15) INIT(0), /* LOOP COUNTER VARIABLE */ 03070000
KK FIXED BIN(15) INIT(0), /* LOOP COUNTER VARIABLE */ 03080000
OSTMTLN FIXED BIN(15) INIT(0), /* # OF OUTPUT LINES NEED-*/ 03090000
/* ED FOR INPUT STATEMENT */ 03100000
PAGEBUF VAR CHAR(15) INIT(' '), /* OUTPUT PAGE INFORMATION*/ 03110000
PARMS VAR CHAR(16), /* PROGRAM INPUT PARM @03*/ 03120000
PRTBUF VAR CHAR(80) INIT(' '), /* PRINT BUFFER @35*/ 03130000
WRNING BIT(1) INIT('0'B), /* PRINT SQLCA ON WARNING */ 03140000
RETCODE FIXED BIN(31) INIT(0); /* RETURN CODE FOR DSN8EP1*/ 03150000
03160000
/*******************************************************************/ 03170000
/* BUILT IN FUNCTIONS DECLARATIONS */ 03180000
/*******************************************************************/ 03190000
03200000
DCL 03210000
ADDR BUILTIN, /* FUNCTION TO RETURN THE ADDRESS */ 03220000
CHAR BUILTIN, /* RETURNS CHAR REPRESENTATION */ 03230000
LENGTH BUILTIN, /* RETURNS LENGTH OF A STRING */ 03240000
MIN BUILTIN, /* FUNCTION TO RETURN MINIMUM */ 03250000
NULL BUILTIN, /* NULL VALUE */ 03260000
SUBSTR BUILTIN, /* FUNCTION TO RETURN SUBSTRING */ 03270000
PLIRETC BUILTIN, /* FUNCTION TO SET RETURN CODE */ 03280000
PLIRETV BUILTIN, /* PL/I RETURN CODE VALUE */ 03290000
UNSPEC BUILTIN; /* IGNORES VARIABLE TYPING */ 03300000
03310000
/*******************************************************************/ 03320000
/* DECLARE BUFFER AREAS FOR THE SQLCA AND THE SQLDA */ 03330000
/*******************************************************************/ 03340000
03350000
EXEC SQL INCLUDE SQLCA; /* DEFINE THE SQLCA */ 03360000
03370000
/*******************************************************************/ 03380000
/* MESSAGE FORMATTING ROUTINE AND VARIABLES DECLARAIONS */ 03390000
/*******************************************************************/ 03400000
DCL 03410000
DSNTIAR ENTRY EXTERNAL OPTIONS(ASM INTER RETCODE); 03420000
DCL 03430000
MSGBLEN FIXED BIN(15) INIT(10); /* MAX # SQL MESSAGES */ 03440000
DCL 03450000
01 MESSAGE, /* RETURNED MESSAGES AREA */ 03460000
02 MESSAGEL FIXED BIN(15) /* MESSAGE BUFFER LENGTH */ 03470000
INIT(0), 03480000
02 MESSAGET(MSGBLEN) CHAR(MAXPAGWD) /* SQLCA MSGS SPACE */ 03490000
INIT(' '); 03500000
/*******************************************************************/ 03510000
/* BUFFER DECLARATION FOR THE INPUT STATEMENT */ 03520000
/* *** NOTE *** : THE CHARACTER SIZE MUST BE EXPLICIT FOR THE */ 03530000
/* PRECOMPILER */ 03540000
/*******************************************************************/ 03550000
03560000
DCL 03570000
INPLLEN FIXED BIN(15) INIT(100), /* LENGTH OF PRINT STMT */ 03580000
STMTBUF VAR CHAR(4096) INIT(' '), /* STATEMENT STRING */ 03590000
STMTLEN FIXED BIN(15) INIT(0), /* STMT STRING LENGTH */ 03600000
STMTMAX FIXED BIN INIT(4096);/* STATEMENT BUFFER */ 03610000
/* MAXIMUM LENGTH */ 03620000
03630000
/*******************************************************************/ 03640000
/* FILE DECLARATIONS */ 03650000
/*******************************************************************/ 03660000
03670000
DCL 03680000
SYSIN FILE STREAM INPUT, /* INPUT FILE */ 03690000
SYSPRINT FILE STREAM OUTPUT /* OUTPUT FILE */ 03700000
ENV(FB,RECSIZE(PAGEWIDTH),BLKSIZE(PAGEWIDTH)); 03710000
%PAGE; 03720000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1103
/*******************************************************************/ 03730000
/* MAIN PROGRAM */ 03740000
/*******************************************************************/ 03750000
/* GENERAL INITIALIZATION */ 03760000
/*******************************************************************/ 03770000
03780000
RETCODE = ZERO; /* INITIALIZE THE RETURN CODE */ 03790000
WRNING = NO; /* INITIALIZE PRINTING SQLCA ON */ 03800000
/* WARNING FLAG */ 03810000
MESSAGEL = MSGBLEN * MAXPAGWD; /* SET MESSAGE BUFFER LENGTH */ 03820000
DB2LOC2 = PARMS; /* INPUT PARAMETER IS THE REMOTE */ 03830000
/* DB2 LOCATION NAME */ 03840000
03850000
/*******************************************************************/ 03860000
/* INPUT PROCESSING INITIALIZATION */ 03870000
/*******************************************************************/ 03880000
03890000
EXIT = NO; /* DON'T EXIT-CONTINUE PROCESSING */ 03900000
EODIN = NO; /* NOT AT THE END OF INPUT DATA */ 03910000
INPUT = NULLCHAR; /* NULL THE INPUT DATA ARRAY */ 03920000
INCOL = INPUTL+ONE; /* SET COLUMN TO 73 TO INDICATE A */ 03930000
/* NEW LINE IS TO BE READ IN */ 03940000
/* READRTN */ 03950000
03960000
%PAGE; 03970000
/*******************************************************************/ 03980000
/* READ THE FIRST COMMAND STATEMENT TO BE PROCESSED */ 03990000
/*******************************************************************/ 04000000
04010000
CALL READRTN; 04020000
/*******************************************************************/ 04030000
/* MAIN LOOP. CONTINUE PROCESSING DB2 COMMANDS UNTIL THE END OF */ 04040000
/* DATA IS REACHED OR A SEVERE ERROR HAS BEEN ENCOUNTERED */ 04050000
/*******************************************************************/ 04060000
04070000
PRC: 04080000
DO WHILE (EXIT = NO & RETCODE < SEVERE); 04090000
ERR = ZERO; /* CLEAR THE CURRENT RETURN CODE */ 04100000
/* INCLUDE OUTPUT HEADINGS */ 04110000
CALL READRTN; /* READ NEXT STATEMENT */ 04120000
END; /* END PRC */ 04130000
GOTO STOPRUN; /* EXIT */ 04140000
04150000
%PAGE; 04160000
04170000
HEX2CHAR: 04180000
/***************************************************/ 04190000
/* PROCEDURE TO PRINT THE IFI RETURN CODE IN HEX */ 04200000
/***************************************************/ 04210000
PROCEDURE(INPUT) RETURNS(CHAR(8)); /* RESULTS RETURNED IN */ 04220000
/* CHARACTER FORMAT */ 04230000
DECLARE INPUT BIT(31), /* RETURN CODE IN BINARY */ 04240000
I1 BIT(4) DEF INPUT, 04250000
I2 BIT(4) DEF INPUT POSITION(4), 04260000
I3 BIT(4) DEF INPUT POSITION(8), 04270000
I4 BIT(4) DEF INPUT POSITION(12), 04280000
I5 BIT(4) DEF INPUT POSITION(16), 04290000
I6 BIT(4) DEF INPUT POSITION(20), 04300000
I7 BIT(4) DEF INPUT POSITION(24), 04310000
I8 BIT(4) DEF INPUT POSITION(28), 04320000
HEXES CHAR(16) INIT('0123456789ABCDEF'), 04330000
OUTPUT CHAR(8), 04340000
OUTPUT1(8) CHAR(1) DEFINED(OUTPUT); 04350000
OUTPUT1(1)=SUBSTR(HEXES,I1+1,1); /*1ST BYTE OF RET CODE IN HEX */ 04360000
OUTPUT1(2)=SUBSTR(HEXES,I2+1,1); /*2ND BYTE OF RET CODE IN HEX */ 04370000
OUTPUT1(3)=SUBSTR(HEXES,I3+1,1); /*3RD BYTE OF RET CODE IN HEX */ 04380000
OUTPUT1(4)=SUBSTR(HEXES,I4+1,1); /*4TH BYTE OF RET CODE IN HEX */ 04390000
OUTPUT1(5)=SUBSTR(HEXES,I5+1,1); /*5TH BYTE OF RET CODE IN HEX */ 04400000
OUTPUT1(6)=SUBSTR(HEXES,I6+1,1); /*6TH BYTE OF RET CODE IN HEX */ 04410000
OUTPUT1(7)=SUBSTR(HEXES,I7+1,1); /*7TH BYTE OF RET CODE IN HEX */ 04420000
OUTPUT1(8)=SUBSTR(HEXES,I8+1,1); /*8TH BYTE OF RET CODE IN HEX */ 04430000
RETURN (OUTPUT); /* RETURN THE OUTPUT RESULT*/ 04440000
END HEX2CHAR; 04450000
04460000
%PAGE; 04470000
/*******************************************************************/ 04480000
/* PROCEDURE TO PRINT THE SQLCA ERROR INDICATION AND CLEAR OUT THE */ 04490000
/* SQLCA. OUTPUT MOST OF THE DATA ON AN EXCEPTION BASIS */ 04500000
/*******************************************************************/ 04510000
04520000
PRINTCA: PROCEDURE; 04530000
04540000
1104 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
/*******************************************************************/ 04550000
/* PROCESS SQL OUTPUT MESSAGE */ 04560000
/*******************************************************************/ 04570000
04580000
CALL DSNTIAR ( SQLCA, MESSAGE, MAXPAGWD); /* FORMAT ANY MESSAGES */ 04590000
IF PLIRETV ^= ZERO THEN /* IF THE RETURN CODE ISN'T ZERO */ 04600000
DO; /* ISSUE AN ERROR MESSAGE */ 04610000
PUT EDIT (' *** RETURN CODE ', PLIRETV, /*@35*/ 04620000
' FROM MESSAGE ROUTINE DSNTIAR.') 04630000
(COL(1), A(17), F(8), A(30)); /* ISSUE THE MESSAGE */ 04640000
RETCODE = SEVERE; /* SET THE RETURN CODE */ 04650000
END; /* END ISSUE AN ERROR MESSAGE */ 04660000
04670000
DO I = ONE TO MSGBLEN /* PRINT OUT THE DSNTIAR BUFFER */ 04680000
WHILE (MESSAGET(I) ^= BLANK); /* PRINT NON BLANK LINES */ 04690000
PUT EDIT ( MESSAGET(I) ) (COL(2), A(MAXPAGWD)); 04700000
END; 04710000
04720000
RETCODE = SEVERE; /* SET THE RETURN CODE */ 04730000
04740000
END PRINTCA; 04750000
04760000
04770000
%PAGE; 04780000
04790000
/*******************************************************************/ 04800000
/* THIS PROCEDURE READS THE DATA FROM THE USER AND OBTAINS A DB2 */ 04810000
/* COMMAND TO PASS TO DSN8EP2 FOR EXECUTION VIA THE IFI CALL */ 04820000
/*******************************************************************/ 04830000
04840000
READRTN: PROCEDURE; 04850000
04860000
DCL 04870000
CONTLINE FIXED BIN(15) /* CONTINUATION LINE - INPUT STMT */ 04880000
INIT(0), /* IS MORE THAN 72 CHARACTERS */ 04890000
DQUOTFLAG BIT(1) /* DOUBLE QUOTE (") ENCOUNTERED? */ 04900000
INIT('0'B), 04910000
FIRSTCHAR BIT(1) /* FIRST NON BLANK CHAR? */ 04920000
INIT('0'B), 04930000
LASTCHAR CHAR(1) /* LAST CHARACTER IN THE BUFFER */ 04940000
INIT(' '), 04950000
MOVECHAR BIT(1) /* MOVE CHAR INTO STMT BUFFER? */ 04960000
INIT('0'B), 04970000
NBLK FIXED BIN(15) /* NUMBER OF BLANKS FOUND */ 04980000
INIT( 0 ), 04990000
NEWOFSET FIXED BIN(15) /* FIRST POSITION OF THE COMMAND */ 05000000
INIT( 0 ), /* IN THE STATEMENT BUFFER */ 05010000
NEWSTMT BIT(1) /* NEW STMT TO BE PROCESSED? */ 05020001
INIT('0'B), 05030000
QUOTEFLAG BIT(1) /* QUOTE (') ENCOUNTERED? */ 05040000
INIT('0'B); 05050000
05060000
/*******************************************************************/ 05070000
/* ENDFILE CONDITIONS */ 05080000
/*******************************************************************/ 05090000
05100000
ON ENDFILE(SYSIN) /* PROCESS EOF ON INPUT FILE */ 05110000
BEGIN; /* END OF FILE */ 05120000
IF LENGTH(STMTBUF) = 0 THEN 05130000
DO; /* LENGTH(STMTBUF) = 0 */ 05140000
EXIT = YES; /* NO STMT TO PROCESS, */ 05150000
GOTO ENDRD; /* SO END THE PROGRAM */ 05160000
END; /* END LENGTH(STMTBUF) = 0 */ 05170000
ELSE /* PROCESS THE CURRENT STATEMENT */ 05180000
DO; /* LENGTH(STMTBUF) ^= 0 */ 05190000
EODIN = YES; /* SIGNAL END_OF_DATA */ 05200000
ENDSTR = YES; /* SIGNAL END_OF_STRING */ 05210000
GOTO CHKCOMM; /* PROCESS CURRENT COMMAND */ 05220000
END; /* END LENGTH(STMTBUF) ^= 0 */ 05230000
END; /* END END OF FILE */ 05240000
05250000
/*******************************************************************/ 05260000
/* BEGIN READRTN PROCESSING */ 05270000
/*******************************************************************/ 05280000
05290000
NEWSTMT= YES; /* NEW STMT IS BEING PROCESSED */ 05300000
05310000
%PAGE; 05320000
05330000
/*******************************************************************/ 05340000
/* READ IN THE INPUT STATEMENT */ 05350000
/*******************************************************************/ 05360000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1105
05370000
RD: 05380000
05390000
DO WHILE (NEWSTMT = YES); 05400000
05410000
/*****************************************************************/ 05420000
/* NO MORE INPUT DATA (EOF) SO RETURN TO CALLER */ 05430000
/*****************************************************************/ 05440000
05450000
IF EODIN = YES THEN 05460000
DO; /* END OF DATA */ 05470000
EXIT = YES; /* EXIT PROGRAM */ 05480000
LEAVE RD; /* LEAVE THE LOOP */ 05490000
END; /* END END OF DATA */ 05500000
05510000
/*****************************************************************/ 05520000
/* PROCESS THE STATEMENT */ 05530000
/*****************************************************************/ 05540000
05550000
ELSE /* MORE INPUT TO PROCESS */ 05560000
DO; 05570000
NEWSTMT = NO; /* TURN NEW STATEMENT FLAG OFF */ 05580000
CONTLINE = ZERO; /* CLEAR MULTILINE STMT COUNTER */ 05590000
ENDSTR = NO; /* NOT AT THE END OF THE STRING */ 05600000
QUOTEFLAG = NO; /* INITIALIZE QUOTE FLAG */ 05610000
DQUOTFLAG = NO; /* INITIALIZE DOUBLE QUOTE FLAG */ 05620000
STMTLEN = ZERO; /* INITIALIZE THE STMT LENGTH */ 05630000
STMTBUF = NULLCHAR; /* INIT STMT BUFFER TO NULLS */ 05640000
LASTCHAR = NULLCHAR; /* INIT. LAST CHARACTER TO NULL */ 05650000
COMMENT = NO; /* INITIALIZE THE COMMENT FLAG */ 05660000
FIRSTCHAR = NO; /* INIT. FIRST CHAR TO NO */ 05670000
NBLK = ZERO; /* INIT. BLANK COUNT TO 0 */ 05680000
05690000
/*************************************************************/ 05700000
/* READ AND PROCESS A NEW STATEMENT */ 05710000
/*************************************************************/ 05720000
05730000
DO WHILE (ENDSTR = NO); /* PUT INPUT STMT IN STMT BUFFER */ 05740000
05750000
/***********************************************************/ 05760000
/* IF THE COLUMN BEING PROCESSED IS GREATER THAN THE */ 05770000
/* LENGTH OF THE INPUT LINE THEN READ THE NEXT LINE */ 05780000
/***********************************************************/ 05790000
05800000
IF INCOL > INPUTL THEN 05810000
DO; /* GET SYSIN DATA */ 05820000
GET EDIT (INPUT) (COL(1), (INPUTL) A(1)); /* */ 05830000
INCOL = ONE; /* POINT TO FIRST CHARACTER */ 05840000
IF FIRSTCHAR = YES THEN /* FIRST CHAR SET? */ 05850000
CONTLINE = CONTLINE + 1; /* INCREMENT INPUT LINE CTR */ 05860000
END; 05870000
05880000
/***********************************************************/ 05890000
/* THE CHARACTER IN COLUMN ONE IS AN ASTERISK OR THE */ 05900000
/* CHARACTERS IN COLUMNS 1 AND 2 ARE '--'. CONSIDER THIS */ 05910000
/* LINE TO BE A COMMENT. PRINT THE LINE AND RETRIEVE THE */ 05920000
/* NEXT INPUT LINE. */ 05930000
/***********************************************************/ 05940000
05950000
IF INCOL = 1 & (INPUT(1) = ASTERISK 05960000
| (INPUT(1) = HYPHEN & INPUT(2) = HYPHEN)) 05970000
& STMTLEN = 0 THEN 05980000
DO; /* STATEMENT IS A COMMENT */ 05990000
DO J = 1 TO INPUTL; /* PUT ENTIRE LINE INTO STMTBUF */ 06000000
STMTBUF = STMTBUF || INPUT(J); 06010000
END; 06020000
STMTLEN = LENGTH(STMTBUF); 06030000
ENDSTR = YES; /* INDICATE END OF A STRING */ 06040000
NEWSTMT = YES; /* NEW STMT SHOULD BE READ */ 06050000
INCOL = INPUTL + ONE; /* SET INDEX TO 73 TO FORCE */ 06060000
/* THE NEXT STMT TO BE READ */ 06070000
COMMENT= ^COMMENT; /* SET COMMENT INDICATOR ON */ 06080000
END; /* END STATEMENT IS A COMMENT */ 06090000
06100000
/***********************************************************/ 06110000
/* PROCESS THE INPUT STATEMENT */ 06120000
/***********************************************************/ 06130000
06140000
ELSE 06150000
DO; 06160000
06170000
/*******************************************************/ 06180000
1106 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
/* MOVE THE CHARACTER FROM THE INPUT DATA INTO THE */ 06190000
/* STATEMENT BUFFER UNTIL AN END OF LINE CHARACTER */ 06200000
/* OR SEMICOLON IS ENCOUNTERED */ 06210000
/*******************************************************/ 06220000
06230000
DO J = INCOL TO INPUTL WHILE (^ENDSTR); 06240000
06250000
/*****************************************************/ 06260000
/* PREPROCESS ANY DOUBLE QUOTATION MARKS ("). IF THE */ 06270000
/* DOUBLE QUOTATION MARK IS CONTAINED BETWEEN */ 06280000
/* QUOTATION MARKS ('), THE QUOTATION MARK IS */ 06290000
/* CONSIDERED TO BE THE STRING DELIMITER. THE */ 06300000
/* DQUOTFLAG WILL NOT BE SET. IN THIS CASE THE */ 06310000
/* DOUBLE QUOTATION MARK IS CONSIDERED TO BE PART OF */ 06320000
/* THE STRING */ 06330000
/*****************************************************/ 06340000
06350000
IF INPUT(J) = DQUOTE THEN 06360000
DO; /* INPUT(J)=DQUOTE */ 06370000
IF ^QUOTEFLAG THEN /* NOT DELIMITED BY QUOTES */ 06380000
/* THEN DOUBLE */ 06390000
/* QUOTES ARE */ 06400000
DQUOTFLAG = ^DQUOTFLAG; /* THE DELIMITER */ 06410000
END; /* END INPUT(J) = DQUOTE */ 06420000
06430000
/*****************************************************/ 06440000
/* PREPROCESS ANY QUOTATION MARKS ('). IF THE */ 06450000
/* QUOTATION MARK IS CONTAINED BETWEEN DOUBLE */ 06460000
/* QUOTATION MARKS ("), THE DOUBLE QUOTATION MARK IS */ 06470000
/* CONSIDERED TO BE THE STRING DELIMITER. THE */ 06480000
/* QUOTEFLAG WILL NOT BE SET. IN THIS CASE THE */ 06490000
/* QUOTATION MARK IS CONSIDERED TO BE PART OF THE */ 06500000
/* STRING. */ 06510000
/*****************************************************/ 06520000
06530000
IF INPUT(J) = QUOTE THEN 06540000
DO; /* INPUT(J) = QUOTE */ 06550000
IF ^DQUOTFLAG THEN /* NOT DELIMITED BY */ 06560000
/* DOUBLE QUOTES THEN */ 06570000
/* SINGLE QUOTES ARE THE */ 06580000
QUOTEFLAG = ^QUOTEFLAG; /* DELIMITER */ 06590000
END; /* END INPUT(J) = QUOTE */ 06600000
06610000
/*****************************************************/ 06620000
/* PROCESS A HYPHEN IF FOUND. THE HYPHEN IS */ 06630000
/* CONSIDERED PART OF A STRING IF A DELIMITER FLAG */ 06640000
/* IS SET. IF THE FOLLOWING CHARACTER IS A HYPHEN, */ 06650000
/* MOVE THE REMAINING CHARACTERS TO THE STATEMENT */ 06660000
/* BUFFER. */ 06670000
/*****************************************************/ 06680000
06690000
IF (INPUT(J) = HYPHEN) & /*INPUT CHAR IS '-' */ 06700000
(J < INPUTL) & /* STILL MORE & */ 06710000
^QUOTEFLAG & /* NOT CURRENTLY IN */ 06720000
^DQUOTFLAG THEN /* DELIMITED STRING THEN */ 06730000
DO; /* LOOK FOR '--' */ 06740000
IF INPUT(J+1) = HYPHEN THEN /* FOUND '--' */ 06750000
DO; /* DO NOT MOVE CHARACTERS */ 06760000
MOVECHAR = NO; /* INTO THE STATEMENT BUFFER*/ 06770000
END; 06780000
IF (INPUT(J+1) = HYPHEN) & 06790000
(MOVECHAR = NO) THEN /* COMMENT FOUND */ 06800000
DO; /* STATEMENT IS A COMMENT*/ 06810000
DO J = 1 TO INPUTL; 06820000
STMTBUF = STMTBUF || INPUT(J); 06830000
END; /* PUT ENTIRE LINE INTO STMTBUF */ 06840000
STMTLEN = LENGTH(STMTBUF); 06850000
ENDSTR = YES; /* INDICATE END OF A STRING */ 06860000
NEWSTMT = YES; /* NEW STMT SHOULD BE READ */ 06870000
INCOL = INPUTL + ONE; /* SET INDEX TO 73 */ 06880000
/* TO FORCE THE NEXT STATEMENT */ 06890000
/* TO BE READ */ 06900000
COMMENT= ^COMMENT; /* SET THE COMMENT */ 06910000
/* INDICATOR ON */ 06920000
END; /* END STATEMENT IS A COMMENT */ 06930000
END; /* END LOOK FOR '--' */ 06940000
/*****************************************************/ 06950000
/* PROCESS THE END-OF-STRING IF A SEMICOLON IS */ 06960000
/* FOUND. THE SEMICOLON CANNOT BE CONTAINED WITHIN */ 06970000
/* A DELIMITED STRING. THE ACCEPTABLE DELIMITERS */ 06980000
/* ARE QUOTE OR DOUBLE QUOTE MARKS. */ 06990000
/*****************************************************/ 07000000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1107
07010000
IF (INPUT(J) = SEMICOLON) & ^DQUOTFLAG & 07020000
^QUOTEFLAG THEN /* SEMICOLON & NOT */ 07030000
ENDSTR = ^ENDSTR; /* DELIMITED THEN SET END */ 07040000
/* OF STRING */ 07050000
/*****************************************************/ 07060000
/* NOT THE END OF THE STRING, PROCESS THE STATEMENT */ 07070000
/*****************************************************/ 07080000
07090000
ELSE 07100000
DO; 07110000
07120000
/***************************************************/ 07130000
/* MOVE ALL NON BLANK CHARACTERS INTO THE DB2 */ 07140000
/* COMMAND STATEMENT BUFFER */ 07150000
/***************************************************/ 07160000
07170000
IF INPUT(J)^= BLANK THEN 07180000
DO; 07190000
MOVECHAR = YES; 07200000
FIRSTCHAR = YES; 07210000
NBLK = ZERO; 07220000
END; 07230000
07240000
/***************************************************/ 07250000
/* A BLANK SHOULD BE MOVED IN THE FOLLOWING CASES: */ 07260000
/* */ 07270000
/* 1. IF THE BLANK IS IN A DELIMITED STRING */ 07280000
/* */ 07290000
/* 2. IF AN INPUT STATEMENT SPANS MORE THAN */ 07300000
/* ONE LINE AND THE PREVIOUS LINE HAD A */ 07310000
/* CHARACTER IN COLUMN 72 AND THE CURRENT */ 07320000
/* LINE HAS BLANKS BEFORE THE FIRST WORD */ 07330000
/***************************************************/ 07340000
07350000
ELSE /* BLANK CHARACTER FOUND */ 07360000
DO; 07370000
IF QUOTEFLAG | DQUOTFLAG | 07380000
(CONTLINE >= 1 & J = 1 & NBLK = 0) THEN 07390000
DO; /* BLANK IS DELIMITED, MOVE */ 07400000
MOVECHAR = YES; /* IT INTO STMT BUFFER*/ 07410000
NBLK = NBLK + ONE; /* & INC BLANK COUNT */ 07420000
END; 07430000
ELSE /* BLANK NOT DELIMITED */ 07440000
DO; 07450000
NBLK = NBLK + ONE; /* INCREASE BLANK CTR */ 07460000
IF (NBLK = ONE) & (FIRSTCHAR = YES) THEN 07470000
MOVECHAR = YES; 07480000
ELSE 07490000
DO; 07500000
MOVECHAR = NO; 07510000
END; 07520000
END; /* END BLANK NOT DELIMITED */ 07530000
END; /* END BLANK CHARACTER FOUND */ 07540000
07550000
/*************************************************/ 07560000
/* IF MOVECHAR IS SET THEN MOVE THE INPUT */ 07570000
/* CHARACTER INTO STATEMENT BUFFER AREA */ 07580000
/*************************************************/ 07590000
07600000
IF MOVECHAR = YES THEN 07610000
DO; 07620000
07630000
/*********************************************/ 07640000
/* WHEN THE STATEMENT LENGTH IS TOO LONG,THE */ 07650000
/* STATEMENT CANNOT BE PROCESSED. A RETURN */ 07660000
/* CODE IS SET TO INDICATE NO FURTHER */ 07670000
/* PROCESSING SHOULD BE DONE. AN ERROR */ 07680000
/* MESSAGE WILL BE PUT OUT. */ 07690000
/*********************************************/ 07700000
07710000
STMTLEN = LENGTH(STMTBUF); 07720000
IF STMTLEN = STMTMAX THEN /* STMT TOO LONG */ 07730000
DO; 07740000
RETCODE = SEVERE; /* SET RETURN CODE */ 07750000
PUT EDIT(' *** ERROR: STATEMENT GREATER ', 07760000
'THAN ',STMTMAX,' CHARACTERS. ', 07770000
'STMT: ') /* @35*/ 07780000
(COL(1),A(31),A(5),F(4),A(13), 07790000
A(7)); /* @35*/ 07800000
PUT EDIT((SUBSTR(STMTBUF,KK, 07810000
MIN(100,STMTLEN-KK+1)) 07820000
1108 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
DO KK = 1 TO STMTLEN BY 100)) 07830000
(COL(2),A(100)); /* @35*/ 07840000
LEAVE RD; 07850000
END; /* END STMT TOO LONG */ 07860000
STMTBUF = STMTBUF || INPUT(J); 07870000
END; /* MOVE CHARACTER INTO BUFFER */ 07880000
LASTCHAR = INPUT(J); /* SAVE THIS CHARACTER */ 07890000
END; /* END CHARACTER NOT A SEMICOLON */ 07900000
END; /* END DO J = INCOL TO INPUTL */ 07910000
END; /* END PROCESS THE INPUT STMT */ 07920000
INCOL = J; /* UPDATE THE INPUT COLUMN */ 07930000
END; /* END DO WHILE (ENDSTR = NO) */ 07940000
07950000
/*************************************************************/ 07960000
/* CHECK WHETHER THE COMMAND ENTERED IS A COMMENT. IF NOT, */ 07970000
/* PRINT THE DB2 COMMAND INPUT STATEMENT. */ 07980000
/*************************************************************/ 07990000
CHKCOMM: 08000000
IF ^COMMENT THEN 08010000
DO; 08020000
STMTLEN = LENGTH(STMTBUF); 08030000
NEWOFSET = ONE; 08040000
END; 08050000
/***************************************************/ 08060000
/* PRINT OUT THE DB2 COMMAND INPUT STATEMENT */ 08070000
/***************************************************/ 08080000
PUT SKIP; 08090000
IF ^COMMENT THEN 08100000
DO; 08110000
PUT SKIP; /*@35*/ 08120000
PUT EDIT (' *** INPUT STATEMENT: ') (COL(1), A); /*@35*/ 08130000
J = STMTLEN; /*@35*/ 08140000
PUT EDIT ((SUBSTR(STMTBUF,KK,MIN(INPLLEN,J-KK+1)) 08150000
DO KK = 1 TO STMTLEN BY INPLLEN)) 08160000
(A(INPLLEN),COL(1)); 08170000
END; 08180000
ELSE /*@35*/ 08190000
DO; /*@35*/ 08200000
J = STMTLEN; /*@35*/ 08210000
PUT EDIT ((SUBSTR(STMTBUF,KK,MIN(INPLLEN,J-KK+1)) /*@35*/ 08220000
DO KK = 1 TO STMTLEN BY INPLLEN)) /*@35*/ 08230000
(COL(2),A(INPLLEN),COL(1)); /*@35*/ 08240000
END; /*@35*/ 08250000
IF ^COMMENT THEN 08260000
STMTBUF = SUBSTR(STMTBUF,ONE,STMTLEN); 08270000
/*************************************************/ 08280000
/* UPDATE THE OUTPUT LINE COUNTER */ 08290000
/*************************************************/ 08300000
08310000
OSTMTLN = STMTLEN/INPLLEN; /* # LINES NEEDED FOR */ 08320000
/* INPUT STMT */ 08330000
IF OSTMTLN * INPLLEN ^= STMTLEN THEN 08340000
OSTMTLN = OSTMTLN + ONE; 08350000
08360000
/*****************************************************/ 08370000
/* CHECK THAT THE DB2 COMMAND BEGINS WITH A HYPHEN. */ 08380000
/* IF NOT, CALL BADCMD AND ISSUE AN ISSUE AN ERROR */ 08390000
/* MESSAGE. */ 08400000
/*****************************************************/ 08410000
08420000
IF ^COMMENT THEN 08430000
DO; /* STATEMENT NOT A COMMENT */ 08440000
/*******************************************************************/ 08450000
/* HANDLE BAD IFI CALL SYNTAX */ 08460000
/*******************************************************************/ 08470000
IF SUBSTR(STMTBUF,ONE,ONE) ^= '-' THEN /* NO HYPHEN */ 08480000
DO; 08490000
PUT SKIP; 08500000
PUT SKIP EDIT(' *** SYNTAX FOR DB2 COMMAND ',/*@35*/ 08510000
'IS NOT VALID.') /*@35*/ 08520000
(COL(1),A(28),A(13)); /*@35*/ 08530000
PUT SKIP EDIT(' *** A VALID COMMAND MUST ', /*@35*/ 08540000
'BEGIN WITH A HYPHEN.') 08550000
(COL(1),A(26),A(20)); /*@35*/ 08560000
RETCODE = RETERR; /* SET RET CODE TO 8 */ 08570000
END; /* END NO HYPHEN */ 08580000
/*******************************************************************/ 08590000
/* COMMAND SYNTAX IS CORRECT */ 08600000
/*******************************************************************/ 08610000
ELSE 08620000
DO; /* A VALID */ 08630000
INPUTCMD = SUBSTR(STMTBUF,ONE,STMTLEN); /* COMMAND*/ 08640000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1109
/*SO MAKE CALL*/ 08650000
/****************************************************/ 08660000
/* CONNECT TO THE DB2 REMOTE LOCATION */ 08670000
/****************************************************/ 08680000
EXEC SQL CONNECT TO :DB2LOC2; /* CONNECT TO */ 08690000
/* REMOTE LOCATION */ 08700000
IF SQLCODE < 0 THEN /* SQL ERROR? @42*/ 08710000
DO; /* YES, ERROR FOUND*/ 08720000
PUT EDIT (' *** CONNECTION TO ',DB2LOC2, /*@35*/ 08730000
' NOT SUCCESSFUL:') 08740000
(COL(1), A(19), A(16), A(16)); /*@35*/ 08750000
CALL PRINTCA; /* PRINT ERROR MSG */ 08760000
GOTO STOPRUN; /* END PROGRAM */ 08770000
END; /* END ERROR FOUND */ 08780000
/****************************************************/ 08790000
/* CALL THE STORED PROCEDURE PROGRAM DSN8EP2 */ 08800000
/****************************************************/ 08810000
RETURN_IND = -1; /*@35*/ 08820000
EXEC SQL CALL DSN8.DSN8EP2(:INPUTCMD, 08830000
:IFCA_RET_HEX, 08840000
:IFCA_RES_HEX, 08850000
:BUFF_OVERFLOW, /*@35*/ 08860000
:RETURN_BUFF:RETURN_IND); /*@35*/ 08870000
IF SQLCODE < 0 THEN /* SQL ERROR? @42*/ 08880000
DO; /* YES ERROR FOUND */ 08890000
PUT EDIT (' *** CALL TO DSN8EP2 NOT SUCCESSFUL:') 08900000
(COL(1),A(36)); /*@35*/ 08910000
IF SQLCODE = -911 | SQLCODE = -918 /*@42*/ 08920000
| SQLCODE = -919 | SQLCODE = -965 /*@42*/ 08930000
THEN /* CHECK FOR SPECIFIC ERRORS @42*/ 08940000
/* THAT REQUIRE A ROLL BACK @42*/ 08950000
DO; /* YES, ROLL BACK REQUIRED @42*/ 08960000
CALL PRINTCA; /* PRINT ERROR MSG @42*/ 08970000
PUT EDIT (' *** ISSUE ROLLBACK WORK ', 08980000
'BECAUSE STORED PROCEDURE ', 08990000
'CALL NOT SUCCESSFUL') 09000000
(COL(1), A(25), A(25), A(19)); 09010000
/* PRINT ROLLBACK WORK MESSAGE @42*/ 09020000
EXEC SQL ROLLBACK WORK; /* EXECUTE ROLLBACK*/ 09030000
/* WORK STMT @42*/ 09040000
END; /* END ROLL BACK REQUIRED @42*/ 09050000
CALL PRINTCA; /* PRINT ERROR MSG */ 09060000
GOTO STOPRUN; /* END PROGRAM */ 09070000
END; /* END ERROR FOUND */ 09080000
/*******************************************************************/ 09090000
/* CALL THE RESULTS PROC TO PROCESS THE RETURN CODE, THE REASON */ 09100000
/* CODE AND THE RESULTS MESSAGE OF THE COMMAND EXECUTED BY IFI. */ 09110000
/* NEXT, INITIALIZE THE VARIABLES TO PROCESS THE NEXT DB2 COMMAND. */ 09120000
/*******************************************************************/ 09130000
CALL RESULTS; /* PROCESS THE RESULTS */ 09140000
END; /* END VALID COMMAND */ 09150000
NEWOFSET = ZERO; /* RESET CHARACTER PTR */ 09160000
NEWSTMT = YES; /* RESET FOR NEW STMT */ 09170000
END; /* END STATEMENT NOT A COMMENT */ 09180000
END; /* END ELSE MORE INPUT */ 09190000
END; /* END DO WHILE NEW STMT */ 09200000
09210000
ENDRD:; /* END RD SUB-PROC */ 09220000
END READRTN; /* END READRTN PROC */ 09230000
09240000
%PAGE; 09250000
09260000
/*******************************************************************/ 09270000
/* PROCESS THE DB2 COMMAND RESULTS FROM THE IFCA RETURN BUFFER */ 09280000
/*******************************************************************/ 09290000
RESULTS: PROCEDURE; 09300000
DCL 09310000
M0LENGTH CHAR(2) INIT(' '), /* LENGTH OF CMD RESULT */ 09320000
M1LENGTH BIT(16) INIT('0'B), /* INTERNALLY STORED LNG */ 09330000
M2LENGTH FIXED BIN(15) INIT(0), /* LENGTH OF MESSAGE N */ 09340000
BEGINSTR FIXED BIN(15) INIT(1), /* CHAR 1 POINTER */ 09350000
TOTBYTES FIXED BIN(31) INIT(0); /* MSG BYTE COUNT */ 09360000
09370000
IFCA_RET_CODE = HEX2CHAR(IFCA_RET_HEX); /* RETURN CODE IN HEX */ 09380000
IFCA_RES_CODE = HEX2CHAR(IFCA_RES_HEX); /* REASON CODE IN HEX */ 09390000
TOTBYTES = 0; /* INITIALIZE COUNTER */ 09400000
BEGINSTR = 1; /* INITIALIZE POINTER */ 09410000
09420000
IF IFCA_RET_HEX ^= 0 THEN /* IF THE RETURN CODE ISN'T ZERO */ 09430000
/* ISSUE AN ERROR MESSAGE */ 09440000
DO; 09450000
PUT EDIT(' *** RETURN CODE=',SUBSTR(IFCA_RET_CODE,7,2), /*@35*/ 09460000
1110 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
' REASON CODE=',IFCA_RES_CODE,' FROM IFI REQUEST') 09470000
(COL(1),A(17),A(2),A,A(8),A); /*@35*/ 09480000
END; /* END ISSUE AN ERROR MESSAGE */ 09490000
09500000
IF LENGTH(RETURN_BUFF) ^= 0 THEN /*@35*/ 09510000
/* DON'T PRINT UNLESS SOME DATA RET. */ 09520000
DO; 09530000
PUT SKIP; /*@35*/ 09540000
PUT SKIP EDIT(' *** IFI RETURN AREA:') /*@35*/ 09550000
(COL(1),A); /*@35*/ 09560000
/*************************************************************/ 09570000
/* PROCESS THE UNFORMATTED COMMAND RESULTS FROM THE IFI CALL.*/ 09580000
/* GET THE LENGTH OF EACH RESULT LINE FROM THE FIRST TWO */ 09590000
/* BYTES. PUT IT IN USABLE FORM. PRINT THE RESULTS FROM */ 09600000
/* THE FIRST LINE. UPDATE THE POINTER AND THE COUNTERS AND */ 09610000
/* REPEAT UNTIL ALL BYTES FROM IFCA_BYTES_MOVED HAVE BEEN */ 09620000
/* PROCESSED. */ 09630000
/*************************************************************/ 09640000
CURPTR = 0; /* START OF DATA IN RET AREA@35*/ 09650000
REMBYTES = LENGTH(RETURN_BUFF); /* NUMBER OF BYTES TO PROC@35*/ 09660000
DO WHILE (REMBYTES > 0); /* RETURN AREA PRINT LOOP @35*/ 09670000
PRTBUF = SUBSTR(RETURN_BUFF,CURPTR,OUTLEN); /*@35*/ 09680000
SUBSTR(PRTBUF,1,1) = BLANK; /* BLANK FIRST COLUMN TO @35*/ 09690000
/* AVOID CARRIAGE CTRL PROB */ 09700000
PUT SKIP EDIT (PRTBUF) (COL(1),A(OUTLEN)); /*@35*/ 09710000
CURPTR = CURPTR + OUTLEN; /*@35*/ 09720000
REMBYTES = REMBYTES - OUTLEN; /*@35*/ 09730000
END; /*@35*/ 09740000
END; /* END IFCA_BYTES_MOVED ^= 0 */ 09750000
09760000
IF BUFF_OVERFLOW = 1 THEN /* COULDN'T GET ALL DATA @35*/ 09770000
DO; /*@35*/ 09780000
PUT SKIP EDIT (' *** INSUFFICIENT SPACE TO RECEIVE ', /*@35*/ 09790000
'ALL OUTPUT FROM IFI RETURN AREA.') /*@35*/ 09800000
(A(35),A(32)); /*@35*/ 09810000
IF RETCODE < RETWRN THEN /*@35*/ 09820000
RETCODE = RETWRN; /*@35*/ 09830000
END; /*@35*/ 09840000
IF IFCA_RET_HEX > RETCODE THEN /* CHECK RETURN CODES */ 09850000
RETCODE = IFCA_RET_HEX; /* USE THE HIGHEST ONE */ 09860000
09870000
IF IFCA_RET_HEX = SEVERE THEN /* IF RETURN CODE = 12 */ 09880000
GOTO STOPRUN; /* STOP PROGRAM EXECUTION*/ 09890000
09900000
END RESULTS; /* END RESULTS PROC */ 09910000
/*******************************************************************/ 09920000
/* SET THE PL/I RETURN CODE AND TERMINATE PROCESSING */ 09930000
/*******************************************************************/ 09940000
09950000
STOPRUN: 09960000
IF RETCODE >= SEVERE THEN /*@35*/ 09970000
DO; /*@35*/ 09980000
PUT SKIP; /*@35*/ 09990000
PUT SKIP EDIT (' *** SEVERE ERROR OCCURRED. ', /*@35*/ 10000000
'PROGRAM IS TERMINATING.') /*@35*/ 10010000
(A(28),A(23)); /*@35*/ 10020000
END; /*@35*/ 10030000
CALL PLIRETC(RETCODE); /* SET PLI RETURN CODE */ 10040000
END DSN8EP1; /* END PROGRAM */ 10050000
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSN8EP2
USING THE INSTRUMENTATION FACILITY INTERFACE (IFI), PROCESS A Db2 COMMAND WHICH IS
PASSED FROM THE DSN8EP1 REQUESTER PROGRAM.
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1111
* LICENSED MATERIALS - PROPERTY OF IBM * 00100000
* 5675-DB2 * 00110000
* (C) COPYRIGHT 1982, 2000 IBM CORP. ALL RIGHTS RESERVED. * 00120000
* * 00130000
* STATUS = VERSION 7 * 00140000
* * 00150000
* FUNCTION = * 00160000
* USING THE INSTRUMENTATION FACILITY INTERFACE (IFI), * 00170000
* PROCESS A DB2 COMMAND WHICH IS PASSED FROM THE DSN8EP1 * 00180000
* REQUESTER PROGRAM. * 00190000
* * 00200000
* NOTES = * 00210000
* DEPENDENCIES = NONE * 00220000
* * 00230000
* RESTRICTIONS = * 00240000
* 1. THE INSTRUMENTATION FACILITY COMMUNICATION AREA * 00250000
* (IFCA) CONTAINS INFORMATION REGARDING THE SUCCESS * 00260000
* OF THE CALL AND PROVIDES FEEDBACK. * 00270000
* THIS AREA MUST BE MAINTAINED TO INCLUDE ANY CHANGES * 00280000
* TO THE MAPPING MACRO DSNDIFCA. * 00290000
* * 00300000
* MODULE TYPE = PROCEDURE * 00310000
* PROCESSOR = * 00320000
* ADMF PRECOMPILER * 00330000
* PL/I MVS/VM (FORMERLY PL/I SAA AD/CYCLE) * 00340000
* MODULE SIZE = 1K * 00350000
* ATTRIBUTES = RE-ENTERABLE * 00360000
* * 00370000
* ENTRY POINT = DSN8EP2 * 00380000
* PURPOSE = SEE FUNCTION * 00390000
* LINKAGE = INVOKED VIA EXEC SQL CALL. * 00400000
* INPUT = PARAMETERS EXPLICITLY PASSED TO THIS FUNCTION: * 00410000
* SYMBOLIC LABEL/NAME = INPUTCMD * 00420000
* DESCRIPTION = DB2 COMMAND TO BE PROCESSED BY IFI. * 00430000
* INPUT STATEMENTS FROM THE INPUTCMD * 00440000
* PARAMETER WILL BE PASSED TO THE * 00450000
* TEXT_OR_COMMAND FIELD OF THE OUTPUT_AREA * 00460000
* IN THE DSN8EP1 PROGRAM. * 00470000
* * 00480000
* OUTPUT = PARAMETERS EXPLICITLY RETURNED: * 00490000
* SYMBOLIC LABEL/NAME = IFCA_RET_HEX * 00500000
* SYMBOLIC LABEL/NAME = IFCA_RES_HEX * 00510000
* SYMBOLIC LABEL/NAME = IFCA_BYTES_MOVED * 00520000
* DESCRIPTION = COMMUNICATION AREAS BETWEEN THE * 00530000
* APPLICATION PROGRAM AND IFI * 00540000
* SYMBOLIC LABEL/NAME = RETURN_BUFF * 00550000
* DESCRIPTION = DB2 COMMAND RESPONSE FROM IFI * 00560000
* THE RETURN CODE, REASON CODE, AND THE * 00570000
* BYTES MOVED FROM THE IFCA AND THE * 00580000
* RTRN_BUFF FIELD FROM THE IFI RETURN AREA * 00590000
* WILL BE PASSED VIA THE IFCA_RET_HEX, * 00600000
* IFCA_RES_HEX, IFCA_BYTES_MOVED, AND * 00610000
* RETURN_BUFF PARAMETERS. * 00620000
* * 00630000
* EXIT NORMAL = * 00640000
* NO ERRORS WERE FOUND IN THE SOURCE AND NO * 00650000
* ERRORS OCCURRED DURING PROCESSING. * 00660000
* * 00670000
* NORMAL MESSAGES = * 00680000
* * 00690000
* EXIT-ERROR = * 00700000
* ERRORS WERE FOUND IN THE SOURCE, OR OCCURRED DURING * 00710000
* PROCESSING. * 00720000
* * 00730000
* RETURN CODE = 4 - WARNING-LEVEL ERRORS DETECTED. * 00740000
* WARNING FOUND DURING EXECUTION. * 00750000
* REASON CODE = NONE OR FROM IFI * 00760000
* * 00770000
* RETURN CODE = 8 - ERRORS DETECTED. * 00780000
* ERROR FOUND DURING EXECUTION. * 00790000
* REASON CODE = NONE OR FROM IFI * 00800000
* * 00810000
* RETURN CODE = 12 - SEVERE ERRORS DETECTED. * 00820000
* UNABLE TO OPEN FILES. * 00830000
* INTERNAL ERROR, ERROR MESSAGE ROUTINE RETURN CODE. * 00840000
* STATEMENT IS TOO LONG. * 00850000
* BUFFER OVERFLOW. * 00860000
* REASON CODE = NONE OR FROM IFI * 00870000
* * 00880000
* ABEND CODES = NONE * 00890000
* * 00900000
* ERROR MESSAGES = * 00910000
1112 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* * 00920000
* EXTERNAL REFERENCES = * 00930000
* ROUTINES/SERVICES = NONE * 00940000
* DATA-AREAS = NONE * 00950000
* CONTROL-BLOCKS = NONE * 00960000
* * 00970000
* PSEUDOCODE = * 00980000
* DSN8EP2: PROCEDURE. * 00990000
* GET THE RETURN AREA SIZE FOR COMMAND REQUESTS. * 01000000
* ALLOCATE THE REQUESTED RETURN AREA. * 01010000
* FORMAT THE OUTPUT AREA WITH THE REQUESTED COMMAND. * 01020000
* ISSUE COMMAND REQUEST. * 01030000
* PASS RESULTS TO THE OUTPUT PARAMETERS. * 01040000
* * 01050000
* CHANGE ACTIVITY = * 01060000
* 7/05/95 CHANGED THE OUTPUT STRING LENGTH FROM VARYING * 01070000
* TO FIXED 80 BYTE STRINGS PN72035 @47 KFF0347* 01080000
* 04/17/00 INITIALIZE STORAGE TO PREVENT RETURN CODE=04, * 01090000
* REASON CODE=00E60804 FROM IFI PQ36800* 01100000
* 05/22/03 FIX CODE HOLE CLOSED BY VA AND ENTERPRISE PL/I PQ44916* 01101000
********************************************************************/ 01110000
%PAGE; 01120000
/********************************************************************/ 01130000
/* VARIABLE DECLARATIONS */ 01140000
/********************************************************************/ 01150000
01160000
DCL COMMAND CHAR(8) INIT(' '); /* USER SPECIFIED DB2 COMMAND */ 01170000
/********************************************************************/ 01180000
/* BUILT-IN VARIABLES @47*/ 01190000
/********************************************************************/ 01200000
01210000
DCL /*@47*/ 01220000
ADDR BUILTIN, /* ADDRESS OF A DATA AREA @47*/ 01230000
LENGTH BUILTIN, /* RETURNS LENGTH OF A STRING @47*/ 01240000
MOD BUILTIN, /* RETURNS MODULO VALUE @47*/ 01250000
STORAGE BUILTIN, /* FUNCTION TO GET SOME SPACE @47*/ 01260000
SUBSTR BUILTIN, /* FUNCTION TO RETURN SUBSTRING @47*/ 01270000
UNSPEC BUILTIN; /* IGNORES VARIABLE TYPING @47*/ 01280000
/***********************************************************/ 01290000
/* DECLARATION FOR INPUT AND OUTPUT PARAMETERS */ 01300000
/***********************************************************/ 01310000
01320000
DCL 01330000
FUNCTION CHAR(8) INIT(' '), /* FUNC PARM FOR IFI @47*/ 01340000
INPUTCMD CHAR(4096) VARYING, /* DB2 COMMAND @47*/ 01350000
IFCA_RET_HEX FIXED BIN(31), /* IFI RETURN CODE @47*/ 01360000
IFCA_RES_HEX FIXED BIN(31), /* IFI REASON CODE @47*/ 01370000
BUFF_OVERFLOW FIXED BIN(31), /* RETURN BUFF BYTES @47*/ 01380000
/* RETURNED FROM CALL */ 01390000
NULL_ARRAY(5) FIXED BIN(15), /* INDICATOR ARRAY @47*/ 01400000
RETURN_BUFF CHAR(8320) VARYING, /* PASSED BUFFER @47*/ 01410000
RETURN_LEN FIXED BIN(15) INIT(8320) STATIC; /* LENGTH @47*/ 01420000
/* OF PASSED BUFFER */ 01430000
/***********************************************************/ 01440000
/* WORKING VARIABLES @47*/ 01450000
/***********************************************************/ 01460000
DCL 01470000
REMBYTES FIXED BIN(15) INIT(0), /* NUM BYTES TO BE @47*/ 01480000
/* PROCESSED IN RTRN AREA*/01490000
CMDLEN FIXED BIN(15) INIT(0), /* NUM BYTES IN A @47*/ 01500000
/* RETURNED CMD STRING */ 01510000
/* RETURN AREA */ 01520000
01 FIXED_BUFF BASED(ADDR(RETURN_BUFF)), 01530000
02 FIXED_LEN FIXED BIN(15), 01540000
02 FIXED_TEXT CHAR(4160), 01550000
/* OVERLAY OF PASSED BUF FOR @47*/ 01560000
/* MOVING DATA FROM RETURN AREA */ 01570000
FILLBYTS FIXED BIN(15) /* NUMBER OF FILL BYTES NEED @47*/ 01580000
INIT(0), /* TO MAKE RECORD LENGTHS IN */ 01590000
/* OUTPUT EQUAL TO BUFROWLN */ 01600000
NUMFULL FIXED BIN(15) /* NUMBER OF FULL LINES IN @47*/ 01610000
INIT(0), /* PASSED AREA */ 01620000
PARTROW FIXED BIN(15) /* LENGTH OF NON-FULL LINE @47*/ 01630000
INIT(0), 01640000
J FIXED BIN(15) /* LOOP COUNTER @47*/ 01650000
INIT(0), 01660000
BUFPOSI FIXED BIN(15) /* POSITION IN RETURN BUFFER @47*/ 01670000
INIT(0), 01680000
BUFPOSO FIXED BIN(15) /* POSITION IN PASSED BUFFER @47*/ 01690000
INIT(0), 01700000
LEN_CHAR CHAR(2) /* LENGTH BYTES IN COMMAND @47*/ 01710000
INIT(' '), /* RESULT STRING */ 01720000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1113
LEN_BIT BIT(16) /* LENGTH IN BITS FOR @47*/ 01730001
INIT('0'B), /* CONVERSION */ 01740000
LEN_BIN FIXED BIN(15) /* LENGTH IN BINARY @47*/ 01750000
INIT(0), 01760000
SPACE_LEFT FIXED BIN(15) /* BYTES LEFT IN BUFFER @47*/ 01770000
INIT(0); 01780000
/***********************************************************/ 01790000
/* CONSTANTS @47*/ 01800000
/***********************************************************/ 01810000
DCL 01820000
BLANK CHAR(1) INIT(' ') STATIC, /* BUFFER PADDING @47*/ 01830000
BUFROWLN FIXED BIN(15) INIT(80) STATIC; /* LNGTH OF A LINE @47*/ 01840000
/* PASSED TO INVOKER */ 01850000
/***********************************************************/ 01860000
/* DECLARE IFI CALL MACRO DSNWLI */ 01870000
/***********************************************************/ 01880000
01890000
DCL 01900000
DSNWLI ENTRY EXTERNAL OPTIONS(ASM INTER RETCODE); 01910000
/* ENTRY POINT IN LANGUAGE INTERFACE */ 01920000
/* MODULES TO HANDLE IFC API CALLS. */ 01930000
%PAGE; 01940000
/****************************************************/ 01950000
/* IFCA - (INSTRUMENTATION FACILITY COMMUNICATION */ 01960000
/* AREA) CONTAINS INFORMATION REGARDING THE */ 01970000
/* SUCCESS OF THE CALL AND PROVIDES FEEDBACK*/ 01980000
/* INFORMATION TO THE APPLICATION PROGRAM. */ 01990000
/* */ 02000000
/* WARNING: THIS AREA MUST BE MAINTAINED TO INCLUDE*/ 02010000
/* ANY CHANGES TO THE MAPPING MACRO */ 02020000
/* DSNDIFCA */ 02030000
/* */ 02040000
/****************************************************/ 02050000
02060000
02070000
DCL 01 IFCA, 02080000
02 LNGTH /* LENGTH OF IFCA, INCL LENGTH FIELD*/ 02090000
FIXED BIN(15) INIT(0), 02100000
02 UNUSED 02110000
FIXED BIN(15) INIT(0), 02120000
02 EYE_CATCHER /* USED TO VERIFY THE IFCA BLOCK. */ 02130000
CHAR(4) INIT( 'IFCA' ), 02140000
02 OWNER_ID /* TO ESTAB OWNERSHIP OF AN OPN DEST*/ 02150000
CHAR(4) INIT(' '), 02160000
02 IFCARC1 /* RETURN CODE FOR THE IFC API CALL.*/ 02170000
FIXED BIN(31) INIT(0), 02180000
02 IFCARC2 /* REASON CODE FOR THE IFC API CALL.*/ 02190000
FIXED BIN(31) INIT(0), 02200000
02 BYTES_MOVED /* BYTES OF RECORD WHICH WERE MOVED.*/ 02210000
FIXED BIN(31) INIT(0), 02220000
02 EXCESS_RECDS /* BYTES OF RECORD WHICH DID NOT FIT*/ 02230000
FIXED BIN(31) INIT(0), 02240000
02 OPN_WRIT_SEQ_NUM /* LAST OPN WRTR SEQ# FOR READA FUNC*/ 02250000
FIXED BIN(31) INIT(0), 02260000
02 NUM_RECDS_LOST /* RECORDS LOST INDICATOR. */ 02270000
FIXED BIN(31) INIT(0), 02280000
02 OPN_NAME_FOR_READA /* OPN NAME USED FOR READA REQUEST */ 02290000
CHAR(4) INIT(' '), 02300000
02 OPN_NAMES_AREA, /* AREA CONTAINING UP TO 8 OPN NAMES*/ 02310000
03 OPN_LNGTH /* LENGTH OF OPN NAMES RETURNED + 4.*/ 02320000
FIXED BIN(15) INIT(0), 02330000
03 UNUSED_2 02340000
FIXED BIN(15) INIT(0), 02350000
03 ARRAY_OPN_NAMES(8) /* AREA FOR OPN NAMES RETURNED */ 02360000
CHAR(4) INIT(' '), 02370000
02 TRACE_NOS_AREA, /* AREA CONTAINING UP TO 8 TRACE #'S*/ 02380000
03 TRACE_LNGTH /* LENGTH OF TRACE NO.S RETURNED + 4*/ 02390000
FIXED BIN(15) INIT(0), 02400000
03 UNUSED_3 02410000
FIXED BIN(15) INIT(0), 02420000
03 ARRAY_TRACE_NOS(8)/* AREA FOR TRACE NUMBERS RETURNED */ 02430000
CHAR(2) INIT(' '), 02440000
02 DIAGNOS_AREA, /* DIAGNOSTIC AREA. */ 02450000
03 DIAGNOS_LNGTH /* DIAGNOSTIC LENGTH. */ 02460000
FIXED BIN(15) INIT(0), 02470000
03 UNUSED_4 02480000
FIXED BIN(15) INIT(0), 02490000
03 DIAGNOS_DATA /* DIAGNOSTIC DATA. */ 02500000
CHAR(80) INIT(' '); 02510000
02520000
DCL 01 OUTPUT_AREA, 02530000
02 LNGTH /* LENGTH OF APPL PGM REC TO WRITE */ 02540000
1114 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
FIXED BIN(15) INIT(0), 02550000
02 UNUSED 02560000
FIXED BIN(15) INIT(0), 02570000
02 TEXT_OR_COMMAND /* ACTUAL COMMAND OR RECORD TEXT. */ 02580000
CHAR(254) INIT(' '); 02590000
02600000
DCL 01 RETURN_AREA CTL, /* COMMAND RESULT AREA */ 02610000
02 LNGTH /* NUMBER OF BYTES */ 02620000
FIXED BIN(31), 02630000
02 RTRN_BUFF /* OUTPUT BUFFER */ 02640000
CHAR(*); 02650000
02660000
/***********************************************************/ 02670000
/* GENERAL INITIALIZATION */ 02680000
/***********************************************************/ 02690000
02700000
FUNCTION = 'COMMAND'; /* SET FUNCTION FOR IFI CALL */ 02710000
IFCA.LNGTH = STORAGE(IFCA); /* BYTES USED IN MEMORY */ 02720000
IFCA.EYE_CATCHER = 'IFCA'; /* EYE CATCHER */ 02730000
IFCA.OWNER_ID = 'LOC2'; /* DB2 LOCATION 1=LOCAL, 2=REMOTE*/ 02740000
FREE RETURN_AREA; /* FREE STORAGE AND THEN */ 02750000
/* ALLOCATE STORAGE FOR THE */ 02760000
ALLOCATE 1 RETURN_AREA, /* RETURN AREA */ 02770000
2 LNGTH, 02780000
2 RTRN_BUFF CHAR(4096); 02790000
02800000
RTRN_BUFF = ' '; /* CLEAR THE RETURN BUFFER */ 02810000
RETURN_AREA.LNGTH = 4096; /* LENGTH OF RETURN BUFFER */ 02820000
TEXT_OR_COMMAND=BLANK; /* CLEAR THE DB2 COMMAND AREA*/ 02830000
OUTPUT_AREA.UNUSED = '00000000'B; /* CLEAR THE UNUSED AREA */ 02840000
OUTPUT_AREA.LNGTH = LENGTH(INPUTCMD)+4; /* GET REAL LENGTH OF */ 02850000
OUTPUT_AREA.TEXT_OR_COMMAND = INPUTCMD; /* ACTUAL DB2 COMMAND */ 02860000
02870000
/******************************************/ 02880000
/* MAKE THE IFI CALL VIA THE DSNWLI MACRO */ 02890000
/******************************************/ 02900000
02910000
CALL DSNWLI (FUNCTION, IFCA, RETURN_AREA, OUTPUT_AREA); 02920000
02930000
/********************************************************************/ 02940000
/* COPY SELECTED VARIABLES FROM IFI COMMAND RESULTS TO OUTPUT */ 02950000
/* PARAMETER VARIABLES TO PASS TO REQUESTER PROGRAM FOR PROCESSING. */ 02960000
/********************************************************************/ 02970000
02980000
IFCA_RET_HEX = IFCA.IFCARC1; /* RETURN CODE IN BINARY */ 02990000
IFCA_RES_HEX = IFCA.IFCARC2; /* REASON CODE IN BINARY */ 03000000
BUFF_OVERFLOW = 0; /* PLENTY OF ROOM IN BUFF SO FAR @47*/ 03010000
BUFPOSI = 1; /* INIT POSITION IN RETURN AREA @47*/ 03020000
BUFPOSO = 1; /* INIT POSITION IN PASSED BUFF @47*/ 03030000
/******************************************************************/ 03040000
/* COPY RECORDS FROM THE RETURN AREA TO THE CALLER'S BUFFER. @47*/ 03050000
/* PAD EACH RECORD IN THE CALLER'S BUFFER WITH BLANKS SO ITS @47*/ 03060000
/* LENGTH IS A MULTIPLE OF BUFROWLN. @47*/ 03070000
/******************************************************************/ 03080000
03090000
IF IFCA.BYTES_MOVED ^= 0 THEN /*@47*/ 03100000
DO; /* IF ANYTHING TO COPY @47*/ 03110000
DO WHILE (BUFPOSI <= IFCA.BYTES_MOVED - 2); /*@47*/ 03120000
/* COPY TEXT TO PASSED BUF @47*/ 03130000
LEN_CHAR = (SUBSTR(RETURN_AREA.RTRN_BUFF,BUFPOSI,2)); /*@47*/ 03140000
/* GET LENGTH BYTES @47*/ 03150000
LEN_BIT = UNSPEC(LEN_CHAR); /*@47*/ 03160000
/* CONVERT TO BIT STRING @47*/ 03170000
LEN_BIN = LEN_BIT; /*@47*/ 03180000
/* THEN CONVERT TO BINARY @47*/ 03190000
/* CALC BYTES LEFT IN PASSED@47*/ 03200000
LEN_BIN = LEN_BIN - 4; /* TAKE LENGTH BYTES OFF LEN@47*/ 03210000
SPACE_LEFT = (LEN_BIN / BUFROWLN) * BUFROWLN; /*@47*/ 03220000
IF MOD(LEN_BIN,BUFROWLN) > 0 THEN /*@47*/ 03230000
SPACE_LEFT = SPACE_LEFT + BUFROWLN; /*@47*/ 03240000
IF BUFPOSO + SPACE_LEFT - 1 > RETURN_LEN THEN /*@47*/ 03250000
BUFF_OVERFLOW = 1; /* INDICATE BUFFER IS FULL @47*/ 03260000
IF BUFF_OVERFLOW = 1 THEN /*@47*/ 03270000
LEAVE; /* CAN'T COPY MORE, GET OUT @47*/ 03280000
BUFPOSI = BUFPOSI + 4; /* MOVE PAST LENGTH BYTES @47*/ 03290000
IF BUFPOSI + LEN_BIN - 1 > IFCA.BYTES_MOVED THEN /*@47*/ 03300000
LEAVE; /* AT END OF BUFFER @47*/ 03310000
NUMFULL = LEN_BIN / BUFROWLN; /* NUMBER OF FULL LINES @47*/ 03320000
PARTROW = MOD(LEN_BIN,BUFROWLN); /* LENGTH OF PARTIAL LINE @47*/ 03330000
FILLBYTS = BUFROWLN - PARTROW; /* NUMBER OF PAD BYTES NEED@47*/ 03340000
IF NUMFULL > 0 THEN /* MOVE ALL COMPLETE LINES @47*/ 03350000
DO J = 1 TO NUMFULL; /*@47*/ 03360000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1115
SUBSTR(FIXED_BUFF.FIXED_TEXT,BUFPOSO,BUFROWLN) = /*@47*/ 03370000
SUBSTR(RETURN_AREA.RTRN_BUFF,BUFPOSI,BUFROWLN); /*@47*/ 03380000
BUFPOSO = BUFPOSO + BUFROWLN; /* MOVE PAST STRG IN OUTP@47*/ 03390000
BUFPOSI = BUFPOSI + BUFROWLN; /* MOVE PAST STRG IN INPT@47*/ 03400000
REMBYTES = REMBYTES - BUFROWLN; /* CALCULATE BYTES LEFT@47*/ 03410000
END; /*@47*/ 03420000
IF PARTROW > 0 THEN /*@47*/ 03430000
DO; /* MOVE PARTIAL LINE @47*/ 03440000
SUBSTR(FIXED_BUFF.FIXED_TEXT,BUFPOSO,PARTROW) = /*@47*/ 03450000
SUBSTR(RETURN_AREA.RTRN_BUFF,BUFPOSI,PARTROW); /*@47*/ 03460000
BUFPOSI = BUFPOSI + PARTROW; /* MOVE PAST STR IN INPUT@47*/ 03470000
BUFPOSO = BUFPOSO + PARTROW - 1; /* MOVE TO END OF @47*/ 03480000
/* STRING IN OUTPUT @47*/ 03490000
SUBSTR(FIXED_BUFF.FIXED_TEXT,BUFPOSO,1) = BLANK; /*@47*/ 03500000
/* REPLACE THE NEW LINE @47*/ 03510000
/* CHARACTER IN THE LAST */ 03520000
/* POSITION WITH A BLANK */ 03530000
BUFPOSO = BUFPOSO + 1; /* MOVE PAST STRG IN OUTP@47*/ 03540000
REMBYTES = REMBYTES - PARTROW; /* CALCULATE BYTES LEFT @47*/ 03550000
END; /*@47*/ 03560000
IF PARTROW > 0 THEN /* FILL UP SPACE WITH BLK@47*/ 03570000
DO; /*@47*/ 03580000
DO J = BUFPOSO TO (BUFPOSO + FILLBYTS - 1); /*@47*/ 03590000
SUBSTR(FIXED_BUFF.FIXED_TEXT,J,1) = ' '; /*@47*/ 03600000
END; /*@47*/ 03610000
BUFPOSO = BUFPOSO + FILLBYTS; /* MOVE PAST BLANKS @47*/ 03620000
END; /*@47*/ 03630000
END; /* COPY TEXT TO PASSED BUF @47*/ 03640000
FIXED_BUFF.FIXED_LEN = BUFPOSO - 1; /*@47*/ 03650000
/* GET BYTES IN PASSED BUF @47*/ 03660000
END; /* IF ANYTHING TO COPY @47*/ 03670000
END DSN8EP2; /* END PROGRAM */ 03680000
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSN8EPU
PASS Db2 UTILITY STATEMENTS TO BE EXECUTED BY THE STORED PROCEDURE PROGRAM DSNUTILS.
1116 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* '; * 00380000
* * 00390000
* MODULE TYPE = PROCEDURE * 00400000
* PROCESSOR = * 00410000
* ADMF PRECOMPILER * 00420000
* PL/I MVS/VM (FORMERLY PL/I SAA AD/CYCLE) * 00430000
* MODULE SIZE = 2K * 00440000
* ATTRIBUTES = RE-ENTERABLE * 00450000
* * 00460000
* ENTRY POINT = DSN8EPU * 00470000
* PURPOSE = SEE FUNCTION * 00480000
* LINKAGE = STANDARD MVS PROGRAM INVOCATION. * 00490000
* INPUT = PARAMETERS EXPLICITLY PASSED TO THIS FUNCTION: * 00500000
* SYMBOLIC LABEL/NAME = SYSIN * 00510000
* DESCRIPTION = DDNAME OF SEQUENTIAL DATA SET CONTAINING * 00520000
* DSNUTILS STORED PROCEDURE PARAMETERs. * 00530000
* OUTPUT = PARAMETERS EXPLICITLY RETURNED: * 00540000
* SYMBOLIC LABEL/NAME = SYSPRINT * 00550000
* DESCRIPTION = DDNAME OF SEQUENTIAL OUTPUT DATA SET TO * 00560000
* CONTAIN RESULTS OF THE UTILITIES EXECUTED. * 00570000
* * 00580000
* EXIT NORMAL = * 00590000
* * 00600000
* NORMAL MESSAGES = * 00610000
* * 00620000
* EXIT-ERROR = * 00630000
* * 00640000
* * 00650000
* ABEND CODES = NONE * 00660000
* * 00670000
* ERROR MESSAGES = * 00680000
* * 00690000
* EXTERNAL REFERENCES = * 00700000
* ROUTINES/SERVICES = NONE * 00710000
* DATA-AREAS = NONE * 00720000
* CONTROL-BLOCKS = * 00730000
* SQLCA - SQL COMMUNICATION AREA * 00740000
* * 00750000
* PSEUDOCODE = * 00760000
* * 00770000
* DSN8EPU: PROCEDURE. * 00780000
* DECLARATIONS. * 00790000
* INITIALIZE VARIABLES. * 00800000
* GET THE INPUT PARAMETERS AND COPY TO SYSPRINT. * 00810000
* EXEC SQL CALL SYSPROC.DSNUTILS. * 00820000
* DO UNTIL SQLCODE > 0. * 00830000
* EXEC SQL FETCH FROM RESULT SET. * 00840000
* PRINT RESULT SET TO SYSPRINT. * 00850000
* END. * 00860000
* * 00870000
* NOTICE = * 00880000
* THIS SAMPLE PROGRAM USES DB2 UTILITIES. SOME UTILITY FUNCTIONS* 00890000
* ARE ELEMENTS OF SEPARATELY ORDERABLE PRODUCTS. SUCCESSFUL USE* 00900000
* OF A PARTICULAR SAMPLE MAY BE DEPENDENT UPON THE OPTIONAL * 00910000
* PRODUCT BEING LICENSED AND INSTALLED IN YOUR ENVIRONMENT. * 00920000
* * 00930000
* CHANGE ACTIVITY = * 00940000
* PQ24720 - Add FILTRDSN and Fix I/O for seq #ed input * 00950000
* PQ44916 - Fix code hole closed by VA and Enterprise PL/I * 00960000
* d54292 - Check for unexpected SQLCODE in FETCH loop * 00970001
*******************************************************************/ 00980000
DCL SYSPRINT FILE OUTPUT STREAM; 00990000
01000000
DCL SYSIN FILE INPUT STREAM ENV( F RECSIZE(80) ); 01010000
01020000
DCL 01 SYSIN_REC, 01030000
05 UTIL_OPTS CHAR( 72 ), 01040000
05 SEQ_NOS CHAR( 08 ); 01050000
01060000
DCL SYSIN_EOF BIT( 01 ) INIT( '0'B ); 01070000
ON ENDFILE( SYSIN ) 01080000
SYSIN_EOF = '1'B; 01090000
01100000
DCL UTIL_OPTS_BUFF VARYING CHAR( 32760 ) INIT( '' ); 01110000
01120000
DCL ADDR BUILTIN; 01130000
DCL NULL BUILTIN; 01140000
DCL PLIRETC BUILTIN; 01150000
01160000
DCL UID CHAR(16) VARYING; /* UTILITY ID */ 01170000
DCL RESTART CHAR(8) VARYING; /* RESTART */ 01180000
DCL UTSTMT CHAR(32704) VARYING; 01190000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1117
DCL RETCODE FIXED BIN(31); 01200000
DCL UTILITY CHAR(20) VARYING; 01210000
DCL RECDSN CHAR(44) VARYING, 01220000
RECDEVT CHAR(8), 01230000
RECSPACE FIXED BIN(15); 01240000
DCL DISCDSN CHAR(44) VARYING, 01250000
DISCDEVT CHAR(8), 01260000
DISCSPACE FIXED BIN(15); 01270000
DCL PNCHDSN CHAR(44) VARYING, 01280000
PNCHDEVT CHAR(8), 01290000
PNCHSPACE FIXED BIN(15); 01300000
DCL COPYDSN1 CHAR(44) VARYING, 01310000
COPYDEVT1 CHAR(8), 01320000
COPYSPACE1 FIXED BIN(15); 01330000
DCL COPYDSN2 CHAR(44) VARYING, 01340000
COPYDEVT2 CHAR(8), 01350000
COPYSPACE2 FIXED BIN(15); 01360000
DCL RCPYDSN1 CHAR(44) VARYING, 01370000
RCPYDEVT1 CHAR(8), 01380000
RCPYSPACE1 FIXED BIN(15); 01390000
DCL RCPYDSN2 CHAR(44) VARYING, 01400000
RCPYDEVT2 CHAR(8), 01410000
RCPYSPACE2 FIXED BIN(15); 01420000
DCL WORKDSN1 CHAR(44) VARYING, 01430000
WORKDEVT1 CHAR(8), 01440000
WORKSPACE1 FIXED BIN(15); 01450000
DCL WORKDSN2 CHAR(44) VARYING, 01460000
WORKDEVT2 CHAR(8), 01470000
WORKSPACE2 FIXED BIN(15); 01480000
DCL MAPDSN CHAR(44) VARYING, 01490000
MAPDEVT CHAR(8), 01500000
MAPSPACE FIXED BIN(15); 01510000
DCL ERRDSN CHAR(44) VARYING, 01520000
ERRDEVT CHAR(8), 01530000
ERRSPACE FIXED BIN(15); 01540000
DCL FILTRDSN CHAR(44) VARYING, 01550000
FILTRDEVT CHAR(8), 01560000
FILTRSPACE FIXED BIN(15); 01570000
DCL RESULTS SQL TYPE IS RESULT_SET_LOCATOR VARYING; 01580000
DCL SEQNO FIXED BIN(31); 01590000
DCL TEXT CHAR(122) VARYING; 01600000
EXEC SQL INCLUDE SQLCA; 01610000
Uid=''; 01620000
Restart=''; 01630000
Utstmt=''; 01640000
RetCode = 0; 01650000
Utility=''; 01660000
RecDSN=''; RecDEVT=''; RecSpace=0; 01670000
DiscDSN=''; DiscDEVT=''; DiscSpace=0; 01680000
PnchDSN=''; PnchDEVT=''; PnchSpace=0; 01690000
CopyDSN1=''; CopyDEVT1=''; CopySpace1=0; 01700000
CopyDSN2=''; CopyDEVT2=''; CopySpace2=0; 01710000
RcpyDSN1=''; RcpyDEVT1=''; RcpySpace1=0; 01720000
RcpyDSN2=''; RcpyDEVT2=''; RcpySpace2=0; 01730000
WorkDSN1=''; WorkDEVT1=''; WorkSpace1=0; 01740000
WorkDSN2=''; WorkDEVT2=''; WorkSpace2=0; 01750000
MapDSN=''; MapDEVT=''; MapSpace=0; 01760000
ErrDSN=''; ErrDEVT=''; ErrSpace=0; 01770000
FiltrDSN=''; FiltrDEVT=''; FiltrSPACE=0; 01780000
01790000
/* Collect DSNUTILS options from SYSIN records, columns 1-72 */ 01800000
GET COPY EDIT( UTIL_OPTS,SEQ_NOS ) ( A(72),A(8) ); 01810000
DO WHILE( ^SYSIN_EOF ); 01820000
UTIL_OPTS_BUFF = UTIL_OPTS_BUFF || UTIL_OPTS; 01830000
GET COPY EDIT( UTIL_OPTS,SEQ_NOS )( A(72),A(8) ); 01840000
END; /* DO WHILE( ^SYSIN_EOF ); */ 01850000
01860000
/* Assign DSNUTILS options from inputted settings in UTIL_OPTS_BUFF */ 01870000
GET STRING( UTIL_OPTS_BUFF ) DATA; 01880000
01890000
/* Call DSNUTILS stored procedure to process the inputted settings */ 01900000
EXEC SQL 01910000
CALL SYSPROC.DSNUTILS(:UID, :RESTART, 01920000
:UTSTMT, 01930000
:RETCODE, 01940000
:UTILITY, 01950000
:RECDSN ,:RECDEVT ,:RECSPACE , 01960000
:DISCDSN ,:DISCDEVT ,:DISCSPACE , 01970000
:PNCHDSN ,:PNCHDEVT ,:PNCHSPACE , 01980000
:COPYDSN1,:COPYDEVT1,:COPYSPACE1, 01990000
:COPYDSN2,:COPYDEVT2,:COPYSPACE2, 02000000
:RCPYDSN1,:RCPYDEVT1,:RCPYSPACE1, 02010000
1118 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
:RCPYDSN2,:RCPYDEVT2,:RCPYSPACE2, 02020000
:WORKDSN1,:WORKDEVT1,:WORKSPACE1, 02030000
:WORKDSN2,:WORKDEVT2,:WORKSPACE2, 02040000
:MAPDSN ,:MAPDEVT ,:MAPSPACE , 02050000
:ERRDSN ,:ERRDEVT ,:ERRSPACE , 02060000
:FILTRDSN,:FILTRDEVT,:FILTRSPACE); 02070000
IF SQLCODE < 0 THEN 02080000
DO; 02090000
PUT SKIP EDIT('CALL SQLCA')(A); 02100000
PUT SKIP DATA(SQLCA); 02110000
CALL PLIRETC(8); /* SET PLI RETURN CODE */ 02120000
RETURN; 02130000
END; 02140000
02150000
EXEC SQL 02160000
ASSOCIATE LOCATOR (:RESULTS) WITH PROCEDURE SYSPROC.DSNUTILS; 02170000
IF SQLCODE < 0 THEN 02180000
DO; 02190000
PUT SKIP EDIT('ASSOCIATE LOCATOR SQLCA')(A); 02200000
PUT SKIP DATA(SQLCA); 02210000
CALL PLIRETC(8); /* SET PLI RETURN CODE */ 02220000
RETURN; 02230000
END; 02240000
02250000
EXEC SQL 02260000
ALLOCATE SYSPRINT CURSOR FOR RESULT SET :RESULTS; 02270000
IF SQLCODE < 0 THEN 02280000
DO; 02290000
PUT SKIP EDIT('ALLOCATE SYSPRINT SQLCA')(A); 02300000
PUT SKIP DATA(SQLCA); 02310000
CALL PLIRETC(8); /* SET PLI RETURN CODE */ 02320000
RETURN; 02330000
END; 02340000
02350000
FETCHLOOP: 02360000
DO UNTIL(SQLCODE < 0 | SQLCODE = 100 ); 02370001
EXEC SQL 02380000
FETCH SYSPRINT INTO :SEQNO, :TEXT; 02390000
IF (SQLCODE >= 0) 02400000
& (SQLCODE ^= 100) THEN 02410000
DO; 02420000
PUT SKIP EDIT(TEXT)(A); 02430000
END; 02440000
IF (SQLCODE ^= 0) 02450000
& (SQLCODE ^= 100) THEN 02460000
DO; 02470000
PUT SKIP EDIT('FETCH SYSPRINT SQLCA')(A); 02480000
PUT SKIP DATA(SQLCA); 02490000
END; 02500000
END FETCHLOOP; 02510000
IF SQLCODE < 0 THEN 02520000
DO; 02530000
CALL PLIRETC(8); /* SET PLI RETURN CODE */ 02540000
RETURN; 02550000
END; 02560000
02570000
PUT SKIP DATA(RetCode); 02580000
CALL PLIRETC(RetCode); /* SET PLI RETURN CODE */ 02590000
END DSN8EPU; 02600000
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSN8ED1
Pass Db2 commands received from standard input to stored procedure DSN8ED2 for execution.
/********************************************************************/
/* Module name = DSN8ED1 (sample program) */
/* */
/* DESCRIPTIVE NAME = Stored procedure result set requester pgm */
/* */
/* LICENSED MATERIALS - PROPERTY OF IBM */
/* 5645-DB2 */
/* (C) COPYRIGHT 1998 IBM CORP. ALL RIGHTS RESERVED. */
/* */
/* STATUS = VERSION 6 */
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1119
/* */
/* Function = */
/* */
/* Pass DB2 commands received from standard input to */
/* stored procedure DSN8ED2 for execution. Receive the */
/* command results from DSN8ED2 as result set. Unload the */
/* result set and print the contents to standard output. */
/* */
/* Dependencies = None */
/* */
/* Restrictions = */
/* */
/* 1. DB2 commands must be preceded by a hyphen and */
/* followed by a semicolon. Lines with an asterisk */
/* in the first column or two hyphens as the first */
/* nonblank characters are interpreted as comment */
/* lines. Two hyphens placed after the command text in */
/* in a line indicate that the rest of the line is */
/* comments only. */
/* */
/* 2. A command may be no more than 4096 bytes. */
/* */
/* Input = */
/* 1. A single input parameter that indicates the location */
/* of the stored procedure. The contents must be a */
/* valid DB2 location name of at most 16 characters. */
/* */
/* 2. Lines of length INPUTL from standard input. */
/* Only the first INPUSED bytes are used. Lines are */
/* considered to be either command text or comments. */
/* Command text begins with a hyphen and ends with a */
/* semicolon. Comments begin with an asterisk in */
/* column one or two hyphens as the first two nonblank */
/* characters. Command text may span lines, but comment */
/* text may not. */
/* */
/* Output = */
/* Lines of length OUTLEN to standard output. */
/* Each line contains one of the following: */
/* a. Command text. */
/* b. Results returned by the DB2 for MVS/ESA command */
/* processor after the command is issued. */
/* */
/* Module type = C program */
/* Processor = */
/* ADMF Precompiler */
/* C/370 */
/* Module size = See linkedit output */
/* Attributes = Not reentrant or reusable */
/* */
/* Entry point = DSN8ED1 */
/* Purpose = See Function */
/* Linkage = Standard MVS program invocation, one parameter. */
/* */
/* Exit normal = */
/* */
/* Return code 0 on normal completion. */
/* */
/* Normal messages = */
/* */
/* *** Input statement: <DB2 command input statement text> */
/* *** IFI return area: <Results of DB2 command execution> */
/* */
/* */
/* Exit-error = */
/* */
/* Return code = 4 - Warnings occurred. */
/* - The DB2 for MVS/ESA Instrumentation Facility Interface */
/* (IFI) invocation of the DB2 command resulted in a */
/* return code 4. The accompanying reason code indicates */
/* the specific problem. */
/* */
/* Return code = 8 - Errors occurred. */
/* - The DB2 for MVS/ESA Instrumentation Facility Interface */
/* (IFI) invocation of the DB2 command resulted in a */
/* return code 8. The accompanying reason code indicates */
/* the specific problem. */
/* */
/* Return code = 12 - Severe errors occurred. */
/* - Input parameter 1 did not contain the name of the */
/* DB2 server where the stored procedure resides. */
/* - The input dataset (SYSIN) did not contain any data. */
1120 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
/* - Command input did not begin with a hyphen. */
/* - Command input was not ended with a semicolon. */
/* - An input statement contained more than STMTMAX */
/* bytes. */
/* - Connection to the stored procedure location failed. */
/* - The SQL CALL statement to the stored procedure failed. */
/* - The DB2 for MVS/ESA Instrumentation Facility Interface */
/* (IFI) invocation of the DB2 command resulted in a */
/* return code 12. The accompanying reason code indicates */
/* the specific problem. */
/* - The call to the stored procedure, DSN8ED2, succeeded */
/* but DSN8ED2 experienced SQL problems. The formatted */
/* SQL error message appears in SYSPRINT. */
/* - The call to the stored procedure, DSN8ED2, succeeded */
/* but no result set was returned. SYSPRINT messages */
/* should provide more information. */
/* - A result set was returned by DSN8ED2 but one of the */
/* following occurred (see SYSPRINT messages for details):*/
/* - The locator variable could not be associated with */
/* the result set. */
/* - The result set cursor could not be allocated */
/* - No data could be fetched from the result set cursor. */
/* */
/* Abend codes = None */
/* */
/* Error messages = */
/* - *** ERROR: No server name provided - DSN8ED1 ended. */
/* - *** ERROR: No input records found - DSN8ED1 ended. */
/* - *** ERROR: Syntax for DB2 command is invalid. */
/* *** A valid command ends with a semicolon. */
/* - *** ERROR: Syntax for DB2 command is invalid. */
/* *** A valid command begins with a hyphen. */
/* - *** ERROR: Statement length is greater than the ____ */
/* character maximum. */
/* - *** ERROR: Connection to server <location> was unsuc- */
/* cessful. */
/* - *** ERROR: Call to stored procedure DSN8ED2 failed; */
/* diagnostics follow. */
/* - *** ERROR: The following diagnostics were returned by */
/* stored procedure DSN8ED2. */
/* - *** ERROR: DSNTIAR could not format the message. */
/* SQLCODE is ____, SQLERRM is ___________ ... */
/* - *** WARNING: Call to stored procedure DSN8ED2 succeeded */
/* but no result set was returned. */
/* - *** WARNING: IFI error codes returned by DSN8ED2. */
/* Return code=___, reason code=____ from */
/* IFI request. */
/* - *** WARNING: ____ records were lost because the IFI */
/* return area in stored procedure DSN8ED2 */
/* is too small to accomodate this request. */
/* ** Increase the IFI return area (RETURN_LEN) */
/* in DSN8ED2 and then recompile/relink/rebind */
/* before resubmitting this request. */
/* */
/* - *** Syntax for DB2 command is invalid. */
/* *** A valid command must begin with a hyphen. */
/* */
/* - *** Statement length is greater than the <STMTMAX> */
/* character maximum. */
/* - *** Connection to <location> unsuccessful. */
/* *** SQLCODE is <sqlcode>. */
/* - *** Call to DSN8ED2 unsuccessful. */
/* *** SQLCODE is <sqlcode>. */
/* - *** Insufficient space to receive all output from IFI */
/* return area. */
/* - *** Return code=<return code>, reason code=<reason code> */
/* from IFI request. */
/* - *** Severe error occurred. Program is terminating. */
/* */
/* External references = */
/* Routines/services = */
/* none */
/* Data areas = */
/* none */
/* Control blocks = */
/* SQLCA - SQL communication area */
/* */
/* Pseudocode = */
/* */
/* DSN8ED1: */
/* - Extract the name of the DB2 server where stored procedure */
/* DSN8ED2 resides from input parameter number 1. */
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1121
/* - Call build_DB2_command to create a logical DB2 command record*/
/* from one or more records from SYSIN. */
/* - If a command was created successfully, do the following until*/
/* all input has been processed or severe errors occur. */
/* - Call connect_to_sp_server to connect to the DB2 server */
/* specified in the first input parameter. */
/* - Call send_DB2_command_to_sp to invoke stored procedure */
/* DSN8ED2 to process the command. */
/* - Call output_results_from_sp to unload the result set */
/* from DSN8ED2 to SYSPRINT. */
/* - Call build_DB2_command to create the next logical DB2 */
/* command record from SYSIN records. */
/* End DSN8ED1 */
/* */
/* build_DB2_command: */
/* - Read a record from SYSIN */
/* - Do the following until either a full command is built, end */
/* of file is reached, or an error occurs: */
/* - if the first byte of the record is '*' or the first two */
/* nonblank bytes of the record are '--' then the whole */
/* record is a comment. Disregard it. */
/* - if '--' is encountered after nonblanks are found then the */
/* rest of the record is a comment and can be disregarded. */
/* - else if a semicolon is found inside a delimited string */
/* call copy_byte_to_cmd_buf to add it to the command string. */
/* - a delimited string is one that starts but has not yet */
/* terminated with a single quote or a double quote */
/* - else if a semicolon is found outside a delimited string */
/* then the command is complete. */
/* - else if a nonblank is found then call copy_byte_to_cmd_buf */
/* to add it to the command string. */
/* - else if a blank is found inside a delimited string then */
/* call copy_byte_to_cmd_buf to add it to the command string. */
/* - else if a blank is found outside a delimited string and */
/* the preceding byte was nonblank then call copy_byte_to_ */
/* cmd_buf to add it to the command string. */
/* - else if a blank is found outside a delimited string and */
/* the preceding byte was blank then disregard the blank. */
/* - if the input record is exhausted before a terminating */
/* semicolon is found, read the next input record. */
/* - When a command is created successfully, call echo_DB2_command*/
/* to output the reformatted command. */
/* - Check the command to ensure that it starts with a hypen. */
/* End build_DB2_command */
/* */
/* copy_byte_to_cmd_buf */
/* - append the current byte of the input record to the end of */
/* the command string and update length of command string. */
/* - if command string exceeds buffer size, issue a message and */
/* end DSN8ED1. */
/* End copy_byte_to_cmd_buf */
/* */
/* echo_DB2_command */
/* - output the reformatted DB2 command to SYSPRINT */
/* End echo_DB2_command */
/* */
/* connect_to_sp_server */
/* - invoke SQL to CONNECT to the DB2 server where stored proc- */
/* edure DSN8ED2 resides. */
/* - if the CONNECT fails, issue a message and end DSN8ED1. */
/* End connect_to_sp_server */
/* */
/* send_DB2_command_to_sp */
/* - invoke SQL to call stored procedure DSN8ED2 to process the */
/* contents of the command buffer. */
/* - analyze the resultant SQLCODE, IFI return and result codes, */
/* and buffer overload and error parameters returned by DSN8ED2.*/
/* End send_DB2_command_to_sp */
/* */
/* output_results_from_sp */
/* - associate a DB2 locator variable with the result set from */
/* stored procedure DSN8ED2 */
/* - allocate a cursor to the result set */
/* - fetch each row from the result set and output it to SYSPRINT */
/* End output_results_from_sp */
/* */
/* sql_error */
/* - invoke DSNTIAR to format the current SQL code and print the */
/* messages to SYSPRINT */
/* - if DSNTIAR cannot detail the code, output the SQLCODE and */
/* SQLERRM to SYSPRINT
/* End sql_error */
1122 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
/* */
/* Change activity = */
/* none */
/********************************************************************/
struct {
short int cmdlen; /* Statement length */
char cmdtxt[4096]; /* Statement text */
} cmdbuf; /* Statement buffer passed to */
/* stored procedure */
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1123
/*********************************************************************
**********************************************************************
** main routine **
**********************************************************************
*********************************************************************/
int main( int argc, char *argv[] ) /*proc*/
{
/*******************************************************************
* initialize working variables *
*******************************************************************/
cmdbuf.cmdlen = 0; /* Nothing in command buf yet */
input_eof = No; /* Not at end of input */
rc = 0; /* No errors yet */
/*******************************************************************
* get input parameter (name of server where stored proc resides) *
*******************************************************************/
for( j=1; j<argc; j++ ) /* break out the input parms */
parms[j] = argv[j];
/*******************************************************************
* build the first DB2 command from one or more input records *
*******************************************************************/
if( rc < RETSEV )
{
build_DB2_command();
if( input_eof == Yes && rc < RETSEV )
{
printf( " *** ERROR: No input records found - DSN8ED1 ended.\n");
rc = RETSEV;
}
}
/******************************************************************/
/* If a command was built successfully, connect to the DB2 server */
/* where the stored procedure resides, send the command to the */
/* stored procedure, output the results, and build the next com- */
/* mand, if any. */
/******************************************************************/
while( input_eof == No && rc < RETSEV )
{
connect_to_sp_server(); /* connect to the server */
printf( " \n \n *** DSN8ED1 completed; highest return code was %d\n",
rc );
/********************************************************************
1124 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
*********************************************************************
** Build a DB2 command from one or more physical input records **
*********************************************************************
********************************************************************/
build_DB2_command() /*proc*/
{
/*******************************************************************
* initialize working variables *
*******************************************************************/
for( i=0; i<INPUTL; i++ ) /* Blank the input array */
input[i] = ' ';
/*******************************************************************
* read the first physical record of the command from input *
*******************************************************************/
inres = gets( input );
if( inres == NULL ) /* If end of file reached */
input_eof = Yes; /* then all finished */
/*******************************************************************
* parse the current input record for DB2 command parts *
*******************************************************************/
while( endstr == No && input_eof == No && rc < RETSEV )
{
/*****************************************************************
* If 1st char in a line is '*' -OR- the 1st two non-blank chars *
* in a line are '--', this is a comment line. Don't copy it to *
* the command buffer; request next line. *
*****************************************************************/
if( i == 0 && input[0] == ASTERISK )
i = INPUSED;
else if( cmdbuf.cmdlen == 0
&& input[0] == HYPHEN && input[1] == HYPHEN )
i = INPUSED;
/*****************************************************************
* Otherwise, this must be a command line. Parse it into the com-*
* mand buffer while looking for delimiters and the end of stmt. *
*****************************************************************/
else
while( i < INPUSED && endstr == No && rc < RETSEV )
{
if( input[i] == DQUOTE ) /* if double quote found */
if( dquotflag == Yes ) /* and is already a delimiter*/
dquotflag = No; /* note end of delimited str*/
else if( quoteflag == No ) /* else if it's not delimited*/
dquotflag = Yes; /* then it's a delimiter */
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1125
&& c > 0 /* and something's in cmd buf*/
&& cmdbuf.cmdtxt[c-1]!=BLANK)/* and prev cmd byte nonblank */
copy_byte_to_cmd_buf(); /* copy it to command buffer*/
/*****************************************************************
* if current physical record is exhausted but the current log- *
* ical record is still incomplete, get the next physical record *
*****************************************************************/
if( i >= INPUSED && endstr == No && rc < RETSEV )
{
for( i=0; i<INPUTL; i++ ) /* Blank the input array */
input[i] = ' ';
i = 0; /* reset pointer to input buff*/
inres = gets( input ); /* Read the next physical rec */
if( inres == NULL ) /* If end of file reached */
{ /* current logical rec inmplt*/
input_eof = Yes; /* don't ask for more */
printf( " *** ERROR: Syntax for DB2 command is invalid.\n");
printf( " *** A valid command ends with a" );
printf( " semicolon.\n" );
rc = RETSEV; /* stop the program */
}
}
} /* end while( endstr == No && input_eof == No && rc < RETSEV ) */
/*******************************************************************
* display the reformatted command (if one exists) *
*******************************************************************/
if( cmdbuf.cmdlen > 0 )
echo_DB2_command();
/*******************************************************************
* verify that the command has a valid syntax *
*******************************************************************/
if( endstr == Yes && input_eof == No && rc < RETSEV )
if( cmdbuf.cmdtxt[0] != HYPHEN )
{
printf( " *** ERROR: Syntax for DB2 command is invalid.\n");
printf( " *** A valid command begins with a hyphen.\n" );
rc = RETSEV;
}
} /* end of build_DB2_command() */
/*********************************************************************
**********************************************************************
** Copy the current byte of current input line to command buffer **
**********************************************************************
*********************************************************************/
copy_byte_to_cmd_buf() /*proc*/
{
cmdbuf.cmdtxt[c++] = input[i];
cmdbuf.cmdlen = c;
/*******************************************************************
* if entry is too long for command buffer, issue message and quit *
*******************************************************************/
if( cmdbuf.cmdlen >= STMTMAX )
{
printf( " *** ERROR: Statement length is greater than the" );
printf( " %d character maximum.\n",STMTMAX );
rc = RETSEV;
}
} /* end of copy_byte_to_cmd_buf() */
/*********************************************************************
**********************************************************************
** Connect to the server where the stored procedure resides **
**********************************************************************
*********************************************************************/
connect_to_sp_server() /*proc*/
{
EXEC SQL CONNECT TO :db2loc2;
if( SQLCODE != 0 )
{
1126 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
printf( " *** ERROR: Connection to server %s was unsuccessful.\n",
db2loc2 );
sql_error( " *** Connection to server unsuccessful" );
rc = RETSEV;
}
} /* end of connect_to_sp_server() */
/*********************************************************************
**********************************************************************
** Process the current DB2 command built from the input file **
**********************************************************************
*********************************************************************/
send_DB2_command_to_sp() /*proc*/
{
sperind1 = 0; /* tell DB2 to transmit */
/* contents of parm 1 */
EXEC SQL CALL DSN8.DSN8ED2( :cmdbuf :sperind1,
:ifca_ret_hex :sperind2,
:ifca_res_hex :sperind3,
:xs_bytes_hex :sperind4,
:sp_err_buf :sperind5 );
/*******************************************************************
* verify the SQL return code returned by the stored procedure *
*******************************************************************/
if( SQLCODE == 0 )
{
printf( " *** WARNING: Call to stored procedure DSN8ED2" );
printf( " succeeded\n" );
printf( " but no result set was returned.\n" );
if( rc < RETERR )
rc = RETERR;
}
else if( SQLCODE == 466 )
{
printf( " *** A result set was returned by stored procedure" );
printf( " DSN8ED2.\n" );
}
else
{
printf( " *** ERROR: Call to stored procedure DSN8ED2 failed;" );
printf( " diagnostics follow.\n" );
sql_error( "*** Stored procedure call unsuccessful." );
rc = RETSEV;
}
/*******************************************************************
* verify the IFI return code returned by the stored procedure *
*******************************************************************/
if( sperind2 != -1 && ifca_ret_hex != 0 )
{
printf( " *** WARNING: IFI error codes returned by DSN8ED2.\n" );
printf( " *** Return code=%0X ", ifca_ret_hex );
printf( " *** reason code=%0X from IFI request.\n", ifca_res_hex );
if( ifca_ret_hex > rc )
rc = ifca_ret_hex;
}
/*******************************************************************
* if IFI return buffer was too small, output a message *
*******************************************************************/
if( sperind4 != -1 && xs_bytes_hex != 0 )
{
printf( " *** WARNING: %d bytes were lost", xs_bytes_hex );
printf( " because the IFI return area in stored\n" );
printf( " *** procedure DSN8ED2 is too small" );
printf( " to accomodate this request.\n" );
printf( " *** ** Increase the IFI return area" );
printf( " (RETURN_LEN) in DSN8ED2 and then\n" );
printf( " *** recompile/relink/rebind before" );
printf( " resubmitting the request.\n" );
if( rc < RETWRN )
rc = RETWRN;
}
/*******************************************************************
* output any data from the error message buffer *
*******************************************************************/
if( sperind5 != -1 )
{
printf( " *** ERROR: The following diagnostics were returned by" );
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1127
printf( " stored procedure DSN8ED2.\n \n" );
for( j = 0; j < sp_err_buf.sp_err_blen; j++ )
printf( "%c",sp_err_buf.sp_err_txt[j] );
printf( "\n" );
if( rc < RETSEV )
rc = RETSEV;
}
} /* end of send_DB2_command_to_sp() */
/*********************************************************************
**********************************************************************
** Write out the DB2 command that has been built from input records **
**********************************************************************
*********************************************************************/
echo_DB2_command() /*proc*/
{
short int c; /* local ptr to command buffer*/
short int k,kk,l; /* counters and loop control */
c = 0;
/*******************************************************************
* calculate no. of full print lines the cmd uses and print them *
*******************************************************************/
kk = cmdbuf.cmdlen / (OUTLEN - 1);
for( k=1; k<=kk; k++ )
{
printf( " " );
for( l=0; l<(OUTLEN-1); l++ )
{
printf( "%c",cmdbuf.cmdtxt[c++] );
}
printf( "\n" );
}
/*******************************************************************
* calculate no. of partial print lines the cmd uses; print them *
*******************************************************************/
kk = cmdbuf.cmdlen % (OUTLEN - 1);
if( kk > 0 )
{
printf( " " );
for( k=1; k<=kk; k++ )
{
printf( "%c",cmdbuf.cmdtxt[c++] );
}
printf( "\n" );
}
} /* end of echo_DB2_command() */
/*********************************************************************
**********************************************************************
** Output the contents of the result set returned by the stored **
** procedure. **
**********************************************************************
*********************************************************************/
output_results_from_sp() /*proc*/
{
/*******************************************************************
* local initialization *
*******************************************************************/
for(j=0; j<(OUTLEN-1); j++) /* Blank the input array */
rs_data[j] = BLANK; /* Initialize result string */
rs_sequence = 0; /* Initialize data sequence */
/*******************************************************************
* associate a locator variable with the result *
*******************************************************************/
EXEC SQL ASSOCIATE LOCATOR /* Associate the result set */
(:DSN8ED2_rs_loc) /* locator with a host var. */
WITH PROCEDURE DSN8.DSN8ED2; /* */
if (SQLCODE != 0 ) /* If unsuccessful then */
{ /* - Say so */
sql_error( "*** Associate result set locator call unsuccessful." );
/* - Print the sqlcode */
1128 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
rc = RETSEV; /* - Flush remainder of proc */
} /* */
/*******************************************************************
* allocate the result set cursor *
*******************************************************************/
if( rc < RETSEV ) /* Or if okay so far then */
{ /* */
EXEC SQL ALLOCATE DSN8ED2_RS_CSR /* - Allocate a cursor to read*/
CURSOR FOR /* - Allocate a cursor to read*/
RESULT SET :DSN8ED2_rs_loc; /* the result set locator */
if (SQLCODE != 0 ) /* - If unsuccessful then */
{ /* - Say so */
sql_error( "*** Allocate result set cursor call unsuccessful." );
/* - Print the sqlcode */
rc = RETSEV; /* - Flush remainder of proc*/
} /* */
} /* */
/*******************************************************************
* fetch first row from the result set *
*******************************************************************/
if( rc < RETSEV ) /* Or if okay so far then */
{
EXEC SQL FETCH DSN8ED2_RS_CSR /* - Fetch first row (if any) */
INTO :rs_sequence, :rs_data; /* from the result set csr */
if (SQLCODE != 0 ) /* - If unsuccessful then */
{ /* - Say so */
sql_error("*** Priming fetch of result set cursor unsuccessful");
/* - Print the sqlcode */
rc = RETSEV; /* - Flush remainder of proc*/
} /* */
} /* */
/*******************************************************************
* output the contents of the result set *
*******************************************************************/
while(SQLCODE == 0 && rc < RETSEV) /* Or if okay so far then */
{ /* until all lines processed */
printf( " %s\n", rs_data ); /* -- Output current line */
/* */
EXEC SQL FETCH DSN8ED2_RS_CSR /* -- Get the next one from */
INTO :rs_sequence, :rs_data; /* the result set cursor */
} /* */
/*******************************************************************
* check for successful processing of result set *
*******************************************************************/
if (SQLCODE != 100 && rc < RETSEV) /* If unsuccessful then */
{ /* - Say so */
sql_error( "*** Fetch of result set cursor unsuccessful." );
/* - Print the sqlcode */
rc = RETSEV; /* - Set return code */
} /* */
} /* end of output_results_from_sp() */
/*********************************************************************
**********************************************************************
** SQL error handler **
**********************************************************************
*********************************************************************/
#pragma linkage(dsntiar, OS)
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1129
/*******************************************************************
* print the locator message *
*******************************************************************/
printf( " %.80s\n", locmsg );
/*******************************************************************
* format and print the SQL message *
*******************************************************************/
rc = dsntiar( &sqlca, &error_message, &lrecl );
if( rc == 0 )
for( j=0; j<=DATA_DIM; j++ )
printf( " %.80s\n", error_message.error_text[j] );
else
{
printf( " *** ERROR: DSNTIAR could not format the message\n" );
printf( " *** SQLCODE is %d\n",SQLCODE );
printf( " *** SQLERRM is \n" );
for( j=0; j<sqlca.sqlerrml; j++ )
printf( "%c", sqlca.sqlerrmc[j] );
printf( "\n" );
}
} /* end of sql_error */
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSN8ED2
Use the Instrumentation Facility Interface (IFI) to process a Db2 command which has been passed from
DSN8ED1, the requester program.
/******************************************************************** 00010000
* Module name = DSN8ED2 (sample program) * 00020000
* * 00030000
* Descriptive name = Stored procedure result set server program * 00040000
* * 00050000
* LICENSED MATERIALS - PROPERTY OF IBM * 00060000
* 5675-DB2 * 00070000
* (C) COPYRIGHT 1997, 2000 IBM CORP. ALL RIGHTS RESERVED. * 00080000
* * 00090000
* STATUS = VERSION 7 * 00100000
* * 00110000
* Function: * 00120000
* Use the Instrumentation Facility Interface (IFI) to process * 00130000
* a DB2 command which has been passed from DSN8ED1, the * 00140000
* requester program. Load the responses to a temporary DB2 * 00150000
* table and return them as a result set. * 00160000
* * 00170000
* Notes: * 00180000
* Dependencies = * 00190000
* 1. Must be linked and run under LE/370 * 00200000
* 2. Requires global temporary table DSN8.DSN8ED2_RS_TBL * 00202990
* (created by sample job DSNTEJ6T) * 00205980
* * 00210000
* Restrictions = * 00220000
* 1. The Instrumentation Facility Communication Area * 00230000
* (IFCA) contains information regarding the success * 00240000
* of the call and provides feedback. * 00250000
* This area must be maintained to include any changes * 00260000
* to the mapping macro DSNDIFCA. * 00270000
* * 00280000
* 2. A command may be no more than 4096 bytes. * 00290000
* * 00300000
* Module type = C program * 00310000
* Processor = * 00320000
* ADMF precompiler * 00330000
* C/370 * 00340000
* Module size = See linkedit output * 00350000
* Attributes = Not re-entrant nor re-usable * 00360000
* * 00370000
* Entry Point = CEESTART (LE/370) * 00380000
* Purpose = See function * 00390000
* Linkage = SIMPLE WITH NULLS * 00400000
* Invoked via EXEC SQL call * 00410000
* Input = Parameters explicitly passed to this function: * 00420000
* Symbolic label/name = ARGV[1] (puts inputcmd) * 00430000
1130 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* Description = DB2 command to be processed by IFI. * 00440000
* Input statements from this parameter * 00450000
* will be passed to the text_or_command * 00460000
* field of the output_area of the IFI * 00470000
* utility for processing. * 00480000
* * 00490000
* Output = Parameters explicitly returned: * 00500000
* Symbolic label/name = ARGV[2] (gets ifca_ret_hex) * 00510000
* - IFI return code, in hex * 00520000
* Symbolic label/name = ARGV[3] (gets ifca_res_hex) * 00530000
* - IFI reason code, in hex * 00540000
* Symbolic label/name = ARGV[4] (gets xs_bytes_hex) * 00550000
* - Excess bytes not returned, in hex * 00560000
* Symbolic label/name = ARGV[5] (gets errmsg_buf) * 00570000
* - Formatted SQL error messages * 00580000
* Symbolic label/name = ARGV[6] (gets indvar) * 00590000
* - DB2 indicator variables * 00600000
* * 00610000
* Output = Result set returned: * 00620000
* Result set cursor name = DSN8ED2_RS_CSR * 00630000
* - Formatted responses from IFI for input command * 00640000
* * 00650000
* Exit normal = * 00660000
* No errors were found in the passed DB2 command and no * 00670000
* errors occurred during processing. * 00680000
* * 00690000
* Normal messages = * 00700000
* * 00710000
* Exit-error = * 00720000
* Errors were found in the passed DB2 command or occurred * 00730000
* during processing. * 00740000
* * 00750000
* Return codes: n/a * 00760000
* * 00770000
* Error messages = see under output * 00780000
* * 00790000
* External references = * 00800000
* Routines/services = none * 00810000
* Data areas = none * 00820000
* Control blocks = none * 00830000
* * 00840000
* Pseudocode = * 00850000
* DSN8ED2: Main * 00860000
* - get the passed DB2 command. * 00870000
* - calculate the return area size for command requests. * 00880000
* - allocate the requested return area. * 00890000
* - format the output area with the requested command. * 00900000
* - issue the command request to IFI. * 00910000
* - create the temporary table to hold the result set. * 00920000
* - call sql_error if an unexpected SQLCODE is encountered * 00930000
* - extract the responses from the IFI return buffer and * 00940000
* insert them to the result set table. * 00950000
* - call sql_error if an unexpected SQLCODE is encountered * 00960000
* - open the cursor to the result set table and exit. * 00970000
* - call sql_error if an unexpected SQLCODE is encountered * 00980000
* End DSN8ED2 * 00990000
* * 01000000
* sql_error * 01010000
* - invoke DSNTIAR to format the current SQL code and put the * 01020000
* messages to output parameter ARGV[5]. * 01030000
* - if DSNTIAR cannot detail the code, put the SQLCODE and the * 01040000
* SQLERRM to output parameter ARGV[5]. * 01050000
* End sql_error * 01060000
********************************************************************/ 01070000
01080000
01090000
/********************** C library definitions ***********************/ 01100000
#pragma runopts( plist(mvs) ) 01110000
#include <stdio.h> 01120000
#include <stdlib.h> 01130000
#include <string.h> 01140000
#pragma linkage( dsnwli,OS ) 01150000
01160000
/**************************** Constants *****************************/ 01170000
#define BLANK ' ' /* Buffer padding */ 01180000
#define BUFROWLN 80 /* Length of a report line */ 01190000
#define DATA_DIM 10 /* Number of message lines */ 01200000
#define HYPHEN '-' /* Hyphen */ 01210000
#define LINEFEED '\n' /* Linefeed character */ 01220000
#define NULLCHAR '\0' /* Null character */ 01230000
#define RETSEV 12 /* Severe error return code */ 01240000
#define RETURN_LEN 8320 /* Length of IFI return buffer*/ 01250000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1131
01260000
/********************** Program Argument List ***********************/ 01270000
struct inp { /* Arg1 (in): Command stmt */ 01280000
short int incmlen; /* - Input stmt length */ 01290000
char incmtxt[4096]; /* - Input stmt text */ 01300000
} inputcmd; /* */ 01310000
struct inp *inpptr; /* Pointer to input struct */ 01320000
01330000
long int ifca_ret_hex; /* Arg2 (out): IFI return code*/ 01340000
long int ifca_res_hex; /* Arg3 (out): IFI reason code*/ 01350000
01360000
long int xs_bytes_hex; /* Arg4 (out): # records lost */ 01370000
01380000
char errmsg[DATA_DIM+1][BUFROWLN]; 01390000
/* Arg5 (out): error messages */ 01400000
01410000
short int locind[5]; /* Arg6 (out): indicator vars */ 01420000
01430000
/************************ Working variables *************************/ 01440000
char *parg1[]; /* Pointer to argument 1 */ 01450000
int *parg2; /* Pointer to argument 2 */ 01460000
int *parg3; /* Pointer to argument 3 */ 01470000
int *parg4; /* Pointer to argument 4 */ 01480000
char *parg5[][BUFROWLN]; /* Pointer to argument 5 */ 01490000
short int *parg6; /* Pointer to argument 6 */ 01500000
01510000
long int rc, lastrc; /* Return codes */ 01520000
01530000
/************************ DB2 Host Variables ************************/ 01540000
EXEC SQL BEGIN DECLARE SECTION; 01550000
long int rs_sequence; /* Result set data sequence */ 01560000
char rs_data[81]; /* Result set data buffer */ 01570000
/* - length is BUFROWLN+1 for */ 01580000
/* C NUL-terminator byte) */ 01590000
EXEC SQL END DECLARE SECTION; 01600000
01610000
/******************** DB2 SQL Communication Area ********************/ 01620000
EXEC SQL INCLUDE SQLCA; 01630000
01640000
/******************** DB2 SQL Cursor Declarations *******************/ 01650000
EXEC SQL DECLARE DSN8ED2_RS_CSR 01660000
CURSOR WITH RETURN WITH HOLD FOR 01670000
SELECT RS_SEQUENCE, RS_DATA 01680000
FROM DSN8.DSN8ED2_RS_TBL /* <- Created in job DSNTEJ6T */ 01690000
ORDER BY RS_SEQUENCE; 01700000
01710000
/********************************************************************/ 01720000
/*************************** main routine ***************************/ 01730000
/********************************************************************/ 01740000
int main( int argc, char *argv[] ) /* Argument count and list */ 01750000
{ 01760000
/*************************** Constants ****************************/ 01770000
01780000
char eye[4] /* Const for IFI eye catcher */ 01790000
= {'I','F','C','A'}; 01800000
char loc[4] /* Const for IFI location */ 01810000
= {'L','O','C','2'}; 01820000
01830000
/*********************** Working variables ************************/ 01840000
01850000
short int numfull; /* No. of lines in area passed*/ 01860000
/* from IFI that have BUFROWLN*/ 01870000
/* or more bytes */ 01880000
short int partrow; /* No. of lines in area passed*/ 01890000
/* from IFI that have less */ 01900000
/* than BUFROWLN bytes */ 01910000
01920000
short int i, j, k; /* Loop control vars */ 01930000
01940000
char *curbyte; /* Pointer to current byte in */ 01950000
/* return area */ 01960000
01970000
short int len_bin; /* Length of buffer, in binary*/ 01980000
char lenbyt1; /* 1st byte of length */ 01990000
char lenbyt2; /* 2nd byte of length */ 02000000
02010000
02020000
/*********************** IFI Argument List ************************/ 02030000
02040000
char function[9]; /* First parm for IFI call */ 02050000
02060000
/******************************************************************* 02070000
1132 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* IFCA - (Instrumentation Facility Communication Area) contains * 02080000
* information regarding the success of the call to IFI and * 02090000
* provides feedback information to the application program. * 02100000
* * 02110000
* WARNING: This area must be maintained to include any changes to * 02120000
* the mapping macro DSNDIFCA. * 02130000
*******************************************************************/ 02140000
02150000
typedef struct { /* Second parm for IFI call */ 02160000
short int lngth; /* Length of the IFCA, */ 02170000
/* including length field */ 02180000
short int unused1; /* Reserved */ 02190000
char eye_catcher[4]; /* Valid eye catcher of IFCA */ 02200000
/* used to verify IFCA block */ 02210000
char owner_id[4]; /* Used to establish ownership*/ 02220000
/* of an OPN destination */ 02230000
long int ifcarc1; /* Rtrn code for IFC API call */ 02240000
long int ifcarc2; /* Reason cd for IFC API call */ 02250000
long int bytes_moved; /* Bytes of recrd rtrnd by IFI*/ 02260000
long int excess_bytes; /* Bytes that did not fit */ 02270000
long int opn_writ_seq_num; /* Last OPN writer sequ numbr */ 02280000
/* rtrnd for a READA function*/ 02290000
long int num_recds_lost; /* Records lost indicator */ 02300000
char opn_name_for_reada[4];/* OPN nm used for READA requ */ 02310000
struct { /* Area with up to 8 OPN names*/ 02320000
short int opn_lngth; /* Length+4 of OPN names rtrnd*/ 02330000
short int unused2; /* Reserved */ 02340000
char array_opn_names[4][8]; 02350000
/* Area for OPN names returned*/ 02360000
} opn_names_area; 02370000
struct { /* Area with up to 8 trace nos*/ 02380000
short int trace_lngth; /* Length+4 of trace nos rtrnd*/ 02390000
short int unused3; /* Reserved */ 02400000
char array_trace_nos[2][8]; 02410000
/* Area for trace nos returned*/ 02420000
} trace_nos_area; 02430000
struct { /* Diagnosticd area */ 02440000
short int diagnos_lngth; /* Diagnostics length */ 02450000
short int unused4; /* Reserved */ 02460000
char diagnos_data[80]; /* Diagnostics data */ 02470000
} diagnos_area; 02480000
} ifca; /****** end IFCA typedef ******/ 02490000
02500000
ifca *pi; /* Pointer to IFCA structure */ 02510000
02520000
typedef struct { /* Third parm for IFI call */ 02530000
short int lngth; /* Length+4 of text or command*/ 02540000
short int unused; /* Reserved */ 02550000
char text_or_command[254]; /* Actual cmd or record text */ 02560000
} output_area; 02570000
02580000
output_area *po; /* Pointer to IFI output area */ 02590000
02600000
typedef struct { /* Fourth parm for IFI call */ 02610000
long int lngth; /* Length+4 of IFI return area*/ 02620000
char rtrn_buff[RETURN_LEN];/* IFI return area */ 02630000
} return_area; 02640000
02650000
return_area *pr; /* Pointer to IFI return area */ 02660000
02670000
/******************************************************************* 02680000
* initialize working variables * 02690000
*******************************************************************/ 02700000
rc = 0; /* Initialize return code */ 02710000
lastrc = 0; /* Initialize return code */ 02720000
02730000
for( i=0; i<DATA_DIM+1; i++ ) /* clear error message buffer */ 02740000
for( j=0; j<BUFROWLN; j++ ) 02750000
errmsg[i][j] = BLANK; 02760000
02770000
/******************************************************************* 02780000
* get input parameter (command for IFI) from caller * 02790000
*******************************************************************/ 02800000
parg1[1] = argv[1]; /* Command text from caller */ 02810000
curbyte = parg1[1]; /* Get pointer to input struct*/ 02820000
02830000
/******************************************************************* 02840000
* determine the length of the command text * 02850000
*******************************************************************/ 02860000
inputcmd.incmlen = 0; 02870000
i = 0; 02880000
while( *(curbyte) != NULLCHAR && i < 4096 ) 02890000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1133
{ 02900000
inputcmd.incmtxt[i] = *curbyte; 02910000
i++; 02920000
curbyte++; 02930000
inputcmd.incmlen++; 02940000
} 02950000
02960000
/******************************************************************* 02970000
* initialize the IFI parameters * 02980000
*******************************************************************/ 02990000
strncpy( function,"COMMAND \0",9 ); /* Set constant */ 03000000
03010000
pi = malloc( sizeof(ifca) ); /* Point to IFCA structure */ 03020000
pi->lngth = sizeof(ifca); /* Note length of IFCA area */ 03030000
for(i=0; i<4; i++ ) 03040000
{ 03050000
pi->eye_catcher[i] = eye[i]; /* Initialize eye catcher */ 03060000
pi->owner_id[i] = loc[i]; /* DB2 Loc: 1=Local, 2=Remote */ 03070000
} 03080000
03090000
pr = malloc( sizeof(return_area) ); /* Point to IFI return area */ 03100000
for( i=0; i<RETURN_LEN; i++ ) 03110000
pr->rtrn_buff[i] = BLANK; /* Clear the return buffer */ 03120000
pr->lngth = RETURN_LEN; /* Length of return buffer */ 03130000
03140000
po = malloc( sizeof(output_area) ); /* Point to IFI command area */ 03150000
po->lngth = inputcmd.incmlen+4; /* Note length of command text*/ 03160000
for( i=0; i<254; i++ ) /* Copy in command */ 03170000
po->text_or_command[i] = inputcmd.incmtxt[i]; 03180000
03190000
/******************************************************************* 03200000
* make the IFI call via the DSNWLI macro * 03210000
*******************************************************************/ 03220000
dsnwli( function,pi,pr,po ); 03230000
03240000
/******************************************************************* 03250000
* copy IFI command status codes to output parms * 03260000
*******************************************************************/ 03270000
ifca_ret_hex = pi->ifcarc1; /* IFI Return code in binary */ 03280000
ifca_res_hex = pi->ifcarc2; /* IFI Reason code in binary */ 03290000
xs_bytes_hex = pi->excess_bytes; /* Bytes that did not fit */ 03300000
03310000
/******************************************************************* 03320000
* Extract records from the IFI return area and place them in a * 03330000
* table for transmission to the caller via a result set * 03340000
*******************************************************************/ 03350000
if( pi->bytes_moved != 0 ) /* If data was returned by IFI*/ 03360000
{ 03370000
/***************************************************************** 03380000
* First, clear any residue from the result set table * 03390000
*****************************************************************/ 03400000
EXEC SQL DELETE 03439990
FROM DSN8.DSN8ED2_RS_TBL; 03469980
if( SQLCODE != 0 /* 0 because everything is ok */ 03499970
& SQLCODE != +88 ) /* +88 because all rows del'd */ 03529960
sql_error( "*** SQL error when clearing temp table ..." ); 03559950
03620000
rs_sequence = 0; /* Init result set sequence no*/ 03630000
for( k=0; k<BUFROWLN; k++ ) /* Clear result set data var */ 03640000
rs_data[k] = BLANK; 03650000
03660000
/***************************************************************** 03670000
* The IFI return buffer contains one or more variable length * 03680000
* records. Each record consists of a 4-byte length component * 03690000
* followed by a text component. The length component contains * 03700000
* the length of the text component plus 4 to account for its * 03710000
* own length. * 03720000
****************************************************************** 03730000
* Extract the length of the 1st record in the buffer and sub- * 03740000
* tract 4 bytes to obtain the length of just the text portion. * 03750000
*****************************************************************/ 03760000
curbyte = &( pr->rtrn_buff[0] ); /* Point to 1st byte in buffer*/ 03770000
lenbyt1 = *(curbyte); /* Set 1st byte of length */ 03780000
lenbyt2 = *(curbyte+1); /* Set 2nd byte of length */ 03790000
03800000
len_bin = ( (short int)lenbyt1 ) * 10 + ( (short int)lenbyt2 ); 03810000
len_bin = len_bin - 4; /* Discount size of length fld*/ 03820000
03830000
/***************************************************************** 03840000
* For each IFI record returned, create one or more records of * 03850000
* length BUFROWLN and insert them to the result set table * 03860000
*****************************************************************/ 03870000
1134 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
while( ( rc < RETSEV ) && (pi->bytes_moved - len_bin) > 2 ) 03880000
{ 03890000
curbyte = curbyte + 4; /* Update position in buffer */ 03900000
03910000
if( ((short int)( curbyte - &(pr->rtrn_buff[0]) ) + len_bin - 1) 03920000
> pi->bytes_moved ) 03930000
break; /* At end of buffer */ 03940000
03950000
numfull = len_bin / BUFROWLN; /* No. rows of BUFROWLN bytes */ 03960000
partrow = len_bin % BUFROWLN; /* No. of bytes leftover */ 03970000
03980000
/*************************************************************** 03990000
* Move all complete lines * 04000000
***************************************************************/ 04010000
if( numfull > 0 ) 04020000
for( j=0; j<numfull; j++ ) 04030000
{ 04040000
for( i=0; i<BUFROWLN; i++ ) /* Clear result set tbl buffer*/ 04050000
rs_data[i] = BLANK; 04060000
for( i=0; i<BUFROWLN; i++ ) 04070000
{ 04080000
rs_data[i] = *curbyte; /* Build result set table rec */ 04090000
curbyte++; /* Bump ptr into IFI rtrn buff*/ 04100000
} 04110000
04120000
rs_sequence++; /* Bump result set tbl sequ no*/ 04130000
EXEC SQL INSERT /* Insert to the table */ 04140000
INTO DSN8.DSN8ED2_RS_TBL 04150000
( RS_SEQUENCE,RS_DATA ) 04160000
VALUES(:rs_sequence,:rs_data ); 04170000
if( SQLCODE != 0 ) 04180000
sql_error( "*** SQL error when inserting full line ..." ); 04190000
} 04200000
04210000
/*************************************************************** 04220000
* Move leftover bytes to one last result set table record * 04230000
***************************************************************/ 04240000
if( rc < RETSEV && partrow > 0 ) 04250000
{ 04260000
for( i=0; i<BUFROWLN; i++ ) /* Clear result set tbl buffer*/ 04270000
rs_data[i] = BLANK; 04280000
for( i=0; i<partrow; i++ ) 04290000
{ 04300000
rs_data[i] = *curbyte; /* Build result set table rec */ 04310000
curbyte++; /* Bump ptr into IFI rtrn buff*/ 04320000
} 04330000
rs_data[i-1] = BLANK; /* Discard linefeed char */ 04340000
04350000
rs_sequence++; /* Bump result set tbl sequ no*/ 04360000
04370000
EXEC SQL INSERT /* Insert to the table */ 04380000
INTO DSN8.DSN8ED2_RS_TBL 04390000
( RS_SEQUENCE,RS_DATA ) 04400000
VALUES(:rs_sequence,:rs_data ); 04410000
if( SQLCODE != 0 ) 04420000
sql_error( "*** SQL error when inserting partial line ..." );04430000
} /* End-move partial line */ 04440000
04450000
/*************************************************************** 04460000
* Advance to next record in the IFI buffer, extract its length,* 04470000
* and subtract 4 bytes to get length of text portion * 04480000
***************************************************************/ 04490000
lenbyt1 = *(curbyte); /* Set 1st byte of length */ 04500000
lenbyt2 = *(curbyte+1); /* Set 2nd byte of length */ 04510000
04520000
len_bin = ( (short int)lenbyt1) * 10 + ((short int)lenbyt2 ); 04530000
len_bin = len_bin - 4; /* Discount for length field */ 04540000
04550000
} /* End of copying IFI return text to result set table */ 04560000
04570000
/***************************************************************** 04580000
* Open the cursor to the result set table on the way out * 04590000
*****************************************************************/ 04600000
if( rc < RETSEV ) 04610000
{ 04620000
EXEC SQL OPEN DSN8ED2_RS_CSR; 04630000
if( SQLCODE != 0 ) 04640000
sql_error( "*** SQL error when opening result set cursor ...");04650000
} 04660000
04670000
} /* End of if data was returned by IFI */ 04680000
04690000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1135
/******************************************************************* 04700000
* Set output arguments and DB2 locator variables * 04710000
*******************************************************************/ 04720000
parg2 = (int *)argv[2]; /* locate and recast 2nd arg */ 04730000
*parg2 = ifca_ret_hex; /* assign it ifca return cd */ 04740000
locind[1] = 0; /* tell DB2 to transmit it */ 04750000
04760000
parg3 = (int *)argv[3]; /* locate and recast 3rd arg */ 04770000
*parg3 = ifca_res_hex; /* assign it ifca reason cd */ 04780000
locind[2] = 0; /* tell DB2 to transmit it */ 04790000
04800000
parg4 = (int *)argv[4]; /* locate and recast 4th arg */ 04810000
*parg4 = xs_bytes_hex; /* and assign it bytes lost */ 04820000
locind[3] = 0; /* tell DB2 to transmit it */ 04830000
04840000
if( errmsg[0][0] == BLANK ) /* if no error message exists*/ 04850000
locind[4] = -1; /* -tell DB2 not to send one */ 04860000
else /* otherwise copy it over and*/ 04870000
{ /* tell DB2 to transmit it */ 04880000
parg5[0][0] = argv[5]; /* -locate the 5th func arg */ 04890000
curbyte = parg5[0][0]; /* -set helper pointer */ 04900000
for( i=0; i<DATA_DIM+1; i++ ) /* -parse a row, looking for */ 04910000
{ /* the end of its msg text */ 04920000
j = 0; 04930000
while( errmsg[i][j] != NULLCHAR && j < BUFROWLN ) 04940000
{ 04950000
*curbyte = errmsg[i][j++]; /* -copy nonnull bytes */ 04960000
curbyte++; 04970000
} 04980000
errmsg[i][j] = LINEFEED; /* -add linefd to end of row */ 04990000
} /* End of for( i=0; i<DATA_DIM+1; i++ ) */ 05000000
05010000
*curbyte = NULLCHAR; /* -null-terminate the buffer*/ 05020000
locind[4] = 0; /* -tell DB2 to transmit it */ 05030000
} /* End of if( errmsg[0][0] != BLANK ) */ 05040000
05050000
parg6 = (short int *)argv[6]; /* locate and recast 6th arg */ 05060000
for( j=0; j<5; j++ ) /* copy over null-ind array */ 05070000
{ 05080000
*parg6 = locind[j]; 05090000
parg6++; 05100000
} /* return control to caller */ 05110000
05120000
} /* end of main */ 05130000
05140000
/********************************************************************* 05150000
* SQL error handler * 05160000
*********************************************************************/ 05170000
#pragma linkage(dsntiar, OS) 05180000
05190000
sql_error( char locmsg[] ) 05200000
{ 05210000
05220000
/* DSNTIAR message structure */ 05230000
struct error_struct { 05240000
short int error_len; 05250000
char error_text[DATA_DIM][BUFROWLN]; 05260000
} error_message = {DATA_DIM * BUFROWLN}; 05270000
05280000
extern short int dsntiar( struct sqlca *sqlca, 05290000
struct error_struct *msg, 05300000
int *len ); 05310000
05320000
char *curbyte; /* Pointer to current byte in */ 05330000
/* error_message */ 05340000
05350000
short int tiar_rc; /* DSNTIAR Return code */ 05360000
int i; /* Loop control */ 05370000
static int lrecl = BUFROWLN; /* Width of message lines */ 05380000
05390000
/******************************************************************* 05400000
* indicate that a fatal error has occurred * 05410000
*******************************************************************/ 05420000
rc = RETSEV; 05430000
05440000
/******************************************************************* 05450000
* copy locator message to the error message return buffer * 05460000
*******************************************************************/ 05470000
strcpy( errmsg[0],locmsg ); 05480000
05490000
/******************************************************************* 05500000
* format the SQL message and move it to the err msg rtn buffer * 05510000
1136 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
*******************************************************************/ 05520000
tiar_rc = dsntiar( &sqlca, &error_message, &lrecl ); 05530000
05540000
if( tiar_rc == 0 ) 05550000
for( i=0; i<DATA_DIM; i++ ) 05560000
{ 05570000
strncpy( errmsg[i+1],error_message.error_text[i],BUFROWLN ); 05580000
} 05590000
else 05600000
{ 05610000
strcpy( errmsg[1],"DSNTIAR could not detail the SQL error" ); 05620000
strcpy( errmsg[2],"*** SQLCODE is " ); 05630000
strcat( errmsg[3],(char *)SQLCODE ); 05640000
strcpy( errmsg[4],"*** SQLERRM is " ); 05650000
for( i=0; i<sqlca.sqlerrml; i++ ) 05660000
errmsg[5][i],sqlca.sqlerrmc[i]; 05670000
} 05680000
05690000
} /* end of sql_error */ 05700000
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSN8EC1
Demonstrates how a Db2 stored procedure can use IMS Open Database Access (ODBA) to connect to IMS
DBCTL and access IMS data.
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1137
* Attributes = Re-entrant * 00005000
* * 00005100
* * 00005200
* Entry Point = DSN8EC1 * 00005300
* Purpose = See function * 00005400
* Linkage = Standard MVS program invocation * 00005500
* Input = Parameters explicitly passed to this function: * 00005600
* TDBCTLID ...... PIC X(8) * 00005700
* - IMS subsystem id * 00005800
* COMMAND ....... PIC X(8) * 00005900
* - Action to perform: ADD, UPD, DIS, DEL * 00006000
* LAST-NAME ..... PIC X(10) * 00006100
* FIRST-NAME .... PIC X(10) * 00006200
* EXTENSION ..... PIC X(10) * 00006300
* ZIP-CODE ...... PIC X(7) * 00006400
* * 00006500
* Output = Parameters explicitly passed by this function * 00006600
* COMMAND ....... PIC X(8) * 00006700
* - Action performed: ADD, UPD, DIS, DEL * 00006800
* LAST-NAME ..... PIC X(10) * 00006900
* FIRST-NAME .... PIC X(10) * 00007000
* EXTENSION ..... PIC X(10) * 00007100
* ZIP-CODE ...... PIC X(7) * 00007200
* AIBRETRN ...... PIC S9(9) COMP * 00007300
* - Return code from IMS AIB call * 00007400
* AIBREASN ...... PIC S9(9) COMP * 00007500
* - Reason code from IMS AIB call * 00007600
* ERROR-CALL .... PIC X(4) * 00007700
* - DL/I command that failed * 00007800
* * 00007900
* Exit-Normal = Return Code 0 Normal Completion * 00008000
* * 00008100
* Exit-Error = Return Code 0 Abnormal Completion * 00008200
* * 00008300
* Error Messages = None: Errors are signaled by means of * 00008400
* SQLCODEs and DL/I codes returned to the * 00008500
* client. * 00008600
* * 00008700
* External References = * 00008800
* Routines/Services = * 00008900
* AERTDLI - DL/I interface for ODBA * 00009000
* * 00009100
* Data areas = None * 00009200
* * 00009300
* Control Blocks = * 00009400
* AIB - DL/I Application Interface Block * 00009500
* * 00009600
* Tables = None * 00009700
* * 00009800
* * 00009900
* Change Activity = None * 00010000
* * 00010100
* * 00010200
* *Pseudocode* * 00010300
* * 00010400
* PROCEDURE A00000-ODBA-SP * 00010500
* Call B10000-ALLOCATE-AIB to allocate the IMS AIB * 00010600
* Call B20000-PREPARE-REQUEST to format input from the client* 00010700
* Call B30000-PROCESS-REQUEST to access data on IMS * 00010800
* Call C31000-ADD-ENTRY if client passed ADD request * 00010900
* Call D31100-INSERT-TO-DB to process IMS ISRT * 00011000
* Call C32000-UPDATE-ENTRY if client passed UPD request * 00011100
* Call D32100-GET-HOLD-UNIQUE-FROM-DB for IMS GHU * 00011200
* Call D32200-REPLACE-IN-DB for IMS REPL * 00011300
* Call C33000-DELETE-ENTRY if client passed DEL request * 00011400
* Call D32100-GET-HOLD-UNIQUE-FROM-DB for IMS GHU * 00011500
* Call D33200-DELETE-FROM-DB for IMS DLET * 00011600
* Call C34000-DISPLAY-ENTRY if client passed DIS request* 00011700
* Call D34100-GET-UNIQUE-FROM-DB for IMS GU * 00011800
* Call B40000-DEALLOCATE-AIB to pend unit of work on IMS * 00011900
* * 00012000
*---------------------------------------------------------------* 00012100
00012200
00012300
00012400
ENVIRONMENT DIVISION. 00012500
CONFIGURATION SECTION. 00012600
SOURCE-COMPUTER. IBM-370. 00012700
OBJECT-COMPUTER. IBM-370. 00012800
00012900
INPUT-OUTPUT SECTION. 00013000
00013100
1138 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
DATA DIVISION. 00013200
WORKING-STORAGE SECTION. 00013300
00013400
***************************************************************** 00013500
* DL/I-related declarations 00013600
***************************************************************** 00013700
* Application Interface Block(AIB) mapping 00013800
01 AIB. 00013900
02 AIBID PIC X(8). 00014000
02 AIBLEN PIC 9(9) USAGE BINARY. 00014100
02 AIBSFUNC PIC X(8). 00014200
02 AIBRSNM1 PIC X(8). 00014300
02 AIBRSNM2 PIC X(8). 00014400
02 AIBRESV1 PIC X(8). 00014500
02 AIBOALEN PIC 9(9) USAGE BINARY. 00014600
02 AIBOAUSE PIC 9(9) USAGE BINARY. 00014700
02 AIBRESV2 PIC X(12). 00014800
02 AIBRETRN PIC 9(9) USAGE BINARY. 00014900
02 AIBREASN PIC 9(9) USAGE BINARY. 00015000
02 AIBRESV3 PIC X(4). 00015100
02 AIBRESA1 USAGE POINTER. 00015200
02 AIBRESA2 USAGE POINTER. 00015300
02 AIBRESA3 USAGE POINTER. 00015400
02 AIBRESV4 PIC X(40). 00015500
02 AIBSAVE OCCURS 18 TIMES 00015600
USAGE POINTER. 00015700
02 AIBTOKN OCCURS 6 TIMES 00015800
USAGE POINTER. 00015900
02 AIBTOKC PIC X(16). 00016000
02 AIBTOKV PIC X(16). 00016100
02 AIBTOKA OCCURS 2 TIMES 00016200
PIC 9(9) USAGE BINARY. 00016300
00016400
* Segment Search Argument (SSA) 00016500
01 SSA. 00016600
02 SEGMENT-NAME PIC X(8) VALUE 'A1111111'. 00016700
02 SEG-KEY-NAME PIC X(11) VALUE '(A1111111 ='. 00016800
02 SSA-KEY PIC X(10). 00016900
02 FILLER PIC X VALUE ')'. 00017000
00017100
* Initializers 00017200
77 SSA1 PIC X(9) VALUE 'A1111111 '. 00017300
77 APSBNME PIC X(8) VALUE 'DFSIVP6'. 00017400
77 DPCBNME PIC X(8) VALUE 'TELEPCB1'. 00017500
77 VAIBID PIC X(8) VALUE 'DFSAIB '. 00017600
77 SFPREP PIC X(4) VALUE 'PREP'. 00017700
00017800
* DL/I function codes 00017900
77 GET-UNIQUE PIC X(4) VALUE 'GU '. 00018000
77 GET-HOLD-UNIQUE PIC X(4) VALUE 'GHU '. 00018100
77 GET-NEXT PIC X(4) VALUE 'GN '. 00018200
77 ISRT PIC X(4) VALUE 'ISRT'. 00018300
77 DLET PIC X(4) VALUE 'DLET'. 00018400
77 REPL PIC X(4) VALUE 'REPL'. 00018500
77 APSB PIC X(4) VALUE 'APSB'. 00018600
77 DPSB PIC X(4) VALUE 'DPSB'. 00018700
77 APPERR PIC X(3) VALUE '264'. 00018800
77 INVCMD PIC X(3) VALUE '440'. 00018900
77 NOKEY PIC X(3) VALUE '218'. 00019000
00019100
***************************************************************** 00019200
* I/O area for datacase handling 00019300
***************************************************************** 00019400
01 IOAREA. 00019500
02 IO-BLANK PIC X(37) VALUE SPACES. 00019600
02 IO-DATA REDEFINES IO-BLANK. 00019700
03 IO-LAST-NAME PIC X(10). 00019800
03 IO-FIRST-NAME PIC X(10). 00019900
03 IO-EXTENSION PIC X(10). 00020000
03 IO-ZIP-CODE PIC X(7). 00020100
02 IO-FILLER PIC X(3) VALUE SPACES. 00020200
02 IO-COMMAND PIC X(8) VALUE SPACES. 00020300
00020400
01 DB2IN-COMMAND. 00020500
02 DB2IW-COMMAND PIC X(8). 00020600
02 DB2TEMP-COMMAND REDEFINES DB2IW-COMMAND. 00020700
03 DB2TEMP-IOCMD PIC X(3). 00020800
03 FILLER PIC X(5). 00020900
00021000
***************************************************************** 00021100
* Miscellaneous variables 00021200
***************************************************************** 00021300
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1139
77 TEMP-ONE PICTURE X(8) VALUE SPACES. 00021400
77 TEMP-TWO PICTURE X(8) VALUE SPACES. 00021500
77 REPLY PICTURE X(16). 00021600
00021700
01 FLAGS. 00021800
02 SET-DATA-FLAG PIC X VALUE '0'. 00021900
88 NO-SET-DATA VALUE '1'. 00022000
02 TADD-FLAG PIC X VALUE '0'. 00022100
88 PROCESS-TADD VALUE '1'. 00022200
00022300
01 COUNTERS. 00022400
02 L-SPACE-CTR PIC 9(2) COMP VALUE 0. 00022500
00022600
01 RUN-STATUS PIC X(4). 00022700
88 NOT-OKAY VALUE 'BAD'. 00022800
88 OKAY VALUE 'GOOD'. 00022900
00023000
00023100
00023200
LINKAGE SECTION. 00023300
00023400
***************************************************************** 00023500
* Data area for DB2 Stored Procedures input/output 00023600
***************************************************************** 00023700
01 DB2IO-TDBCTLID PIC X(8). 00023800
01 DB2IO-COMMAND PIC X(8). 00023900
01 DB2IO-LAST-NAME PIC X(10). 00024000
01 DB2IO-FIRST-NAME PIC X(10). 00024100
01 DB2IO-EXTENSION PIC X(10). 00024200
01 DB2IO-ZIP-CODE PIC X(7). 00024300
00024400
***************************************************************** 00024500
* Data area for DB2 Stored Procedures output 00024600
***************************************************************** 00024700
01 DB2OUT-AIBRETRN PIC S9(9) COMP. 00024800
01 DB2OUT-AIBREASN PIC S9(9) COMP. 00024900
01 DC-ERROR-CALL PIC X(4). 00025000
00025100
00025200
***************************************************************** 00025300
* Stored Procedure parameter list 00025400
***************************************************************** 00025500
PROCEDURE DIVISION 00025600
USING DB2IO-TDBCTLID, 00025700
DB2IO-COMMAND, 00025800
DB2IO-LAST-NAME, 00025900
DB2IO-FIRST-NAME, 00026000
DB2IO-EXTENSION, 00026100
DB2IO-ZIP-CODE, 00026200
DB2OUT-AIBRETRN, 00026300
DB2OUT-AIBREASN, 00026400
DC-ERROR-CALL. 00026500
00026600
00026700
***************************************************************** 00026800
* Main Driver: Process data passed by client and apply the data 00026900
* to the IMS IVP phone book database, DFSIVD1. 00027000
***************************************************************** 00027100
A00000-ODBA-SP. 00027200
MOVE 'GOOD' TO RUN-STATUS. 00027300
PERFORM B10000-ALLOCATE-AIB. 00027400
IF OKAY THEN 00027500
PERFORM B20000-PREPARE-REQUEST. 00027600
IF OKAY THEN 00027700
PERFORM B30000-PROCESS-REQUEST. 00027800
IF OKAY THEN 00027900
PERFORM B40000-DEALLOCATE-AIB. 00028000
00028100
STOP RUN. 00028200
00028300
00028400
***************************************************************** 00028500
* Initialize and allocate the Application Interface Block 00028600
***************************************************************** 00028700
B10000-ALLOCATE-AIB. 00028800
INITIALIZE AIB. 00028900
SET AIBRESA1 TO NULLS. 00029000
SET AIBRESA2 TO NULLS. 00029100
SET AIBRESA3 TO NULLS. 00029200
MOVE ZEROES to AIBRETRN. 00029300
MOVE ZEROES to AIBREASN. 00029400
MOVE VAIBID to AIBID. 00029500
1140 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
MOVE LENGTH OF AIB to AIBLEN. 00029600
MOVE SPACES to IOAREA. 00029700
MOVE LENGTH OF IOAREA to AIBOALEN. 00029800
MOVE SPACES TO AIBSFUNC. 00029900
MOVE APSBNME to AIBRSNM1. 00030000
MOVE DB2IO-TDBCTLID to AIBRSNM2. 00030100
00030200
* Allocate the PSB for the AIB 00030300
CALL 'AERTDLI' USING APSB, AIB. 00030400
00030500
IF AIBRETRN EQUAL ZEROES THEN 00030600
MOVE 0 TO SET-DATA-FLAG 00030700
MOVE 0 TO TADD-FLAG 00030800
ELSE 00030900
MOVE 'BAD' TO RUN-STATUS 00031000
MOVE AIBRETRN TO DB2OUT-AIBRETRN 00031100
MOVE AIBREASN TO DB2OUT-AIBREASN. 00031200
00031300
00031400
***************************************************************** 00031500
* Prepare data passed from client for processing by ODBA 00031600
***************************************************************** 00031700
B20000-PREPARE-REQUEST. 00031800
00031900
* Check the leading space in input command and trim it off 00032000
INSPECT DB2IO-COMMAND 00032100
TALLYING L-SPACE-CTR FOR LEADING SPACE 00032200
REPLACING LEADING SPACE BY '*'. 00032300
IF L-SPACE-CTR > 0 THEN 00032400
UNSTRING DB2IO-COMMAND 00032500
DELIMITED BY ALL '*' 00032600
INTO TEMP-ONE TEMP-TWO 00032700
MOVE TEMP-TWO TO DB2IO-COMMAND 00032800
MOVE 0 TO L-SPACE-CTR 00032900
MOVE SPACES TO TEMP-TWO. 00033000
00033100
* Check the leading space in input LAST NAME and trim it off 00033200
INSPECT DB2IO-LAST-NAME 00033300
TALLYING L-SPACE-CTR FOR LEADING SPACE 00033400
REPLACING LEADING SPACE BY '*'. 00033500
IF L-SPACE-CTR > 0 THEN 00033600
UNSTRING DB2IO-LAST-NAME 00033700
DELIMITED BY ALL '*' 00033800
INTO TEMP-ONE TEMP-TWO 00033900
MOVE TEMP-TWO TO DB2IO-LAST-NAME 00034000
MOVE 0 TO L-SPACE-CTR 00034100
MOVE SPACES TO TEMP-TWO. 00034200
00034300
* Check the leading space in input FIRST NAME and trim it off 00034400
INSPECT DB2IO-FIRST-NAME 00034500
TALLYING L-SPACE-CTR FOR LEADING SPACE 00034600
REPLACING LEADING SPACE BY '*'. 00034700
IF L-SPACE-CTR > 0 THEN 00034800
UNSTRING DB2IO-FIRST-NAME 00034900
DELIMITED BY ALL '*' 00035000
INTO TEMP-ONE TEMP-TWO 00035100
MOVE TEMP-TWO TO DB2IO-FIRST-NAME 00035200
MOVE 0 TO L-SPACE-CTR 00035300
MOVE SPACES TO TEMP-TWO. 00035400
00035500
* Check the leading space in input EXTENSION and trim it off 00035600
INSPECT DB2IO-EXTENSION 00035700
TALLYING L-SPACE-CTR FOR LEADING SPACE 00035800
REPLACING LEADING SPACE BY '*'. 00035900
IF L-SPACE-CTR > 0 THEN 00036000
UNSTRING DB2IO-EXTENSION 00036100
DELIMITED BY ALL '*' 00036200
INTO TEMP-ONE TEMP-TWO 00036300
MOVE TEMP-TWO TO DB2IO-EXTENSION 00036400
MOVE 0 TO L-SPACE-CTR 00036500
MOVE SPACES TO TEMP-TWO. 00036600
00036700
* Check the leading space in input ZIP CODE and trim it off 00036800
INSPECT DB2IO-ZIP-CODE 00036900
TALLYING L-SPACE-CTR FOR LEADING SPACE 00037000
REPLACING LEADING SPACE BY '*'. 00037100
IF L-SPACE-CTR > 0 THEN 00037200
UNSTRING DB2IO-ZIP-CODE 00037300
DELIMITED BY ALL '*' 00037400
INTO TEMP-ONE TEMP-TWO 00037500
MOVE TEMP-TWO TO DB2IO-ZIP-CODE 00037600
MOVE 0 TO L-SPACE-CTR 00037700
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1141
MOVE SPACES TO TEMP-TWO. 00037800
00037900
* Move the data to IO area for IMS 00038000
MOVE DB2IO-LAST-NAME TO IO-LAST-NAME. 00038100
MOVE DB2IO-COMMAND TO IO-COMMAND. 00038200
MOVE DB2IO-COMMAND TO DB2IN-COMMAND. 00038300
DISPLAY 'TE>DB2TEMP-IOCMD=' DB2TEMP-IOCMD. 00038400
00038500
* If no command specified, issue error 00038600
IF IO-COMMAND EQUAL SPACES THEN 00038700
MOVE 'BAD' TO RUN-STATUS 00038800
MOVE APPERR TO DB2OUT-AIBRETRN 00038900
MOVE INVCMD TO DB2OUT-AIBREASN 00039000
00039100
* If no LAST NAME specified, issue error 00039200
ELSE IF IO-LAST-NAME EQUAL SPACES THEN 00039300
MOVE 'BAD' TO RUN-STATUS 00039400
MOVE APPERR TO DB2OUT-AIBRETRN 00039500
MOVE NOKEY TO DB2OUT-AIBREASN. 00039600
00039700
00039800
***************************************************************** 00039900
* Process the request from the client 00040000
***************************************************************** 00040100
B30000-PROCESS-REQUEST. 00040200
00040300
* If command is ADD, insert a new record 00040400
IF DB2TEMP-IOCMD EQUAL 'ADD' THEN 00040500
PERFORM C31000-ADD-ENTRY 00040600
00040700
* If command is TAD, insert a new record and trace with WTO 00040800
ELSE IF DB2TEMP-IOCMD EQUAL 'TAD' THEN 00040900
MOVE 1 TO TADD-FLAG 00041000
PERFORM C31000-ADD-ENTRY 00041100
00041200
* If command is UPD, update existing record for LAST NAME 00041300
ELSE IF DB2TEMP-IOCMD EQUAL 'UPD' THEN 00041400
PERFORM C32000-UPDATE-ENTRY 00041500
00041600
* If command is DEL, delete record for LAST NAME 00041700
ELSE IF DB2TEMP-IOCMD EQUAL 'DEL' THEN 00041800
PERFORM C33000-DELETE-ENTRY 00041900
00042000
* If command is DIS, display record for LAST NAME 00042100
ELSE IF DB2TEMP-IOCMD EQUAL 'DIS' THEN 00042200
PERFORM C34000-DISPLAY-ENTRY 00042300
00042400
* Otherwise, issue error for unexpected command 00042500
ELSE 00042600
MOVE 'BAD' TO RUN-STATUS 00042700
MOVE APPERR TO DB2OUT-AIBRETRN 00042800
MOVE INVCMD TO DB2OUT-AIBREASN. 00042900
00043000
00043100
***************************************************************** 00043200
* Deallocate the ODBA Application Interface Block 00043300
***************************************************************** 00043400
B40000-DEALLOCATE-AIB. 00043500
MOVE APSBNME to AIBRSNM1. 00043600
* PREP keyword, below, tells IMS to move in-flight transactions 00043700
* to in-doubt state, so checkpoint or rollback can be deferred 00043800
* until DB2 stored procedure client issues COMMIT or ROLLBACK 00043900
MOVE SFPREP to AIBSFUNC. 00044000
00044100
* Deallocate the PSB for the AIB 00044200
CALL 'AERTDLI' USING DPSB, AIB. 00044300
DISPLAY 'AFTER DPSB PREP, DPCBNME=' DPCBNME. 00044400
DISPLAY 'DPSB PREP AIBRETRN=' AIBRETRN. 00044500
DISPLAY 'DPSB PREP AIBREASN=' AIBREASN. 00044600
DISPLAY 'DPSB PREP AIBRSNM1=' AIBRSNM1. 00044700
DISPLAY 'DPSB PREP AIBRSNM2=' AIBRSNM2. 00044800
DISPLAY 'DPSB PREP AIBRESA1=' AIBRESA1. 00044900
DISPLAY 'DPSB PREP AIBRESA2=' AIBRESA2. 00045000
DISPLAY 'DPSB PREP AIBRESA3=' AIBRESA3. 00045100
MOVE AIBRETRN TO DB2OUT-AIBRETRN. 00045200
MOVE AIBREASN TO DB2OUT-AIBREASN. 00045300
00045400
00045500
***************************************************************** 00045600
* Addition request handler 00045700
***************************************************************** 00045800
C31000-ADD-ENTRY. 00045900
1142 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
MOVE DB2IO-FIRST-NAME TO IO-FIRST-NAME. 00046000
MOVE DB2IO-EXTENSION TO IO-EXTENSION. 00046100
MOVE DB2IO-ZIP-CODE TO IO-ZIP-CODE. 00046200
MOVE IO-COMMAND TO DB2IO-COMMAND. 00046300
00046400
IF DB2IO-FIRST-NAME EQUAL SPACES 00046500
OR DB2IO-EXTENSION EQUAL SPACES 00046600
OR DB2IO-ZIP-CODE EQUAL SPACES THEN 00046700
MOVE 'BAD' TO RUN-STATUS 00046800
MOVE APPERR TO DB2OUT-AIBRETRN 00046900
MOVE INVCMD TO DB2OUT-AIBREASN 00047000
ELSE 00047100
PERFORM D31100-INSERT-TO-DB. 00047200
00047300
00047400
***************************************************************** 00047500
* Update request handler 00047600
***************************************************************** 00047700
C32000-UPDATE-ENTRY. 00047800
MOVE 0 TO SET-DATA-FLAG. 00047900
MOVE IO-LAST-NAME TO SSA-KEY. 00048000
PERFORM D32100-GET-HOLD-UNIQUE-FROM-DB. 00048100
IF AIBRETRN = ZEROES THEN 00048200
IF DB2IO-FIRST-NAME NOT = SPACES THEN 00048300
MOVE 1 TO SET-DATA-FLAG 00048400
MOVE DB2IO-FIRST-NAME TO IO-FIRST-NAME 00048500
END-IF 00048600
IF DB2IO-EXTENSION NOT = SPACES THEN 00048700
MOVE 1 TO SET-DATA-FLAG 00048800
MOVE DB2IO-EXTENSION TO IO-EXTENSION 00048900
END-IF 00049000
IF DB2IO-ZIP-CODE NOT = SPACES THEN 00049100
MOVE 1 TO SET-DATA-FLAG 00049200
MOVE DB2IO-ZIP-CODE TO IO-ZIP-CODE 00049300
END-IF 00049400
MOVE IO-COMMAND TO DB2IO-COMMAND. 00049500
IF NO-SET-DATA THEN 00049600
PERFORM D32200-REPLACE-IN-DB 00049700
ELSE 00049800
MOVE 'BAD' TO RUN-STATUS 00049900
MOVE APPERR TO DB2OUT-AIBRETRN 00050000
MOVE INVCMD TO DB2OUT-AIBREASN. 00050100
00050200
00050300
***************************************************************** 00050400
* Delete request handler 00050500
***************************************************************** 00050600
C33000-DELETE-ENTRY. 00050700
MOVE IO-LAST-NAME TO SSA-KEY. 00050800
PERFORM D32100-GET-HOLD-UNIQUE-FROM-DB. 00050900
IF AIBRETRN = ZEROES THEN 00051000
MOVE IO-COMMAND TO DB2IO-COMMAND 00051100
PERFORM D33200-DELETE-FROM-DB. 00051200
00051300
00051400
***************************************************************** 00051500
* Display request handler 00051600
***************************************************************** 00051700
C34000-DISPLAY-ENTRY. 00051800
MOVE IO-LAST-NAME TO SSA-KEY. 00051900
DISPLAY 'TE>SSA-KEY=' SSA-KEY. 00052000
PERFORM D34100-GET-UNIQUE-FROM-DB. 00052100
IF AIBRETRN = ZEROES THEN 00052200
MOVE IO-LAST-NAME TO DB2IO-LAST-NAME 00052300
MOVE IO-FIRST-NAME TO DB2IO-FIRST-NAME 00052400
MOVE IO-EXTENSION TO DB2IO-EXTENSION 00052500
MOVE IO-ZIP-CODE TO DB2IO-ZIP-CODE 00052600
MOVE IO-COMMAND TO DB2IO-COMMAND. 00052700
00052800
00052900
***************************************************************** 00053000
* Data base segment insert request handler 00053100
***************************************************************** 00053200
D31100-INSERT-TO-DB. 00053300
MOVE DPCBNME to AIBRSNM1. 00053400
CALL 'AERTDLI' USING ISRT, AIB, IOAREA, SSA1. 00053500
IF AIBRETRN = ZEROES THEN 00053600
IF PROCESS-TADD THEN 00053700
DISPLAY 'INSERT IS DONE, REPLY' UPON CONSOLE 00053800
ACCEPT REPLY FROM CONSOLE 00053900
MOVE 0 TO TADD-FLAG 00054000
END-IF 00054100
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1143
ELSE 00054200
MOVE 'BAD' TO RUN-STATUS 00054300
DISPLAY 'ISRT AIBRETRN=' AIBRETRN 00054400
DISPLAY 'ISRT AIBREASN=' AIBREASN 00054500
DISPLAY 'ISRT AIBRESA1=' AIBRESA1 00054600
DISPLAY 'ISRT AIBRESA2=' AIBRESA2 00054700
DISPLAY 'ISRT AIBRESA3=' AIBRESA3 00054800
MOVE APPERR TO DB2OUT-AIBRETRN 00054900
MOVE INVCMD TO DB2OUT-AIBREASN 00055000
MOVE ISRT TO DC-ERROR-CALL. 00055100
00055200
00055300
***************************************************************** 00055400
* Data base segment request handler 00055500
***************************************************************** 00055600
D32100-GET-HOLD-UNIQUE-FROM-DB. 00055700
MOVE DPCBNME to AIBRSNM1. 00055800
CALL 'AERTDLI' USING GET-HOLD-UNIQUE, AIB, IOAREA, SSA. 00055900
IF AIBRETRN NOT EQUAL ZEROES THEN 00056000
MOVE 'BAD' TO RUN-STATUS 00056100
MOVE APPERR TO DB2OUT-AIBRETRN 00056200
MOVE INVCMD TO DB2OUT-AIBREASN 00056300
MOVE GET-HOLD-UNIQUE TO DC-ERROR-CALL. 00056400
00056500
00056600
***************************************************************** 00056700
* Data base segment replace request handler 00056800
***************************************************************** 00056900
D32200-REPLACE-IN-DB. 00057000
MOVE DPCBNME to AIBRSNM1. 00057100
CALL 'AERTDLI' USING REPL, AIB, IOAREA. 00057200
IF AIBRETRN NOT EQUAL ZEROES THEN 00057300
MOVE 'BAD' TO RUN-STATUS 00057400
MOVE APPERR TO DB2OUT-AIBRETRN 00057500
MOVE INVCMD TO DB2OUT-AIBREASN 00057600
MOVE REPL TO DC-ERROR-CALL. 00057700
00057800
00057900
***************************************************************** 00058000
* Data base segment delete request handler 00058100
***************************************************************** 00058200
D33200-DELETE-FROM-DB. 00058300
MOVE DPCBNME to AIBRSNM1. 00058400
CALL 'AERTDLI' USING DLET, AIB, IOAREA. 00058500
IF AIBRETRN NOT EQUAL ZEROES THEN 00058600
MOVE 'BAD' TO RUN-STATUS 00058700
MOVE APPERR TO DB2OUT-AIBRETRN 00058800
MOVE INVCMD TO DB2OUT-AIBREASN 00058900
MOVE DLET TO DC-ERROR-CALL. 00059000
00059100
00059200
***************************************************************** 00059300
* Data base segment GET-UNIQUE request handler 00059400
***************************************************************** 00059500
D34100-GET-UNIQUE-FROM-DB. 00059600
MOVE DPCBNME to AIBRSNM1. 00059700
CALL 'AERTDLI' USING GET-UNIQUE, AIB, IOAREA, SSA. 00059800
IF AIBRETRN NOT EQUAL ZEROES THEN 00059900
MOVE 'BAD' TO RUN-STATUS 00060000
DISPLAY 'GU AIBRETRN=' AIBRETRN 00060100
DISPLAY 'GU AIBREASN=' AIBREASN 00060200
DISPLAY 'GU AIBRESA1(ADDR PCB)=' AIBRESA1 00060300
DISPLAY 'GU AIBRESA2=' AIBRESA2 00060400
DISPLAY 'GU AIBRESA3=' AIBRESA3 00060500
MOVE APPERR TO DB2OUT-AIBRETRN 00060600
MOVE INVCMD TO DB2OUT-AIBREASN 00060700
MOVE GET-UNIQUE TO DC-ERROR-CALL. 00060800
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSN8EC2
Demonstrates how to CALL the Db2 sample ODBA stored procedure, DSN8.
1144 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
00000300
****** DSN8EC2 - DB2 Sample ODBA Stored Procedure Client ******** 00000400
* * 00000500
* Module Name = DSN8EC2 * 00000600
* * 00000700
* Descriptive Name = DB2 Sample Application * 00000800
* Client for DB2 Sample ODBA Stored Proc * 00000900
* Batch * 00001000
* Cobol * 00001100
* * 00001200
*LICENSED MATERIALS - PROPERTY OF IBM * 00001300
*5675-DB2 * 00001400
*(C) COPYRIGHT 1999, 2000 IBM CORP. ALL RIGHTS RESERVED. * 00001500
* * 00001600
*STATUS = VERSION 7 * 00001700
* * 00001800
* Function = Demonstrates how to CALL the DB2 sample ODBA * 00001900
* stored procedure, DSN8.DSN8EC1, for accessing * 00002000
* the IMS IVP telephone directory database, * 00002100
* DFSIVD1. * 00002200
* * 00002300
* In particular, this program: * 00002400
* (1) Calls DSN8.DSN8EC1, passing an add request * 00002500
* and the data for an entry to be inserted to * 00002600
* DFSIVD1. * 00002700
* (2) Commits the unit of work for both DB2 and * 00002800
* IMS (Note: IMS work is in an "in doubt" * 00002900
* status until the stored procedure client * 00003000
* performs a COMMIT or a ROLLBACK). * 00003100
* (3) Calls DSN8.DSN8EC1 again, passing a display * 00003200
* request for a entry to be retrieved from * 00003300
* DFSIVD1. * 00003400
* * 00003500
* * 00003600
* Notes = NONE * 00003700
* * 00003800
* Module Type = Cobol Program * 00003900
* Processor = DB2 for OS/390 precompiler, IBM Cobol * 00004000
* Module Size = See linkedit output * 00004100
* Attributes = Re-entrant * 00004200
* * 00004300
* * 00004400
* Entry Point = DSN8EC2 * 00004500
* Purpose = See function * 00004600
* Linkage = Standard MVS program invocation * 00004700
* * 00004800
* Input = Parameters explicitly passed to this function: * 00004900
* PARMS ......... PIC X(25) * 00005000
* * 00005100
* Output = Symbolic label/Name = SYSOUT * 00005200
* Description = Results of ADD and DIS * 00005300
* * 00005400
* Exit-Normal = Return Code 0 Normal Completion * 00005500
* * 00005600
* Exit-Error = Return Code 8 Abnormal Completion * 00005700
* * 00005800
* Error Messages = * 00005900
* Unexpected SQLCODE from DSN8.DSN8EC1 during * 00006000
* <command> request. <DSNTIAR detail> * 00006100
* Unexpected return code from ODBA: * 00006200
* - Command .............. <command> * 00006300
* - AIB return code ...... <AIBRETRN> * 00006400
* - AIB reason code ...... <AIBREASN> * 00006500
* - DC error call ........ <DC-ERROR-CALL> * 00006600
* * 00006700
* External References = * 00006800
* Routines/Services = * 00006900
* DSN8EC1 - DB2 sample ODBA stored procedure * 00007000
* DSNTIAR - DB2 SQLCODE message formatter * 00007100
* * 00007200
* Data areas = None * 00007300
* * 00007400
* Control Blocks = * 00007500
* SQLCA - SQL communication area * 00007600
* * 00007700
* Tables = None * 00007800
* * 00007900
* * 00008000
* Change Activity = None * 00008100
* * 00008200
* * 00008300
* *Pseudocode* * 00008400
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1145
* * 00008500
* PROCEDURE A00000-ODBA-SP-CLIENT * 00008600
* Call A30000-ADD-ENTRY to generate add request * 00008700
* Call C31000-CALL-ODBA-SP to handle add request * 00008800
* Call DSN8.DSN8EC1 to perform add request * 00008900
* Call D31100-CHECK-SQLCODE to verify DB2 call * 00009000
* Call E31110-DETAIL-SQL-ERROR to format err * 00009100
* Call F31111-PRINT-SQL-ERROR-MSG * 00009200
* Call D31200-CHECK-AIBCODE to verify IMS state * 00009300
* Call B40000-COMMIT-WORK to commit DB2 work unit * 00009400
* Call B50000-DISPLAY-ENTRY to generate display request * 00009500
* Call C31000-CALL-ODBA-SP to handle display request * 00009600
* Call DSN8.DSN8EC1 to perform display request * 00009700
* Call D31100-CHECK-SQLCODE to verify DB2 call * 00009800
* Call E31110-DETAIL-SQL-ERROR to format err * 00009900
* Call F31111-PRINT-SQL-ERROR-MSG * 00010000
* Call D31200-CHECK-AIBCODE to verify IMS state * 00010100
* * 00010200
*---------------------------------------------------------------* 00010300
00010400
00010500
00010600
ENVIRONMENT DIVISION. 00010700
CONFIGURATION SECTION. 00010800
SOURCE-COMPUTER. IBM-370. 00010900
OBJECT-COMPUTER. IBM-370. 00011000
00011100
INPUT-OUTPUT SECTION. 00011200
00011300
DATA DIVISION. 00011400
WORKING-STORAGE SECTION. 00011500
00011600
***************************************************************** 00011700
* Fields for receiving 00011800
***************************************************************** 00011900
01 DB2-SERVER-LOCATION-NAME PIC X(16). 00012000
01 IMS-SUBSYSTEM-NAME PIC X(8). 00012100
00012200
***************************************************************** 00012300
* Parameter list for invoking sample DB2 stored procedure DSN8EC1 00012400
***************************************************************** 00012500
01 DB2IO-TDBCTLID PIC X(8). 00012600
01 DB2IO-COMMAND PIC X(8). 00012700
01 DB2IO-LAST-NAME PIC X(10). 00012800
01 DB2IO-FIRST-NAME PIC X(10). 00012900
01 DB2IO-EXTENSION PIC X(10). 00013000
01 DB2IO-ZIP-CODE PIC X(7). 00013100
01 DB2OUT-AIBRETRN PIC S9(9) COMP. 00013200
01 DB2OUT-AIBREASN PIC S9(9) COMP. 00013300
01 DC-ERROR-CALL PIC X(4). 00013400
00013500
***************************************************************** 00013600
* Buffer for receiving SQL error messages 00013700
***************************************************************** 00013800
01 ERROR-MESSAGE. 00013900
02 ERROR-LEN PIC S9(4) COMP VALUE +960. 00014000
02 ERROR-TEXT PIC X(120) OCCURS 10 TIMES 00014100
INDEXED BY ERROR-INDEX. 00014200
77 ERROR-TEXT-LEN PIC S9(9) COMP VALUE +120. 00014300
00014400
***************************************************************** 00014500
* Job status indicator 00014600
***************************************************************** 00014700
01 RUN-STATUS PIC X(4). 00014800
88 NOT-OKAY VALUE 'BAD'. 00014900
88 OKAY VALUE 'GOOD'. 00015000
00015100
***************************************************************** 00015200
* Include Cobol standard language global variables 00015300
***************************************************************** 00015400
EXEC SQL INCLUDE SQLCA END-EXEC. 00015500
00015600
00015700
00015800
LINKAGE SECTION. 00015900
00016000
***************************************************************** 00016100
* DSN8EC2 invocation parameter list 00016200
***************************************************************** 00016300
01 PARMS. 00016400
05 PARMS-LEN PIC 9(4) USAGE BINARY. 00016500
05 PARMS-DATA PIC X(25). 00016600
1146 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
00016700
00016800
00016900
PROCEDURE DIVISION 00017000
USING PARMS. 00017100
***************************************************************** 00017200
* Main driver: Use ODBA to add to and display from the IMS IVP DB 00017300
***************************************************************** 00017400
A00000-ODBA-SP-CLIENT. 00017500
DISPLAY '****************************************' 00017600
'****************************************'. 00017700
DISPLAY '* DSN8EC2: Sample Client for IMS/ODBA ' 00017800
'DB2 stored procedure sample (DSN8.DSN8EC1) '. 00017900
DISPLAY '*'. 00018000
MOVE 'GOOD' TO RUN-STATUS. 00018100
00018200
PERFORM B10000-PROCESS-PARMS. 00018300
00018400
PERFORM B20000-CONNECT-TO-SERVER. 00018500
00018600
IF OKAY THEN 00018700
PERFORM B30000-ADD-ENTRY. 00018800
00018900
IF OKAY THEN 00019000
PERFORM B40000-COMMIT-WORK. 00019100
00019200
IF OKAY THEN 00019300
PERFORM B50000-DISPLAY-ENTRY. 00019400
00019500
DISPLAY '****************************************' 00019600
'****************************************'. 00019700
00019800
IF NOT-OKAY THEN 00019900
MOVE 8 to RETURN-CODE. 00020000
00020100
STOP RUN. 00020200
00020300
00020400
B10000-PROCESS-PARMS. 00020500
***************************************************************** 00020600
* Process DSN8EC2 invocation parameters 00020700
***************************************************************** 00020800
UNSTRING PARMS-DATA 00020900
DELIMITED BY SPACE 00021000
INTO DB2-SERVER-LOCATION-NAME 00021100
IMS-SUBSYSTEM-NAME. 00021200
MOVE IMS-SUBSYSTEM-NAME TO DB2IO-TDBCTLID. 00021300
00021400
00021500
B20000-CONNECT-TO-SERVER. 00021600
***************************************************************** 00021700
* Connect to the remote server 00021800
***************************************************************** 00021900
DISPLAY '* Now connecting to ' DB2-SERVER-LOCATION-NAME. 00022000
DISPLAY '* for access to IMS node ' 00022100
IMS-SUBSYSTEM-NAME. 00022200
DISPLAY '*'. 00022300
00022400
EXEC SQL CONNECT TO :DB2-SERVER-LOCATION-NAME END-EXEC. 00022500
IF SQLCODE IS NOT EQUAL TO ZERO THEN 00022600
PERFORM D31100-CHECK-SQLCODE. 00022700
00022800
00022900
B30000-ADD-ENTRY. 00023000
***************************************************************** 00023100
* Generate and add an entry to the IMS IVP database DFSIVD1 00023200
***************************************************************** 00023300
MOVE 'ADD' TO DB2IO-COMMAND. 00023400
MOVE 'DOE' TO DB2IO-LAST-NAME. 00023500
MOVE 'JOHN' TO DB2IO-FIRST-NAME. 00023600
MOVE '9-876-5432' TO DB2IO-EXTENSION. 00023700
MOVE '98765' TO DB2IO-ZIP-CODE. 00023800
MOVE 0 TO DB2OUT-AIBRETRN. 00023900
MOVE 0 TO DB2OUT-AIBREASN. 00024000
MOVE ' ' TO DC-ERROR-CALL. 00024100
00024200
PERFORM C31000-CALL-ODBA-SP. 00024300
00024400
IF OKAY THEN 00024500
DISPLAY '* Entry for:' 00024600
DISPLAY '* - Last Name .......... ' DB2IO-LAST-NAME 00024700
DISPLAY '* - First Name ......... ' DB2IO-FIRST-NAME 00024800
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1147
DISPLAY '* - Extension Number ... ' DB2IO-EXTENSION 00024900
DISPLAY '* - Internal Zip Code .. ' DB2IO-ZIP-CODE 00025000
DISPLAY '* added successfully to database DFSIVD1.' 00025100
DISPLAY '*'. 00025200
00025300
00025400
B40000-COMMIT-WORK. 00025500
***************************************************************** 00025600
* Commit changes in the IMS telephone database 00025700
***************************************************************** 00025800
EXEC SQL COMMIT 00025900
END-EXEC. 00026000
00026100
PERFORM D31100-CHECK-SQLCODE. 00026200
00026300
00026400
B50000-DISPLAY-ENTRY. 00026500
***************************************************************** 00026600
* Retrieve an entry from IMS IVP database DFSIVD1 00026700
***************************************************************** 00026800
MOVE 'DIS' TO DB2IO-COMMAND. 00026900
MOVE 'LAST1' TO DB2IO-LAST-NAME. 00027000
MOVE 'NNNN' TO DB2IO-FIRST-NAME. 00027100
MOVE 'N-NNN-NNNN' TO DB2IO-EXTENSION. 00027200
MOVE 'NNNNN' TO DB2IO-ZIP-CODE. 00027300
MOVE 0 TO DB2OUT-AIBRETRN. 00027400
MOVE 0 TO DB2OUT-AIBREASN. 00027500
MOVE ' ' TO DC-ERROR-CALL. 00027600
00027700
PERFORM C31000-CALL-ODBA-SP. 00027800
00027900
IF OKAY THEN 00028000
DISPLAY '* Entry for:' 00028100
DISPLAY '* - Last Name .......... ' DB2IO-LAST-NAME 00028200
DISPLAY '* - First Name ......... ' DB2IO-FIRST-NAME 00028300
DISPLAY '* - Extension Number ... ' DB2IO-EXTENSION 00028400
DISPLAY '* - Internal Zip Code .. ' DB2IO-ZIP-CODE 00028500
DISPLAY '* retrieved successfully from DFSIVD1.' 00028600
DISPLAY '*'. 00028700
00028800
00028900
C31000-CALL-ODBA-SP. 00029000
***************************************************************** 00029100
* Invoke the sample stored procedure for IMS/ODBA 00029200
***************************************************************** 00029300
EXEC SQL CALL DSN8.DSN8EC1 (:DB2IO-TDBCTLID, 00029400
:DB2IO-COMMAND, 00029500
:DB2IO-LAST-NAME, 00029600
:DB2IO-FIRST-NAME, 00029700
:DB2IO-EXTENSION, 00029800
:DB2IO-ZIP-CODE, 00029900
:DB2OUT-AIBRETRN, 00030000
:DB2OUT-AIBREASN, 00030100
:DC-ERROR-CALL) 00030200
END-EXEC. 00030300
00030400
PERFORM D31100-CHECK-SQLCODE. 00030500
00030600
IF OKAY THEN 00030700
PERFORM D31200-CHECK-AIBCODE. 00030800
00030900
00031000
D31100-CHECK-SQLCODE. 00031100
**************************************************************** 00031200
* Verify that the prior SQL call completed successfully 00031300
**************************************************************** 00031400
IF SQLCODE NOT = 0 THEN 00031500
MOVE 'BAD' TO RUN-STATUS 00031600
DISPLAY '* Unexpected SQLCODE from DSN8.DSN8EC1 ' 00031700
'during ' DB2IO-COMMAND ' request.' 00031800
DISPLAY '*' 00031900
PERFORM E31110-DETAIL-SQL-ERROR. 00032000
00032100
00032200
E31110-DETAIL-SQL-ERROR. 00032300
**************************************************************** 00032400
* Call DSNTIAR to return a text message for an unexpected 00032500
* SQLCODE. 00032600
**************************************************************** 00032700
CALL 'DSNTIAR' USING SQLCA ERROR-MESSAGE ERROR-TEXT-LEN. 00032800
IF RETURN-CODE = ZERO 00032900
PERFORM F31111-PRINT-SQL-ERROR-MSG VARYING ERROR-INDEX 00033000
1148 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
FROM 1 BY 1 UNTIL ERROR-INDEX GREATER THAN 10. 00033100
00033200
* **MESSAGE FORMAT 00033300
* **ROUTINE ERROR 00033400
* **PRINT ERROR MESSAG 00033500
00033600
00033700
F31111-PRINT-SQL-ERROR-MSG. 00033800
**************************************************************** 00033900
* Print message text 00034000
**************************************************************** 00034100
DISPLAY ERROR-TEXT (ERROR-INDEX). 00034200
00034300
00034400
D31200-CHECK-AIBCODE. 00034500
**************************************************************** 00034600
* Verify that the IMS operation via ODBA succeeded 00034700
**************************************************************** 00034800
IF DB2OUT-AIBRETRN NOT = 0 OR DB2OUT-AIBREASN NOT = 0 THEN 00034900
MOVE 'BAD' TO RUN-STATUS 00035000
DISPLAY '* Unexpected return code from ODBA:' 00035100
DISPLAY '* - Command ..............' DB2IO-COMMAND 00035200
DISPLAY '* - AIB return code ......' DB2OUT-AIBRETRN 00035300
DISPLAY '* - AIB reason code ......' DB2OUT-AIBREASN 00035400
DISPLAY '* - DC error call ........' DC-ERROR-CALL 00035500
DISPLAY '*'. 00035600
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSN8ES1
Accepts a department number from the caller and returns parameters containing the total earnings
(salaries and bonuses) for employees in that department, as well as the number of employees who got a
bonus.
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1149
-- Normal Exit: 00410000
-- Error Exit: 00420000
-- 00430000
-- 00440000
-- External References: 00450000
-- - EMP : DB2 Sample Employee Table 00460000
-- - DSN8.DSN8ES1_RS_TBL: Global Temporary Table for result set 00470000
-- 00480000
-- Pseudocode: 00490000
-- - Clear any residual from result set table 00500000
-- - Open cursor on EMP table for employees in department DEPTNO 00510000
-- - While more rows: 00520000
-- - Add current employee's salary and bonus to total department 00530000
-- earnings 00540000
-- - If current employee's bonus is greater than zero 00550000
-- - increment the department bonus counter 00560000
-- - add the employee's serial, first and last name, salary and 00570000
-- bonus to the result set table, using the bonus counter as 00580000
-- a result set sequence number 00590000
-- - If no errors, open the cursor to the result set 00600000
-- 00610000
-- 00620000
CREATE PROCEDURE DSN8.DSN8ES1 00630000
( IN DEPTNO CHAR(3), 00640000
OUT DEPTSAL DECIMAL(15,2), 00650000
OUT BONUSCNT INT ) 00660000
PARAMETER CCSID EBCDIC 00670000
FENCED 00680000
RESULT SET 1 00690000
LANGUAGE SQL 00700000
NOT DETERMINISTIC 00710000
MODIFIES SQL DATA 00720000
COLLID DSN8ES!! 00740000
WLM ENVIRONMENT WLMENV 00750000
ASUTIME NO LIMIT 00760000
COMMIT ON RETURN NO 00800000
00810000
P1: BEGIN NOT ATOMIC 00820000
DECLARE EMPLOYEE_NUMBER CHAR(6) CCSID EBCDIC; 00830000
DECLARE EMPLOYEE_FIRSTNME CHAR(12) CCSID EBCDIC; 00840000
DECLARE EMPLOYEE_LASTNAME CHAR(15) CCSID EBCDIC; 00850000
DECLARE EMPLOYEE_SALARY DECIMAL(9,2) DEFAULT 0; 00860000
DECLARE EMPLOYEE_BONUS DECIMAL(9,2) DEFAULT 0; 00870000
DECLARE TOTAL_SALARY DECIMAL(15,2) DEFAULT 0; 00880000
DECLARE BONUS_COUNTER INT DEFAULT 0; 00890000
DECLARE END_TABLE INT DEFAULT 0; 00900000
00910000
-- Cursor for result set of employees who got a bonus 00920000
DECLARE DSN8ES1_RS_CSR CURSOR WITH RETURN WITH HOLD FOR 00930000
SELECT RS_SEQUENCE, 00940000
RS_EMPNO, 00950000
RS_FIRSTNME, 00960000
RS_LASTNAME, 00970000
RS_SALARY, 00980000
RS_BONUS 00990000
FROM DSN8.DSN8ES1_RS_TBL 01000000
ORDER BY RS_SEQUENCE; 01010000
01020000
-- Cursor to fetch department employees 01030000
DECLARE C1 CURSOR FOR 01040000
SELECT EMPNO, 01050000
FIRSTNME, 01060000
LASTNAME, 01070000
SALARY, 01080000
BONUS 01090000
FROM EMP 01100000
WHERE WORKDEPT = DEPTNO; 01110000
01120000
DECLARE CONTINUE HANDLER FOR NOT FOUND 01130000
SET END_TABLE = 1; 01140000
01150000
DECLARE EXIT HANDLER FOR SQLEXCEPTION 01160000
SET DEPTSAL = NULL; 01170000
01180000
-- Clean residual from the result set table 01190000
DELETE FROM DSN8.DSN8ES1_RS_TBL; 01200000
01210000
OPEN C1; 01220000
01230000
FETCH C1 01240000
INTO EMPLOYEE_NUMBER, 01250000
EMPLOYEE_FIRSTNME, 01260000
1150 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
EMPLOYEE_LASTNAME, 01270000
EMPLOYEE_SALARY, 01280000
EMPLOYEE_BONUS; 01290000
01300000
-- Process each employee in the department 01310000
WHILE END_TABLE = 0 DO 01320000
-- Update department total salary 01330000
SET TOTAL_SALARY = TOTAL_SALARY 01340000
+ EMPLOYEE_SALARY 01350000
+ EMPLOYEE_BONUS; 01360000
01370000
-- If the current employee received a bonus 01380000
IF EMPLOYEE_BONUS > 0.00 THEN 01390000
-- Update department bonus count 01400000
SET BONUS_COUNTER = BONUS_COUNTER + 1; 01410000
01420000
-- Add the employee's data to the result set 01430000
INSERT INTO DSN8.DSN8ES1_RS_TBL 01440000
( RS_SEQUENCE, 01450000
RS_EMPNO, 01460000
RS_FIRSTNME, 01470000
RS_LASTNAME, 01480000
RS_SALARY, 01490000
RS_BONUS ) 01500000
VALUES( P1.BONUS_COUNTER, 01510000
P1.EMPLOYEE_NUMBER, 01520000
P1.EMPLOYEE_FIRSTNME, 01530000
P1.EMPLOYEE_LASTNAME, 01540000
P1.EMPLOYEE_SALARY, 01550000
P1.EMPLOYEE_BONUS ); 01560000
END IF; 01570000
01580000
FETCH C1 01590000
INTO EMPLOYEE_NUMBER, 01600000
EMPLOYEE_FIRSTNME, 01610000
EMPLOYEE_LASTNAME, 01620000
EMPLOYEE_SALARY, 01630000
EMPLOYEE_BONUS; 01640000
01650000
END WHILE; 01660000
01670000
CLOSE C1; 01680000
-- Set return parameters 01690000
SET DEPTSAL = TOTAL_SALARY; 01700000
SET BONUSCNT = BONUS_COUNTER; 01710000
01720000
-- Open the cursor to the result set 01730000
OPEN DSN8ES1_RS_CSR; 01740000
END P1 01750000
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSN8ED3
Demonstrates how to call the sample PSM stored procedure DSN8ES1 using static SQL.
/********************************************************************* 00010000
* Module name = DSN8ED3 (DB2 sample program) * 00020000
* * 00030000
* DESCRIPTIVE NAME = Client for sample PSM Stored Procedure DSN8ES1 * 00040000
* * 00050000
* LICENSED MATERIALS - PROPERTY OF IBM * 00070000
* 5675-DB2 * 00080000
* (C) COPYRIGHT 2000 IBM CORP. ALL RIGHTS RESERVED. * 00090000
* * 00100000
* STATUS = VERSION 7 * 00110000
* * 00120000
* Function: Demonstrates how to call the sample PSM stored procedure * 00130000
* DSN8ES1 using static SQL. * 00140000
* * 00150000
* Notes: * 00160000
* Dependencies: Requires IBM C/C++ for OS/390 V1R3 or higher * 00170000
* * 00180000
* Restrictions: * 00190000
* * 00200000
* Module type: C program * 00210000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1151
* Processor: IBM C/C++ for OS/390 V1R3 or higher * 00220000
* Module size: See linkedit output * 00230000
* Attributes: Re-entrant and re-usable * 00240000
* * 00250000
* Entry Point: DSN8ED3 * 00260000
* Purpose: See Function * 00270000
* Linkage: DB2SQL * 00280000
* Invoked via SQL UDF call * 00290000
* * 00300000
* * 00310000
* Parameters: DSN8ED3 uses the C "main" argument convention of * 00320000
* argv (argument vector) and argc (argument count). * 00330000
* * 00340000
* - ARGV[0] = (input) pointer to a char[9], null- * 00350000
* terminated string having the name of * 00360000
* this program (DSN8ED3) * 00370000
* - ARGV[1] = (input) pointer to a char[4], null- * 00380000
* terminated string having the department * 00390000
* number to be passed to DSN8ES1. * 00400000
* - ARGV[2] = (input) pointer to a char[16], null- * 00410000
* terminated string having the location * 00420000
* name of a server to connect to process * 00430000
* the current request. This parameter is * 00440000
* optional. In its absence, the current * 00450000
* location is used. * 00460000
* * 00470000
* Normal Exit: Return Code: 0000 * 00480000
* - Message: none * 00490000
* * 00500000
* Error Exit: Return Code: 0008 * 00510000
* - Message: DSN8ED3 failed: Invalid parameter count * 00520000
* * 00530000
* - Message: <formatted SQL text from DSNTIAR> * 00540000
* * 00550000
* * 00560000
* External References: * 00570000
* - Routines/Services: DSNTIAR: DB2 msg text formatter * 00580000
* - Data areas : None * 00590000
* - Control blocks : None * 00600000
* * 00610000
* Pseudocode: * 00620000
* DSN8ED3: * 00630000
* - Verify that number of input parameters passed is either: * 00640000
* - 2 (program name and department number); or * 00650000
* - 3 (program name, department number, and (remote) server name * 00660000
* - Other: issue diagnostic message and end with code 0008 * 00670000
* - Connect to server location, if one was passed in. * 00680000
* - Call sample stored procedure DSN8ES1, passing the department * 00690000
* number as the argument of the first (input) parameter. * 00700000
* - if unsuccessful, call sql_error to issue a diagnostic mes- * 00710000
* sage, then end with code 0008. * 00720000
* - Report the following parameters, passed back from DSN8ES1: * 00730000
* - Total of salary and bonusses for department members * 00740000
* - Number of employees in the department who received a bonus * 00750000
* - If a result set was returned, call processResultSet to handle * 00760000
* it * 00770000
* End DSN8ED3 * 00780000
* * 00790000
* processResultSet: * 00800000
* - Associate a locator with the result set passed from DSN8ES1, * 00810000
* which contains the serial number, first and last name, salary, * 00820000
* and bonus for each department member who got a bonus. * 00830000
* - if unsuccessful, call sql_error to issue a diagnostic mes- * 00840000
* sage, then end with code 0008. * 00850000
* - Allocate DSN8ES1_RS_CSR as a cursor for the locator * 00860000
* - if unsuccessful, call sql_error to issue a diagnostic mes- * 00870000
* sage, then end with code 0008. * 00880000
* - Do while not end of cursor * 00890000
* - Read the cursor * 00900000
* - If successful, print the row as a report line item * 00910000
* - else if not end of cursor, call sql_error to issue a diag- * 00920000
* nostic message, then end with code 0008. * 00930000
* - Close the cursor * 00940000
* - if unsuccessful, call sql_error to issue a diagnostic mes- * 00950000
* sage, then end with code 0008. * 00960000
* End processResultSet * 00970000
* * 00980000
* sql_error: * 00990000
* - call DSNTIAR to format the unexpected SQLCODE. * 01000000
* End sql_error * 01010000
* * 01020000
*********************************************************************/ 01030000
1152 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
/********************** C library definitions ***********************/ 01040000
#include <stdio.h> 01050000
#include <stdlib.h> 01060000
#include <string.h> 01070000
#include <decimal.h> 01080000
01090000
/***************************** Equates ******************************/ 01100000
#define NULLCHAR '\0' /* Null character */ 01110000
01120000
#define OUTLEN 80 /* Length of output line */ 01130000
#define DATA_DIM 10 /* Number of message lines */ 01140000
01150000
#define NOT_OK 0 /* Run status indicator: Error*/ 01160000
#define OK 1 /* Run status indicator: Good */ 01170000
01180000
01190000
/******************** DB2 SQL Communication Area ********************/ 01200000
EXEC SQL INCLUDE SQLCA; 01210000
01220000
01230000
/************************ DB2 Host Variables ************************/ 01240000
EXEC SQL BEGIN DECLARE SECTION; 01250000
char hvDeptNo[4]; /* ID of department to query */ 01260000
short int niDeptNo = 0; /* Indic var for dept number */ 01270000
01280000
char hvServerName[17]; /* Location name of server */ 01290000
01300000
decimal(15,2) hvDeptEarnings = 0; /* Total dept salaries & bonus*/ 01310000
short int niDeptEarnings = 0; /* Indic var for dept salary */ 01320000
01330000
long int hvDeptBonusCount= 0; /* Total no. of bonuses in dpt*/ 01340000
short int niDeptBonusCount= 0; /* Indic var for dpt bonus cnt*/ 01350000
01360000
long int hvSequence; /* Result set row sequence no.*/ 01370000
char hvEmpno[7]; /* Employee number */ 01380000
char hvFirstName[13]; /* Employee first name */ 01390000
char hvLastName[16]; /* Employee last name */ 01400000
decimal(9,2) hvSalary = 0; /* Employee salary */ 01410000
decimal(9,2) hvBonus = 0; /* Employee bonus */ 01420000
01430000
EXEC SQL END DECLARE SECTION; 01440000
01450000
01460000
/********************* DB2 Result Set Locators **********************/ 01470000
EXEC SQL BEGIN DECLARE SECTION; 01480000
static volatile SQL TYPE IS RESULT_SET_LOCATOR *DSN8ES1_rs_loc; 01490000
EXEC SQL END DECLARE SECTION; 01500000
01510000
01520000
/********************** DB2 Message Formatter ***********************/ 01530000
struct error_struct /* DSNTIAR message structure */ 01540000
{ 01550000
short int error_len; 01560000
char error_text[DATA_DIM][OUTLEN]; 01570000
} error_message = {DATA_DIM * (OUTLEN)}; 01580000
01590000
#pragma linkage( dsntiar, OS ) 01600000
01610000
extern short int dsntiar( struct sqlca *sqlca, 01620000
struct error_struct *msg, 01630000
int *len ); 01640000
01650000
01660000
/********************* DSN8ED3 Global Variables *********************/ 01670000
short int status = OK; /* DSN8ED3 run status */ 01680000
01690000
long int completion_code = 0; /* DSN8ED3 return code */ 01700000
01710000
01720000
/******************** DSN8ED3 Function Prototypes *******************/ 01730000
int main( int argc, char *argv[] ); 01740000
void processResultSet( void ); 01750000
void sql_error( char locmsg[] ); 01760000
01770000
01780000
int main( int argc, char *argv[] ) 01790000
/********************************************************************* 01800000
* Get input parms, pass them to DSN8ES1, and process the results * 01810000
*********************************************************************/ 01820000
{ 01830000
printf( "**** DSN8ED3: Sample client for DB2 PSM " 01840000
"Stored Procedure Sample (DSN8ES1)\n\n" ); 01850000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1153
01860000
if( argc == 2 ) /* Only dept no. was passed */ 01870000
{ 01880000
strcpy( hvDeptNo,argv[1] ); 01890000
} 01900000
else if( argc == 3 ) /* Dept & server name passed */ 01910000
{ 01920000
strcpy( hvDeptNo,argv[1] ); 01930000
strcpy( hvServerName,argv[2] ); 01940000
EXEC SQL CONNECT TO :hvServerName; 01950000
if( SQLCODE != 0 ) 01960000
sql_error( " *** Connect to server" ); 01970000
} 01980000
else 01990000
{ 02000000
printf( "DSN8ED3 failed: Invalid parameter count\n" ); 02010000
status = NOT_OK; 02020000
} 02030000
02040000
if( status == OK ) 02050000
printf( "Salary and Bonus Report for Department %s\n",hvDeptNo ); 02060000
02070000
if( status == OK ) 02080000
{ 02090000
EXEC SQL CALL DSN8.DSN8ES1( :hvDeptNo :niDeptNo, 02100000
:hvDeptEarnings :niDeptEarnings, 02110000
:hvDeptBonusCount:niDeptBonusCount );02120000
if( SQLCODE != 0 && SQLCODE != 466 ) 02130000
sql_error( " *** Call DSN8ES1" ); 02140000
else 02150000
{ 02160000
printf( "Total Department Salaries and Bonuses: %D(15,2)\n", 02170000
hvDeptEarnings ); 02180000
printf( "Total Number of Bonuses in Department: %i\n", 02190000
hvDeptBonusCount ); 02200000
} 02210000
} 02220000
02230000
if( SQLCODE == 0 && status == OK ) 02240000
if( hvDeptBonusCount != 0 ) 02250000
{ 02260000
printf( "\n*** Error: Result set was expected from DSN8ES1 " 02270000
"but was not received\n" ); 02280000
status = NOT_OK; 02290000
} 02300000
02310000
if( SQLCODE == 466 && status == OK ) 02320000
processResultSet(); 02330000
02340000
if( status != OK ) 02350000
completion_code = 8; 02360000
02370000
return( completion_code ); 02380000
02390000
} /* end main */ 02400000
02410000
02420000
void processResultSet( void ) 02430000
/********************************************************************* 02440000
* If a result was returned by DSN8ES1, this function will process it * 02450000
*********************************************************************/ 02460000
{ 02470000
printf( "Bonus Earners are\n" ); 02480000
02490000
printf( "Serial First Name Last Name " 02500000
"Salary Bonus\n" ); 02510000
printf( "------ ------------ --------------- " 02520000
"--------- ---------\n" ); 02530000
02540000
EXEC SQL ASSOCIATE LOCATOR( :DSN8ES1_rs_loc ) 02550000
WITH PROCEDURE DSN8.DSN8ES1; 02560000
if( SQLCODE != 0 ) 02570000
sql_error( " *** Associate locator DSN8ES1_rs_loc" ); 02580000
02590000
if( SQLCODE == 0 && status == OK ) 02600000
{ 02610000
EXEC SQL ALLOCATE DSN8ES1_RS_CSR 02620000
CURSOR FOR 02630000
RESULT SET :DSN8ES1_rs_loc; 02640000
if( SQLCODE != 0 ) 02650000
sql_error( " *** Allocate cursor for DSN8ES1 result set" ); 02660000
} 02670000
1154 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
02680000
while( SQLCODE == 0 && status == OK ) 02690000
{ 02700000
EXEC SQL FETCH DSN8ES1_RS_CSR 02710000
INTO :hvSequence, 02720000
:hvEmpno, 02730000
:hvFirstName, 02740000
:hvLastName, 02750000
:hvSalary, 02760000
:hvBonus; 02770000
if( SQLCODE == 0 ) 02780000
printf( "%s %s %s %9D(9,2) %9D(9,2)\n", 02790000
hvEmpno, hvFirstName, hvLastName, hvSalary, hvBonus ); 02800000
else if( SQLCODE != 100 ) 02810000
sql_error( " *** Fetch from DSN8ES1 result set cursor" ); 02820000
} 02830000
02840000
} /* end void processResultSet( void ) */ 02850000
02860000
02870000
/********************************************************************* 02880000
********************************************************************** 02890000
** SQL error handler ** 02900000
********************************************************************** 02910000
*********************************************************************/ 02920000
void sql_error( char locmsg[] ) /*proc*/ 02930000
{ 02940000
02950000
02960000
short int rc; /* DSNTIAR Return code */ 02970000
int j,k; /* Loop control */ 02980000
static int lrecl = OUTLEN; /* Width of message lines */ 02990000
03000000
/******************************************************************* 03010000
* set status to prevent further processing * 03020000
*******************************************************************/ 03030000
status = NOT_OK; 03040000
03050000
/******************************************************************* 03060000
* print the locator message * 03070000
*******************************************************************/ 03080000
printf( " %.80s\n", locmsg ); 03090000
03100000
/******************************************************************* 03110000
* format and print the SQL message * 03120000
*******************************************************************/ 03130000
rc = dsntiar( &sqlca, &error_message, &lrecl ); 03140000
if( rc == 0 ) 03150000
for( j=0; j<DATA_DIM; j++ ) 03160000
{ 03170000
for( k=0; k<OUTLEN; k++ ) 03180000
putchar(error_message.error_text[j][k] ); 03190000
putchar('\n'); 03200000
} 03210000
else 03220000
{ 03230000
printf( " *** ERROR: DSNTIAR could not format the message\n" ); 03240000
printf( " *** SQLCODE is %d\n",SQLCODE ); 03250000
printf( " *** SQLERRM is \n" ); 03260000
for( j=0; j<sqlca.sqlerrml; j++ ) 03270000
printf( "%c", sqlca.sqlerrmc[j] ); 03280000
printf( "\n" ); 03290000
} 03300000
03310000
} /* end of sql_error */ 03320000
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSN8ES2
Accepts a bonus base amount (BONUSBAS) to be awarded to employees who are managers.
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1155
-- (C) COPYRIGHT 2000, 2006 IBM CORP. ALL RIGHTS RESERVED. 00050000
-- 00060000
-- STATUS = VERSION 9 00070000
-- 00080000
-- Function: Accepts a bonus base amount (BONUSBAS) to be awarded to 00090000
-- employees who are managers. Determines a bonus premium 00100000
-- (BONUSPRM) for each manager, according to the number of 00110000
-- employees he or she manages. Updates the BONUS column of 00120000
-- the sample EMP table for each manager with the sum of the00130000
-- bonus base and his or her bonus premium. Returns the 00140000
-- total (BONUSTOT) of all bonuses awarded to managers. 00150000
-- 00160000
-- SQLERRCD is null unless an SQL exception occurs, in which00170000
-- case SQLERRCD is set to the current SQLCODE 00180000
-- 00190000
-- Notes: 00200000
-- Dependencies: 00210000
-- - Requires DB2 precompiler support for SQL procedures (DSNHPSM)00220000
-- 00230000
-- Restrictions: 00240000
-- 00250000
-- Module Type: SQL Procedure 00260000
-- Processor: DB2 for OS/390 precompiler and IBM C/C++ for OS/390 00270000
-- or a subsequent release 00280000
-- Attributes: Re-entrant and re-usable 00290000
-- 00300000
-- Entry Point: DSN8ES2 00310000
-- Purpose: See Function, above 00320000
-- 00330000
-- Parameters: 00340000
-- - Input: BONUSBAS DECIMAL(15,2) 00350000
-- - Output: BONUSTOT DECIMAL(15,2) 00360000
-- SQLERRCD INTEGER 00370000
-- 00380000
-- Normal Exit: 00390000
-- Error Exit: 00400000
-- 00410000
-- 00420000
-- External References: 00430000
-- - EMP : DB2 Sample Employee Table 00440000
-- 00450000
-- Pseudocode: 00460000
-- - Open a cursor on sample DEPT and EMP tables, that identifies 00470000
-- department managers and the number of persons in each department 00480000
-- 00490000
-- - For each manager found: 00500000
-- - Determine the bonus premium according to the number of 00510000
-- employees managed: $1000 for more than 10, $500 for 6 to 10, 00520000
-- $100 for 1 to 5 00530000
-- - Update the manager's bonus in the sample EMP table with the 00540000
-- sum of the bonus base and the bonus premium 00550000
-- - Add the manager's bonus to the total bonuses bucket. 00560000
-- - Return total amount of bonuses awarded 00570000
-- 00580000
CREATE PROCEDURE DSN8.DSN8ES2 00590000
( IN BONUSBAS DECIMAL(15,2), 00600000
OUT BONUSTOT DECIMAL(15,2), 00610000
OUT SQLERRCD INTEGER ) 00620000
PARAMETER CCSID EBCDIC 00630000
FENCED 00640000
RESULT SETS 0 00650000
LANGUAGE SQL 00660000
NOT DETERMINISTIC 00670000
MODIFIES SQL DATA 00680000
COLLID DSN8ES!! 00700000
WLM ENVIRONMENT WLMENV 00710000
ASUTIME NO LIMIT 00720000
COMMIT ON RETURN NO 00760000
00770000
P1: BEGIN NOT ATOMIC 00780000
DECLARE MANAGER_ID CHAR(6) CCSID EBCDIC; 00790000
DECLARE NUM_EMPLOYEES INT DEFAULT 0; 00800000
DECLARE BONUSPRM DECIMAL(15,2) DEFAULT 0; 00810000
DECLARE BONUSBKT DECIMAL(15,2) DEFAULT 0; 00820000
DECLARE END_TABLE INT DEFAULT 0; 00830000
DECLARE SQLCODE INT; 00831000
00840000
-- Cursor gets id and no. of direct reports for each manager 00850000
DECLARE C1 CURSOR FOR 00860000
SELECT DEPT.MGRNO, 00870000
COUNT(DISTINCT EMP.EMPNO) 00880000
FROM DEPT DEPT, 00890000
1156 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
EMP EMP 00900000
WHERE EMP.WORKDEPT = DEPT.DEPTNO 00910000
GROUP BY EMP.WORKDEPT, DEPT.MGRNO; 00920000
00930000
DECLARE CONTINUE HANDLER FOR NOT FOUND 00940000
SET END_TABLE = 1; 00950000
00960000
DECLARE EXIT HANDLER FOR SQLEXCEPTION 00970000
SET SQLERRCD = SQLCODE; 00980000
00990000
SET BONUSTOT = NULL; 01000000
SET SQLERRCD = NULL; 01010000
01020000
OPEN C1; 01030000
01040000
FETCH C1 01050000
INTO MANAGER_ID, 01060000
NUM_EMPLOYEES; 01070000
01080000
WHILE END_TABLE = 0 DO 01090000
CASE 01100000
WHEN( NUM_EMPLOYEES > 10 ) THEN 01110000
SET BONUSPRM = 1000.00; 01120000
WHEN( NUM_EMPLOYEES > 5 ) THEN 01130000
SET BONUSPRM = 500.00; 01140000
WHEN( NUM_EMPLOYEES > 0 ) THEN 01150000
SET BONUSPRM = 100.00; 01160000
ELSE 01170000
SET BONUSPRM = 0.00; 01180000
END CASE; 01190000
01200000
UPDATE EMP 01210000
SET BONUS = BONUSBAS + BONUSPRM 01220000
WHERE EMPNO = MANAGER_ID; 01230000
01240000
SET BONUSBKT = BONUSBKT + BONUSBAS + BONUSPRM; 01250000
01260000
FETCH C1 01270000
INTO MANAGER_ID, 01280000
NUM_EMPLOYEES; 01290000
01300000
END WHILE; 01310000
01320000
CLOSE C1; 01330000
01340000
SET BONUSTOT = BONUSBKT; 01350000
01360000
END P1 01370000
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSN8ED6
Demonstrates how to use WLM_REFRESH, the sample stored procedure for refreshing a WLM
environment .
/********************************************************************* 00010000
* Module name = DSN8ED6 (DB2 sample program) * 00020000
* * 00030000
* DESCRIPTIVE NAME = Caller for sample WLM_REFRESH stored procedure * 00040000
* * 00050000
* LICENSED MATERIALS - PROPERTY OF IBM * 00060000
* 5675-DB2 * 00070000
* (C) COPYRIGHT 1999, 2000 IBM CORP. ALL RIGHTS RESERVED. * 00090000
* * 00120000
* STATUS = VERSION 7 * 00130000
* * 00160000
* Function: Demonstrates how to use WLM_REFRESH, the sample stored * 00220000
* procedure for refreshing a WLM environment * 00230000
* * 00240000
* Notes: * 00250000
* Dependencies: Requires IBM C/C++ for OS/390 V1R3 or higher * 00260000
* * 00270000
* Restrictions: * 00280000
* * 00290000
* Module type: C program * 00300000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1157
* Processor: IBM C/C++ for OS/390 V1R3 or higher * 00310000
* Module size: See linkedit output * 00320000
* Attributes: Re-entrant and re-usable * 00330000
* * 00340000
* Entry Point: DSN8ED6 * 00350000
* Purpose: See Function * 00360000
* Linkage: Standard OS/390 linkage * 00370000
* * 00380000
* * 00390000
* Parameters: DSN8ED6 uses the C "main" argument convention of * 00400000
* argv (argument vector) and argc (argument count). * 00410000
* * 00420000
* - ARGV[0] = (input) pointer to a char[9], null- * 00430000
* terminated string having the name of * 00440000
* this program (DSN8ED6) * 00450000
* - ARGV[1] = (input) pointer to a char[32] null- * 00460000
* terminated string having the name of * 00470000
* the WLM environment to be refreshed. * 00480000
* - ARGV[2] = (input) pointer to a char[4], null- * 00490000
* terminated string having the DB2 sub- * 00500000
* system id associated with the WLM * 00510000
* environment to be refreshed * 00520000
* - ARGV[3] = (input) pointer to a char[8], null- * 00530000
* terminated string having the name of a * 00540000
* secondary authorization id that has * 00550000
* access to the resource profile <ssid>.- * 00560000
* WLM_REFRESH.<wlm-environment-name>. * 00570000
* in resource class DSNR. WLM_REFRESH * 00580000
* requires READ access on that profile * 00590000
* in order to fulfill a refresh request. * 00600000
* * 00610000
* Normal Exit: Return Code: 0000 * 00620000
* - Message: none * 00630000
* * 00640000
* Error Exit: Return Code: 1999 * 00650000
* - Message: Error: Invalid call parameter count * 00660000
* Specify either 2 or 3 call para- * 00670000
* meters for DSN8ED6, as follows: * 00680000
* 1. The name of a WLM environment * 00690000
* to be refreshed (1-32 characters)* 00700000
* 2. The DB2 subsystem id (1-4 char- * 00710000
* acters) * 00720000
* 3. A secondary authorization id for * 00730000
* submitting the refresh request * 00740000
* (Optional. 1-8 characters) * 00750000
* * 00760000
* - Message: <formatted SQL text from DSNTIAR> * 00770000
* * 00780000
* * 00790000
* External References: * 00800000
* - Routines/Services: DSNTIAR: DB2 msg text formatter * 00810000
* - Data areas : None * 00820000
* - Control blocks : None * 00830000
* * 00840000
* Pseudocode: * 00850000
* DSN8ED6: * 00860000
* - Verify that number of input parameters passed is either: * 00870000
* - 2 (WLM environment name and DB2 ssid); or * 00880000
* - 3 (WLM environment name, DB2 ssid, and secondary auth id * 00890000
* - Other: issue diagnostic message and end with code 1999 * 00900000
* - Set current SQLID to secondary auth id, if one was passed in * 00910000
* - Call sample stored procedure WLM_REFRESH * 00920000
* - if unsuccessful, call sql_error to issue a diagnostic mes- * 00930000
* sage, then end with code 1999. * 00940000
* - Report the following parameters, passed back from WLM_REFRESH: * 00950000
* - Return code * 00960000
* - Return message * 00970000
* - Set DSN8ED6 return code from WLM_REFRESH return code * 00980000
* End DSN8ED6 * 00990000
* * 01000000
* sql_error: * 01010000
* - call DSNTIAR to format the unexpected SQLCODE. * 01020000
* End sql_error * 01030000
* * 01032000
* Change log: * 01034000
* 01/15/04 PQ79759 - Increase authID to 9 bytes * 01036000
* * 01040000
*********************************************************************/ 01050000
/********************** C library definitions ***********************/ 01060000
#include <stdio.h> 01070000
#include <stdlib.h> 01080000
#include <string.h> 01090000
1158 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
01100000
/***************************** Equates ******************************/ 01110000
#define OUTLEN 80 /* Length of output line */ 01120000
#define DATA_DIM 10 /* Number of message lines */ 01130000
01140000
#define NOT_OK 0 /* Run status indicator: Error*/ 01150000
#define OK 1 /* Run status indicator: Good */ 01160000
01170000
01180000
/******************** DB2 SQL Communication Area ********************/ 01190000
EXEC SQL INCLUDE SQLCA; 01200000
01210000
01220000
/************************ DB2 Host Variables ************************/ 01230000
EXEC SQL BEGIN DECLARE SECTION; 01240000
char wlmEnvName[33]; /* WLM environment name */ 01250000
char ssID[5]; /* Subsystem name */ 01260000
01270000
char authID[9]; /* Current authorization id */ 01280000
01290000
char message[123]; /* WLM_REFRESH return message */ 01300000
long int code; /* WLM_REFRESH return code */ 01310000
EXEC SQL END DECLARE SECTION; 01320000
01330000
/********************** DB2 Message Formatter ***********************/ 01340000
struct error_struct /* DSNTIAR message structure */ 01350000
{ 01360000
short int error_len; 01370000
char error_text[DATA_DIM][OUTLEN]; 01380000
} error_message = {DATA_DIM * (OUTLEN)}; 01390000
01400000
#pragma linkage( dsntiar, OS ) 01410000
01420000
extern short int dsntiar( struct sqlca *sqlca, 01430000
struct error_struct *msg, 01440000
int *len ); 01450000
01460000
/********************* DSN8ED6 Global Variables *********************/ 01470000
short int status = OK; /* DSN8ED6 run status */ 01480000
long int completion_code = 0; /* DSN8ED6 return code */ 01490000
01500000
/******************** DSN8ED6 Function Prototypes *******************/ 01510000
int main( int argc, char *argv[] ); 01520000
void sql_error( char locmsg[] ); 01530000
01540000
01550000
int main( int argc, char *argv[] ) 01560000
/********************************************************************* 01570000
* Get input parms, pass them to DSNTWR, and process the results * 01580000
*********************************************************************/ 01590000
{ printf( "**** DSN8ED6: Sample caller of WLM_REFRESH stored " 01600000
"procedure (DSNTWR)\n" ); 01610000
printf( "*\n" ); 01620000
01630000
if( argc < 3 || argc > 6 ) 01640000
{ printf( "* Error: Invalid call parameter count\n" ); 01650000
printf( "* Specify either 2 or 3 call parameters " 01660000
"for DSN8ED6, as follows:\n" ); 01670000
printf( "* 1. The name of a WLM environment to be " 01680000
"refreshed (1-32 characters)\n" ); 01690000
printf( "* 2. The DB2 subsystem id (1-4 characters)\n" ); 01700000
printf( "* 3. A secondary authorization id for " 01710000
"submitting the refresh request\n" ); 01720000
printf( "* (Optional. 1-8 characters)\n" ); 01730000
status = NOT_OK; 01740000
} 01750000
else if( strlen(argv[1]) < 1 || strlen(argv[1]) > 32 ) 01760000
{ printf( "* Error: The WLM environment name must be 1-32 " 01770000
"characters in length\n" ); 01780000
status = NOT_OK; 01790000
} 01800000
else if( strlen(argv[2]) < 1 || strlen(argv[2]) > 4 ) 01810000
{ printf( "* Error: The DB2 subsystem id must be 1-4 " 01820000
"characters in length\n" ); 01830000
status = NOT_OK; 01840000
} 01850000
else if( argc == 4 && (strlen(argv[3]) < 1 || strlen(argv[3]) > 8) ) 01860000
{ printf( "* Error: The secondary authorization id must be 1-8 " 01870000
"characters in length\n" ); 01880000
status = NOT_OK; 01890000
} 01900000
else 01910000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1159
{ strcpy( wlmEnvName,argv[1] ); 01920000
strcpy( ssID,argv[2] ); 01930000
} 01940000
01950000
/******************************************************************* 01960000
* Change authid if one was passed in * 01970000
*******************************************************************/ 01980000
if( status == OK && argc == 4 ) 01990000
{ strcpy( authID,argv[3] ); 02000000
02010000
EXEC SQL SET CURRENT SQLID = :authID; 02020000
if( SQLCODE != 0 ) 02030000
sql_error( "Error setting SQLID" ); 02040000
} 02050000
02060000
/******************************************************************* 02070000
* Call WLM_REFRESH to refresh the specified WLM environment * 02080000
*******************************************************************/ 02090000
if( status == OK ) 02100000
{ EXEC SQL CALL SYSPROC.WLM_REFRESH( :wlmEnvName, 02110000
:ssID, 02120000
:message, 02130000
:code ); 02140000
if( SQLCODE != 0 ) 02150000
sql_error( "Error calling SYSPROC.WLM_REFRESH" ); 02160000
else 02170000
{ printf( "* Results: WLM_REFRESH returned code %i " 02180000
"and the following message:\n",code ); 02190000
printf( "* %s\n",message ); 02200000
} 02210000
} 02220000
02230000
if( status != OK ) 02240000
completion_code = 1999; 02250000
else 02260000
completion_code = code; 02270000
02280000
return( completion_code ); 02290000
02300000
} /* end main */ 02310000
02320000
02330000
void sql_error( char locmsg[] ) /* SQL message formatter */ 02340000
{ short int rc; /* DSNTIAR Return code */ 02350000
int j,k; /* Loop control */ 02360000
static int lrecl = OUTLEN; /* Width of message lines */ 02370000
02380000
/******************************************************************* 02390000
* set status to prevent further processing * 02400000
*******************************************************************/ 02410000
status = NOT_OK; 02420000
02430000
/******************************************************************* 02440000
* print the locator message * 02450000
*******************************************************************/ 02460000
printf( " %.80s\n", locmsg ); 02470000
02480000
/******************************************************************* 02490000
* format and print the SQL message * 02500000
*******************************************************************/ 02510000
rc = dsntiar( &sqlca, &error_message, &lrecl ); 02520000
if( rc == 0 ) 02530000
for( j=0; j<DATA_DIM; j++ ) 02540000
{ 02550000
for( k=0; k<OUTLEN; k++ ) 02560000
putchar(error_message.error_text[j][k] ); 02570000
putchar('\n'); 02580000
} 02590000
else 02600000
{ 02610000
printf( " *** ERROR: DSNTIAR could not format the message\n" ); 02620000
printf( " *** SQLCODE is %d\n",SQLCODE ); 02630000
printf( " *** SQLERRM is \n" ); 02640000
for( j=0; j<sqlca.sqlerrml; j++ ) 02650000
printf( "%c", sqlca.sqlerrmc[j] ); 02660000
printf( "\n" ); 02670000
} 02680000
02690000
} /* end of sql_error */ 02700000
1160 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSN8ED7
Calls Db2-provided stored procedure ADMIN_INFO_SYSPARM, which returns the current settings of the
Db2 subsystem parameters.
/*********************************************************************
* Module name = DSN8ED7 (DB2 sample program) *
* *
* DESCRIPTIVE NAME = Caller for SYSPROC.ADMIN_INFO_SYSPARM *
* (IFCID 106 formatter stored procedure) *
* *
* Licensed Materials - Property of IBM *
* 5635-DB2 *
* (C) COPYRIGHT 1982, 2006 IBM Corp. All Rights Reserved. *
* *
* STATUS = Version 11 *
* *
* Function: Calls DB2-provided stored procedure ADMIN_INFO_SYSPARM, *
* which returns the current settings of the DB2 subsystem *
* parameters. These settings are then written in *
* report format to standard output. *
* *
* Notes: *
* Dependencies: Requires IBM C/C++ for z/OS *
* *
* Restrictions: *
* *
* Module type: C program *
* Processor: IBM C/C++ for z/OS *
* Module size: See linkedit output *
* Attributes: Re-entrant and re-usable *
* *
* Entry Point: DSN8ED7 *
* Purpose: See Function *
* Linkage: Standard z/OS linkage *
* *
* *
* Parameters: none *
* *
* Normal Exit: Return Code: 0000 *
* - Message: report of DB2 subsystem parameter settings *
* *
* Error Exit: Return Code: 0012 *
* - Message: <formatted SQL text from DSNTIAR> *
* *
* *
* External References: *
* - Routines/Services: DSNTIAR: DB2 msg text formatter *
* - Data areas : None *
* - Control blocks : None *
* *
* Pseudocode: *
* DSN8ED7: *
* - Call ADMIN_INFO_SYSPARM *
* - if unsuccessful, call sql_error to issue a diagnostic mes- *
* sage, then end with code 0012. *
* - Associate a locator variable with the result set *
* - Allocate the result set cursor *
* - Fetch first row from the result set *
* - Print headings *
* - Output the content of the result set's current row and fetch *
* the next row, until are rows have been fetched *
* - Check for successful processing of result set *
* End DSN8ED7 *
* *
* sql_error: *
* - call DSNTIAR to format the unexpected SQLCODE. *
* End sql_error *
* *
* Change activity = *
* 11/07/2012 Convert from SYSPROC.DSNWZP dn1651_inst1 / dn1651 *
* to SYSPROC.ADMIN_INFO_SYSPARM *
* *
*********************************************************************/
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1161
/**************************** Equates *******************************/
#define NOT_OK 0 /* Run status indicator: Error*/
#define OK 1 /* Run status indicator: Good */
/*********************************************************************
* Get DB2's current subsystem and DSNHDECP parameter settings
*********************************************************************/
int main( int argc, char *argv[] )
{
char msgBuf[1400]; /* message buffer */
/*****************************************************************
* Call SYSPROC.ADMIN_INFO_SYSPARM
1162 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
*****************************************************************/
EXEC SQL
CALL SYSPROC.ADMIN_INFO_SYSPARM
( :hvDB2_MEMBER :niDB2_MEMBER
, :hvRETURN_CODE :niRETURN_CODE
, :hvMSG :niMSG
);
/*****************************************************************
* Associate a locator variable with the result set
*****************************************************************/
if( status == OK )
{
EXEC SQL ASSOCIATE LOCATOR
(:DB2_SYSPARM_rs_loc)
WITH PROCEDURE SYSPROC.ADMIN_INFO_SYSPARM;
if (SQLCODE != 0 )
{ sql_error( "*** Associate result set locator "
"call unsuccessful." );
}
}
/*****************************************************************
* Allocate the result set cursor
*****************************************************************/
if( status == OK )
{
EXEC SQL ALLOCATE DB2_SYSPARM_RS_CSR
CURSOR FOR
RESULT SET :DB2_SYSPARM_rs_loc;
if (SQLCODE != 0 )
{ sql_error( "*** Allocate result set cursor "
"call unsuccessful." );
}
}
/*****************************************************************
* Fetch first row from the result set
*****************************************************************/
if( status == OK )
{
EXEC SQL FETCH DB2_SYSPARM_RS_CSR
INTO :hvROWNUM
, :hvMACRO
, :hvPARAMETER
, :hvINSTALL_PANEL :niINSTALL_PANEL
, :hvINSTALL_FIELD :niINSTALL_FIELD
, :hvINSTALL_LOCATION :niINSTALL_LOCATION
, :hvVALUE
, :hvADDITIONAL_INFO
;
if (SQLCODE != 0 )
{ sql_error( "*** Priming fetch of result "
"set cursor unsuccessful" );
}
}
/*****************************************************************
* Write the report header
*****************************************************************/
if( status == OK )
{
printf( "DSN8ED7: Sample DB2 for z/OS "
"Configuration Setting Report Generator\n \n" );
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1163
"Description/ "
"Install Fld \n" );
printf( "Name Name "
"Setting "
"Install Field Name "
"Panel ID No. \n" );
printf( "-------- ------------------------- "
"--------------------------------------- "
"--------------------------------------- "
"-------- ----\n" );
}
/*****************************************************************
* Output the contents of the result set
*****************************************************************/
while( SQLCODE == 0 && status == OK )
{
if( strcmp( hvMACRO,"DSN6SYSP" ) == 0
|| strcmp( hvMACRO,"DSN6LOGP" ) == 0
|| strcmp( hvMACRO,"DSN6ARVP" ) == 0
|| strcmp( hvMACRO,"DSN6SPRM" ) == 0
|| strcmp( hvMACRO,"DSN6FAC" ) == 0
|| strcmp( hvMACRO,"DSN6GRP" ) == 0
|| strcmp( hvMACRO,"DSNHDECP" ) == 0
)
printf( "%-9.8s"
"%-26.25s"
"%-40.39s"
"%-40.39s"
"%-9.8s"
"%4.4s\n"
, hvMACRO
, hvPARAMETER
, hvVALUE
, hvINSTALL_FIELD
, hvINSTALL_PANEL
, hvINSTALL_LOCATION
);
/*****************************************************************
* Check for successful processing of result set
*****************************************************************/
if (SQLCODE != 100 && status == OK )
{ sql_error( "*** Fetch of result set cursor "
"unsuccessful." );
if( status == OK )
return( 0 );
else
return( 12 );
} /* end: main */
/*****************************************************************
* Set status to prevent further processing
*****************************************************************/
status = NOT_OK;
/*****************************************************************
* Print the locator message
*****************************************************************/
printf( " %s\n", locmsg );
/*****************************************************************
1164 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* Format and print the SQL message
*****************************************************************/
rc = dsntiar( &sqlca, &error_message, &lrecl );
if( rc == 0 )
for( j=0; j<DATA_DIM; j++ )
{ for( k=0; k<OUTLEN; k++ )
putchar(error_message.error_text[j][k] );
putchar('\n');
}
else
{ printf( " *** ERROR: DSNTIAR could not format the message\n" );
printf( " *** SQLCODE is %d\n",SQLCODE );
printf( " *** SQLERRM is \n" );
for( j=0; j<sqlca.sqlerrml; j++ )
printf( "%c", sqlca.sqlerrmc[j] );
printf( "\n" );
}
} /* end of sql_error */
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSN8ED9
Demonstrates how to use an application program to call DSN8ES3, a sample native SQL procedure.
/*********************************************************************
* Module name = DSN8ED9 (sample program) *
* *
* DESCRIPTIVE NAME: Sample client for: *
* DSN8ES3 (DB2 sample native SQL procedure) *
* *
* *
* LICENSED MATERIALS - PROPERTY OF IBM *
* 5650-DB2 *
* (C) COPYRIGHT 2006, 2016 IBM CORP. ALL RIGHTS RESERVED. *
* *
* STATUS = VERSION 12 *
* *
* Function: Demonstrates how to use an application program to call *
* DSN8ES3, a sample native SQL procedure. DSN8ED9 *
* receives the schema and name of a stored procedure *
* and passes it to DSN8ES3 to request the CREATE PROCEDURE *
* statement. *
* *
* Notes: *
* Dependencies: Requires DSN8.DSN8ES3 *
* *
* Restrictions: *
* *
* Module type: C program *
* Processor: DB2 Precompiler *
* IBM C/C++ for z/OS *
* Module size: See linkedit output *
* Attributes: Reentrant and reusable *
* *
* Entry point: DSN8ED9 *
* Purpose: See Function *
* Linkage: Standard MVS program invocation, three parameters. *
* *
* Parameters: DSN8ED9 uses the C "main" argument convention of *
* argv (argument vector) and argc (argument count). *
* *
* - ARGV[0]: (input) pointer to a char[9], *
* null-terminated string having the name of *
* this program (DSN8ED9) *
* - ARGV[1]: (input) pointer to a char[129], *
* null-terminated string having the schema *
* of a stored procedure *
* - ARGV[2]: (input) pointer to a char[129], *
* null-terminated string having the name of *
* a stored procedure *
* - ARGV[3]: (input) pointer to a char[17], *
* null-terminated string having the name of *
* the server where DSN8ES3 is to be run. *
* This is an optional parameter; the local *
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1165
* server is used if no argument is provided. *
* *
* Inputs: None *
* *
* Outputs: Standard output (SYSPRINT) *
* *
* Normal Exit: Return Code: 0 *
* - Message: CREATE PROCEDURE statement for specified *
* stored procedure *
* *
* Normal with Warnings Exit: Return Code: 0004 *
* - Message: DSN8ES3 ran successfully but returned *
* no output *
* *
* Error Exit: Return Code: 0012 *
* - Message: DSN8ES3 has completed with return code <n> *
* - Message: The length of the argument specified for *
* the <parameter-name> does not fall within *
* the required bounds of <minimum-length> *
* and <maximum-length> *
* - Message: DSN8ED9 was invoked with <parameter-count> *
* parameters. At least 2 parameters are *
* required *
* - Message: <formatted SQL text from DSNTIAR> *
* *
* External References: *
* - Routines/Services: DSNTIAR: DB2 msg text formatter *
* - Data areas : None *
* - Control blocks : None *
* *
* *
* Pseudocode: *
* DSN8ED9: *
* - call getCallParms to receive and validate call parm arguments*
* - call connectToLocation *
* - call callDSN8ES3 to invoke the sample native SQL procedure *
* - call processDSN8ES3resultSet to output results from DSN8ES3 *
* End DSN8ED9 *
* *
* *
* Change activity = *
* 04/22/2015 Storage overlay stops output d176357 *
* *
*********************************************************************/
1166 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
static volatile SQL TYPE IS RESULT_SET_LOCATOR *DSN8ES3_rs_loc;
EXEC SQL END DECLARE SECTION;
/*****************************************************************
* Extract the following information from the call parms: *
* (1) The schema of the stored procedure *
* (2) The name of the stored procedure *
* (3) Optional: The name of the location where the stored proc *
* resides *
*****************************************************************/
getCallParms( argc,argv );
/*****************************************************************
* Connect to location where the stored procedure resides *
*****************************************************************/
if( rc < RETSEV && strlen(hvLocationName) > 0 )
connectToLocation();
return( rc );
} /* end main */
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1167
*******************************************************************/
{ if( argc < 3 || argc > 4 )
{ issueInvalidCallParmCountError( argc );
}
else if( strlen( argv[1] ) < 1 || strlen( argv[1] ) > 130 )
{ issueInvalidParmLengthError("Stored procedure schema",
1,130);
}
else if( strlen( argv[2] ) < 1 || strlen( argv[1] ) > 130 )
{ issueInvalidParmLengthError("Stored procedure name",
1,130);
}
else
{ strcpy( hvSpSchema, argv[1] );
strcpy( hvSpName, argv[2] );
}
} /* end of getCallParms */
if( SQLCODE != 0 )
{ issueSqlError( "Connect to location failed" );
}
} /* end of connectToLocation */
/*****************************************************************
* Analyze status codes from DSN8ES3 *
*****************************************************************/
if( SQLCODE == 466 )
{ resultSetReturned = Yes;
}
else if( SQLCODE == 0 )
{ resultSetReturned = No;
printf( "\n");
printf( "-> Call to DSN8ES3 succeeded "
"but returned no result\n" );
}
else
{ issueSqlError( "Call to DSN8ES3 failed" );
}
} /* end of callDSN8ES3 */
1168 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
/*****************************************************************
* Allocate a cursor for the result set *
*****************************************************************/
if( rc < RETSEV )
allocateResultSetCursor();
/*****************************************************************
* Output data from the result set *
*****************************************************************/
if( rc < RETSEV )
writeDSN8ES3results();
} /* end of processDSN8ES3resultSet */
if( SQLCODE != 0 )
{ issueSqlError( "Associate locator call failed" );
}
} /* end of associateResultSetLocator */
if( SQLCODE != 0 )
{ issueSqlError( "Allocate result set cursor call failed" );
}
} /* end of allocateResultSetCursor */
/*****************************************************************
* Process all rows in the result set *
*****************************************************************/
while( SQLCODE == 0 && rc < RETSEV )
{ printf( "%s\n",hvLine );
} /* end of writeDSN8ES3results */
EXEC SQL
FETCH DSN8ES3_RS_CSR
INTO :hvSequence,
:hvLine;
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1169
}
} /* end of fetchFromResultSetCursor */
/*****************************************************************
* print the locator message *
*****************************************************************/
printf( "ERROR: %-80s\n", locMsg );
printf( "-----> Processing halted\n" );
/*****************************************************************
* format and print the SQL message *
*****************************************************************/
DSNTIARrc = dsntiar( &sqlca, &error_message, &lrecl );
if( DSNTIARrc == 0 )
for( j = 0; j <= 10; j++ )
printf( " %.80s\n", error_message.error_text[j] );
else
{
printf( " *** ERROR: DSNTIAR could not format the message\n" );
printf( " *** SQLCODE is %d\n",SQLCODE );
printf( " *** SQLERRM is \n" );
for( j=0; j<sqlca.sqlerrml; j++ )
printf( "%c", sqlca.sqlerrmc[j] );
printf( "\n" );
}
1170 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
/*****************************************************************
* set severe error code *
*****************************************************************/
rc = RETSEV;
} /* end of issueSqlError */
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSN8ES3
Accepts the schema and name of an external stored procedure and returns a result set that contains the
CREATE PROCEDURE statement.
-- DSN8ES3: SOURCE MODULE FOR THE SAMPLE NATIVE SQL PROCEDURE 00010000
-- 00020000
-- LICENSED MATERIALS - PROPERTY OF IBM 00022000
-- 5635-DB2 00024000
-- (C) COPYRIGHT 2006 IBM CORP. ALL RIGHTS RESERVED. 00026000
-- 00028000
-- STATUS = VERSION 9 00030000
-- 00040000
-- Function: Accepts the schema and name of an external stored 00050000
-- procedure and returns a result set that contains the 00060000
-- CREATE PROCEDURE statement. 00070000
-- 00080000
-- Notes: 00090000
-- Dependencies: 00100000
-- - Requires support for native SQL procedures 00110000
-- - Requires a global temporary table (created in sample job 00120000
-- DSNTEJ66) for returning the result. 00130000
-- 00140000
-- Restrictions: 00150000
-- 00160000
-- Module Type: SQL Procedure 00170000
-- Processor: DB2 for z/OS Version 9 00180000
-- or a subsequent release 00190000
-- 00200000
-- Entry Point: DSN8ES3 00210000
-- Purpose: See Function, above 00220000
-- 00230000
-- Parameters: 00240000
-- - Input: spSCHEMA VARCHAR(128) 00250000
-- spNAME VARCHAR(128) 00260000
-- - Output: (None) 00270000
-- 00280000
-- Normal Exit: 00290000
-- Error Exit: 00300000
-- 00310000
-- 00320000
-- External References: 00330000
-- - SYSIBM.SYSROUTINES : DB2 catalog table for routines 00340000
-- - SYSIBM.SYSPARMS : DB2 catalog table for routine parameters 00350000
-- - DSN8.DSN8ES3_RS_TBL: Global Temporary Table for result set 00360000
-- 00370000
-- Pseudocode: 00380000
-- - Clear any residual from result set table 00390000
-- - Get the stored proc properties from SYSIBM.SYSROUTINES 00400000
-- - If not found, return SQLSTATE 38602 and the message: 00410000
-- 'Requested object not found' 00420000
-- - If not a stored proc, return SQLSTATE 38603 and the message: 00430000
-- 'Object is not a stored procedure' 00440000
-- - If not an external stored proc, return SQLSTATE 38604 and the 00450000
-- message: 'Object is not an external stored procedure' 00460000
-- - Open a cursor on the SYSPARMS table 00470000
-- - Fetch the first row 00480000
-- - If a row is found, insert the CREATE PROCEDURE clause in the 00490000
-- result set 00500000
-- - For each row in the SYSPARMS cursor, build a parameter clause: 00510000
-- - Start with the parameter type (IN, OUT, or INOUT) 00520000
-- - Append the parameter name 00530000
-- - Append the parameter data type 00540000
-- - For string data types, add the CCSID clause 00550000
-- - Insert the entry in the result set table 00560000
-- - Build the remaining clauses and insert each in the result set 00570000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1171
-- - Build and insert the RESULTS SETS clause 00580000
-- - Build and insert the EXTERNAL NAME clause 00590000
-- - Build and insert the LANGUAGE clause 00600000
-- - Build and insert the SQL data access type clause 00610000
-- - Build and insert the PARAMETER STYLE clause 00620000
-- - Build and insert the DETERMINISTIC clause 00630000
-- - Build and insert the FENCED clause 00640000
-- - Build and insert the COLLID clause 00650000
-- - Build and insert the WLM ENVIRONMENT clause 00660000
-- - Build and insert the ASUTIME clause 00670000
-- - Build and insert the STAY RESIDENT clause 00680000
-- - Build and insert the PROGRAM TYPE clause 00690000
-- - Build and insert the EXTERNAL SECURITY clause 00700000
-- - Build and insert the AFTER FAILURE clause 00710000
-- - Build and insert the RUN OPTIONS clause 00720000
-- - Build and insert the COMMIT ON RETURN clause 00730000
-- - Build and insert the SPECIAL REGISTERS clause 00740000
-- - Build and insert the CALLED ON NULL INPUT clause 00750000
-- - Open the cursor to the result set 00760000
-- 00762000
-- CHANGE ACTIVITY 00764000
-- 10/31/2013 Ignore SYSPARMS rows where ORDINAL = 0 PM98341 00766000
-- 00768000
-- 00770000
CREATE PROCEDURE DSN8.DSN8ES3 00780000
( IN spSCHEMA VARCHAR(128), 00790000
IN spNAME VARCHAR(128) ) 00800000
PARAMETER CCSID EBCDIC 00810000
RESULT SET 1 00820000
NOT DETERMINISTIC 00830000
MODIFIES SQL DATA 00840000
ASUTIME NO LIMIT 00850000
COMMIT ON RETURN NO 00860000
00870000
P1: BEGIN NOT ATOMIC 00880000
DECLARE hvLANGUAGE VARCHAR(24) CCSID EBCDIC; 00890000
DECLARE hvCOLLID VARCHAR(128) CCSID EBCDIC; 00900000
DECLARE hvDETERMINISTIC VARCHAR(17) CCSID EBCDIC; 00910000
DECLARE hvNULL_CALL CHAR(1) CCSID EBCDIC; 00920000
DECLARE hvPARAMETER_STYLE VARCHAR(18) CCSID EBCDIC; 00930000
DECLARE hvFENCED CHAR(1) CCSID EBCDIC; 00940000
DECLARE hvASUTIME INTEGER DEFAULT 0; 00950000
DECLARE hvCOMMIT_ON_RETURN VARCHAR(3) CCSID EBCDIC; 00960000
DECLARE hvEXTERNAL_NAME VARCHAR(762) CCSID EBCDIC; 00970000
DECLARE hvEXTERNAL_SECURITY VARCHAR(7) CCSID EBCDIC; 00980000
DECLARE hvMAX_FAILURE SMALLINT DEFAULT 0; 00990000
DECLARE hvORIGIN CHAR(1) CCSID EBCDIC; 01000000
DECLARE hvPROGRAM_TYPE VARCHAR(4) CCSID EBCDIC; 01010000
DECLARE hvRESULT_SETS SMALLINT DEFAULT 0; 01020000
DECLARE hvROUTINETYPE CHAR(1) CCSID EBCDIC; 01030000
DECLARE hvRUNOPTS VARCHAR(762) CCSID EBCDIC; 01040000
DECLARE hvSPECIAL_REGS VARCHAR(25) CCSID EBCDIC; 01050000
DECLARE hvSQL_DATA_ACCESS VARCHAR(17) CCSID EBCDIC; 01060000
DECLARE hvSTAYRESIDENT VARCHAR(3) CCSID EBCDIC; 01070000
DECLARE hvWLM_ENVIRONMENT VARCHAR(54) CCSID EBCDIC; 01080000
01090000
DECLARE hvENCODING_SCHEME VARCHAR(7) CCSID EBCDIC; 01100000
DECLARE hvLENGTH INTEGER DEFAULT 0; 01110000
DECLARE hvORDINAL SMALLINT DEFAULT 0; 01120000
DECLARE hvPARMNAME VARCHAR(128) CCSID EBCDIC; 01130000
DECLARE hvROWTYPE VARCHAR(6) CCSID EBCDIC; 01140000
DECLARE hvSCALE SMALLINT DEFAULT 0; 01150000
DECLARE hvSUBTYPE VARCHAR(15) CCSID EBCDIC; 01160000
DECLARE hvTYPENAME VARCHAR(128) CCSID EBCDIC; 01170000
01180000
DECLARE RETURN_POINT CHAR(4) CCSID EBCDIC; 01190000
01200000
DECLARE LINE VARCHAR(384) CCSID EBCDIC; 01210000
DECLARE LINE_LENGTH INT DEFAULT 0; 01220000
DECLARE END_TABLE INT DEFAULT 0; 01230000
01240000
DECLARE OPERATION VARCHAR(12) CCSID EBCDIC; 01250000
01260000
DECLARE ROW CHAR(80) CCSID EBCDIC; 01270000
DECLARE ROW_SEQUENCE SMALLINT DEFAULT 1; 01280000
01290000
-- Cursor for result set (CREATE PROCEDURE statement) 01300000
DECLARE DSN8ES3_RS_CSR CURSOR WITH RETURN WITH HOLD FOR 01310000
SELECT RS_SEQUENCE, 01320000
RS_LINE 01330000
FROM DSN8.DSN8ES3_RS_TBL 01340000
ORDER BY RS_SEQUENCE; 01350000
1172 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
01360000
-- Cursor to fetch proc parm properties from SYSIBM.SYSPARMS 01370000
DECLARE SYSPARMS_CURSOR CURSOR FOR 01380000
SELECT PARMNAME 01390000
,CASE ROWTYPE 01400000
WHEN 'P' THEN 'IN ' 01410000
WHEN 'O' THEN 'OUT ' 01420000
WHEN 'B' THEN 'INOUT ' 01430000
END 01440000
,ORDINAL 01450000
,TYPENAME 01460000
,LENGTH 01470000
,SCALE 01480000
,CASE SUBTYPE 01490000
WHEN 'B' THEN ' FOR BIT DATA' 01500000
WHEN 'M' THEN ' FOR MIXED DATA' 01510000
WHEN 'S' THEN ' FOR SBCS DATA' 01520000
WHEN ' ' THEN ' ' 01530000
END 01540000
,CASE ENCODING_SCHEME 01550000
WHEN 'A' THEN ' ASCII' 01560000
WHEN 'E' THEN ' EBCDIC' 01570000
WHEN 'U' THEN ' UNICODE' 01580000
WHEN ' ' THEN ' ' 01590000
END 01600000
FROM SYSIBM.SYSPARMS 01610000
WHERE SCHEMA = spSCHEMA 01620000
AND SPECIFICNAME = spNAME 01630000
AND ORDINAL <> 0 01635000
ORDER BY ORDINAL 01640000
FOR FETCH ONLY; 01650000
01660000
DECLARE CONTINUE HANDLER FOR NOT FOUND 01670000
SET END_TABLE = 1; 01680000
01690000
DECLARE EXIT HANDLER FOR SQLEXCEPTION 01700000
SIGNAL SQLSTATE '38601' 01710000
SET MESSAGE_TEXT = 'Unexpected SQLCODE ' 01720000
|| CHAR(SQLCODE) 01730000
|| ' from ' 01740000
|| OPERATION; 01750000
01760000
-- Clean residual from the result set table 01770000
DELETE FROM DSN8.DSN8ES3_RS_TBL; 01780000
01790000
-- Fetch the stored proc properties from SYSIBM.SYSROUTINES 01800000
SET END_TABLE = 0; 01810000
SET OPERATION = 'SELECT INTO'; 01820000
SELECT LANGUAGE 01830000
,COLLID 01840000
,CASE DETERMINISTIC 01850000
WHEN 'N' THEN 'NOT DETERMINISTIC' 01860000
WHEN 'Y' THEN 'DETERMINISTIC' 01870000
WHEN ' ' THEN ' ' 01880000
END 01890000
,NULL_CALL 01900000
,CASE PARAMETER_STYLE 01910000
WHEN 'D' THEN 'DB2SQL' 01920000
WHEN 'G' THEN 'GENERAL' 01930000
WHEN 'N' THEN 'GENERAL WITH NULLS' 01940000
WHEN 'J' THEN 'JAVA' 01950000
WHEN ' ' THEN ' ' 01960000
END 01970000
,FENCED 01980000
,CASE SQL_DATA_ACCESS 01990000
WHEN 'C' THEN 'CONTAINS SQL' 02000000
WHEN 'M' THEN 'MODIFIES SQL DATA' 02010000
WHEN 'N' THEN 'NO SQL' 02020000
WHEN 'R' THEN 'READS SQL DATA' 02030000
WHEN ' ' THEN ' ' 02040000
END 02050000
,CASE STAYRESIDENT 02060000
WHEN 'N' THEN 'NO' 02070000
WHEN 'Y' THEN 'YES' 02080000
WHEN ' ' THEN ' ' 02090000
END 02100000
,ASUTIME 02110000
,WLM_ENVIRONMENT 02120000
,CASE PROGRAM_TYPE 02130000
WHEN 'M' THEN 'MAIN' 02140000
WHEN 'S' THEN 'SUB' 02150000
WHEN ' ' THEN ' ' 02160000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1173
END 02170000
,CASE EXTERNAL_SECURITY 02180000
WHEN 'D' THEN 'DB2' 02190000
WHEN 'U' THEN 'USER' 02200000
WHEN 'C' THEN 'DEFINER' 02210000
WHEN ' ' THEN ' ' 02220000
END 02230000
,CASE COMMIT_ON_RETURN 02240000
WHEN 'N' THEN 'NO' 02250000
WHEN 'Y' THEN 'YES' 02260000
WHEN ' ' THEN ' ' 02270000
END 02280000
,RESULT_SETS 02290000
,EXTERNAL_NAME 02300000
,RUNOPTS 02310000
,CASE SPECIAL_REGS 02320000
WHEN 'D' THEN 'DEFAULT SPECIAL REGISTERS' 02330000
WHEN 'I' THEN 'INHERIT SPECIAL REGISTERS' 02340000
WHEN ' ' THEN ' ' 02350000
END 02360000
,MAX_FAILURE 02370000
INTO hvLANGUAGE 02380000
,hvCOLLID 02390000
,hvDETERMINISTIC 02400000
,hvNULL_CALL 02410000
,hvPARAMETER_STYLE 02420000
,hvFENCED 02430000
,hvSQL_DATA_ACCESS 02440000
,hvSTAYRESIDENT 02450000
,hvASUTIME 02460000
,hvWLM_ENVIRONMENT 02470000
,hvPROGRAM_TYPE 02480000
,hvEXTERNAL_SECURITY 02490000
,hvCOMMIT_ON_RETURN 02500000
,hvRESULT_SETS 02510000
,hvEXTERNAL_NAME 02520000
,hvRUNOPTS 02530000
,hvSPECIAL_REGS 02540000
,hvMAX_FAILURE 02550000
FROM SYSIBM.SYSROUTINES 02560000
WHERE SCHEMA = spSCHEMA 02570000
AND NAME = spNAME; 02580000
02590000
02600000
CASE 02610000
WHEN END_TABLE = 1 THEN 02620000
SIGNAL SQLSTATE '38602' 02630000
SET MESSAGE_TEXT = 'Requested object "' 02640000
|| spSCHEMA 02650000
|| '"."' 02660000
|| spNAME 02670000
|| '" not found'; 02680000
WHEN hvROUTINETYPE <> 'P' THEN 02690000
SIGNAL SQLSTATE '38603' 02700000
SET MESSAGE_TEXT = 'Object is not a stored procedure'; 02710000
WHEN hvORIGIN <> 'E' THEN 02720000
SIGNAL SQLSTATE '38604' 02730000
SET MESSAGE_TEXT = 'Object is not an external stored procedure'; 02740000
ELSE -- NOOP below provided to satisfy requirement for ELSE clause 02750000
SET ROW_SEQUENCE = ROW_SEQUENCE; 02760000
END CASE; 02770000
02780000
SET END_TABLE = 0; 02790000
SET OPERATION = 'OPEN CURSOR'; 02800000
OPEN SYSPARMS_CURSOR; 02810000
02820000
SET OPERATION = 'FIRST FETCH'; 02830000
FETCH SYSPARMS_CURSOR 02840000
INTO hvPARMNAME 02850000
,hvROWTYPE 02860000
,hvORDINAL 02870000
,hvTYPENAME 02880000
,hvLENGTH 02890000
,hvSCALE 02900000
,hvSUBTYPE 02910000
,hvENCODING_SCHEME; 02920000
02930000
-- Output the CREATE PROCEDURE clause 02940000
IF END_TABLE = 0 THEN 02950000
SET LINE = 'CREATE PROCEDURE ' || spSCHEMA || '.' || spNAME; 02960000
SET RETURN_POINT = 'A100'; 02970000
GOTO INSERTLINE; 02980000
1174 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
END IF; 02990000
03000000
A100: -- Build and output the parameter list 03010000
SET LINE = ' ( '; 03020000
WHILE END_TABLE = 0 DO 03030000
-- Output the parameter type (IN, OUT, or INOUT) 03040000
SET LINE = LINE 03050000
|| hvROWTYPE || ' ' 03060000
|| hvPARMNAME || ' ' 03070000
|| RTRIM(hvTYPENAME); 03080000
CASE 03090000
WHEN hvTYPENAME = 'DECIMAL' 03100000
OR hvTYPENAME = 'DEC' 03110000
OR hvTYPENAME = 'NUMERIC' THEN 03120000
SET LINE = LINE || '(' || VARCHAR(hvLENGTH) 03130000
|| ',' || VARCHAR(hvSCALE) || ')'; 03140000
03150000
WHEN hvTYPENAME = 'FLOAT' THEN 03160000
SET LINE = LINE || '(' || VARCHAR(hvLENGTH) || ')'; 03170000
03180000
WHEN hvTYPENAME = 'CHARACTER' 03190000
OR hvTYPENAME = 'CHAR' 03200000
OR hvTYPENAME = 'CHARACTER VARYING' 03210000
OR hvTYPENAME = 'CHAR VARYING' 03220000
OR hvTYPENAME = 'VARCHAR' 03230000
OR hvTYPENAME = 'CHARACTER LARGE OBJECT' 03240000
OR hvTYPENAME = 'CHAR LARGE OBJECT' 03250000
OR hvTYPENAME = 'CLOB' 03260000
OR hvTYPENAME = 'GRAPHIC' 03270000
OR hvTYPENAME = 'VARGRAPHIC' 03280000
OR hvTYPENAME = 'DBCLOB' 03290000
OR hvTYPENAME = 'BINARY LARGE OBJECT' 03300000
OR hvTYPENAME = 'BLOB' THEN 03310000
SET LINE = LINE || '(' || VARCHAR(hvLENGTH) || ')'; 03320000
03330000
ELSE -- busy statement below required to handle ELSE case 03340000
SET ROW_SEQUENCE = ROW_SEQUENCE; 03350000
END CASE; 03360000
03370000
IF hvSUBTYPE <> ' ' THEN 03380000
SET LINE = LINE || hvSUBTYPE; 03390000
END IF; 03400000
IF hvENCODING_SCHEME <> ' ' THEN 03410000
SET LINE = LINE || ' CCSID' || RTRIM(hvENCODING_SCHEME); 03420000
END IF; 03430000
SET RETURN_POINT = 'B100'; 03440000
GOTO INSERTLINE; 03450000
03460000
B100: -- Fetch the next parameter 03470000
SET OPERATION = 'FETCH'; 03480000
FETCH SYSPARMS_CURSOR 03490000
INTO hvPARMNAME 03500000
,hvROWTYPE 03510000
,hvORDINAL 03520000
,hvTYPENAME 03530000
,hvLENGTH 03540000
,hvSCALE 03550000
,hvSUBTYPE 03560000
,hvENCODING_SCHEME; 03570000
03580000
SET LINE = ' ,'; 03590000
END WHILE; 03600000
03610000
SET OPERATION = 'CLOSE CURSOR'; 03620000
CLOSE SYSPARMS_CURSOR; 03630000
-- Close the parameter list 03640000
SET LINE = ' )'; 03650000
SET RETURN_POINT = 'C100'; 03660000
GOTO INSERTLINE; 03670000
03680000
C100: -- Build remaining clauses for the CREATE PROCEDURE statement 03690000
03700000
-- Output the RESULTS SETS clause 03710000
IF hvRESULT_SETS > 0 THEN 03720000
SET LINE = 'DYNAMIC RESULT SETS ' || VARCHAR(hvRESULT_SETS); 03730000
SET RETURN_POINT = 'D100'; 03740000
GOTO INSERTLINE; 03750000
END IF; 03760000
03770000
D100: -- Output the EXTERNAL NAME clause 03780000
SET LINE = 'EXTERNAL NAME ' || RTRIM(hvEXTERNAL_NAME); 03790000
SET RETURN_POINT = 'E100'; 03800000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1175
GOTO INSERTLINE; 03810000
03820000
E100: -- Output the LANGUAGE clause 03830000
SET LINE = 'LANGUAGE ' || RTRIM(hvLANGUAGE); 03840000
SET RETURN_POINT = 'F100'; 03850000
GOTO INSERTLINE; 03860000
03870000
F100: -- Output the SQL data access type clause 03880000
IF hvSQL_DATA_ACCESS <> ' ' THEN 03890000
SET LINE = hvSQL_DATA_ACCESS; 03900000
SET RETURN_POINT = 'G100'; 03910000
GOTO INSERTLINE; 03920000
END IF; 03930000
03940000
G100: -- Output the PARAMETER STYLE clause 03950000
IF hvPARAMETER_STYLE <> ' ' THEN 03960000
SET LINE = 'PARAMETER STYLE ' || hvPARAMETER_STYLE; 03970000
SET RETURN_POINT = 'H100'; 03980000
GOTO INSERTLINE; 03990000
END IF; 04000000
04010000
H100: -- Output the DETERMINISTIC clause 04020000
IF hvDETERMINISTIC <> ' ' THEN 04030000
SET LINE = hvDETERMINISTIC; 04040000
SET RETURN_POINT = 'I100'; 04050000
GOTO INSERTLINE; 04060000
END IF; 04070000
04080000
I100: -- Output the FENCED clause 04090000
IF hvFENCED <> ' ' THEN 04100000
SET LINE = 'FENCED'; 04110000
SET RETURN_POINT = 'J100'; 04120000
GOTO INSERTLINE; 04130000
END IF; 04140000
04150000
J100: -- Output the COLLID clause 04160000
IF hvCOLLID <> ' ' THEN 04170000
SET LINE = 'COLLID ' || RTRIM(hvCOLLID); 04180000
ELSE 04190000
SET LINE = 'NO COLLID'; 04200000
END IF; 04210000
SET RETURN_POINT = 'K100'; 04220000
GOTO INSERTLINE; 04230000
04240000
K100: -- Output the WLM ENVIRONMENT clause 04250000
SET LINE = 'WLM ENVIRONMENT ' || RTRIM(hvWLM_ENVIRONMENT); 04260000
SET RETURN_POINT = 'L100'; 04270000
GOTO INSERTLINE; 04280000
04290000
L100: -- Output the ASUTIME clause 04300000
IF hvASUTIME <> 0 THEN 04310000
SET LINE = 'ASUTIME ' || VARCHAR(hvASUTIME); 04320000
ELSE 04330000
SET LINE = 'ASUTIME NO LIMIT'; 04340000
END IF; 04350000
SET RETURN_POINT = 'M100'; 04360000
GOTO INSERTLINE; 04370000
04380000
M100: -- Output the STAY RESIDENT clause 04390000
IF hvSTAYRESIDENT <> ' ' THEN 04400000
SET LINE = 'STAY RESIDENT ' || hvSTAYRESIDENT; 04410000
SET RETURN_POINT = 'N100'; 04420000
GOTO INSERTLINE; 04430000
END IF; 04440000
04450000
N100: -- Output the PROGRAM TYPE clause 04460000
IF hvPROGRAM_TYPE <> ' ' THEN 04470000
SET LINE = 'PROGRAM TYPE ' || hvPROGRAM_TYPE; 04480000
SET RETURN_POINT = 'O100'; 04490000
GOTO INSERTLINE; 04500000
END IF; 04510000
04520000
O100: -- Output the EXTERNAL SECURITY clause 04530000
IF hvEXTERNAL_SECURITY <> ' ' THEN 04540000
SET LINE = 'SECURITY ' || hvEXTERNAL_SECURITY; 04550000
SET RETURN_POINT = 'P100'; 04560000
GOTO INSERTLINE; 04570000
END IF; 04580000
04590000
P100: -- Output the AFTER FAILURE clause 04600000
IF hvMAX_FAILURE = -1 THEN 04610000
SET LINE = 'STOP AFTER SYSTEM DEFAULT FAILURES'; 04620000
1176 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
ELSEIF hvMAX_FAILURE = 0 THEN 04630000
SET LINE = 'CONTINUE AFTER FAILURE'; 04640000
ELSE 04650000
SET LINE = 'STOP AFTER ' || VARCHAR(hvMAX_FAILURE) || ' FAILURES'; 04660000
END IF; 04670000
SET RETURN_POINT = 'Q100'; 04680000
GOTO INSERTLINE; 04690000
04700000
Q100: -- Output the RUN OPTIONS clause 04710000
IF hvRUNOPTS <> ' ' THEN 04720000
SET LINE = 'RUN OPTIONS ''' || hvRUNOPTS || ''''; 04730000
SET RETURN_POINT = 'R100'; 04740000
GOTO INSERTLINE; 04750000
END IF; 04760000
04770000
R100: -- Output the COMMIT ON RETURN clause 04780000
IF hvCOMMIT_ON_RETURN <> ' ' THEN 04790000
SET LINE = 'COMMIT ON RETURN ' || hvCOMMIT_ON_RETURN; 04800000
SET RETURN_POINT = 'S100'; 04810000
GOTO INSERTLINE; 04820000
END IF; 04830000
04840000
S100: -- Output the SPECIAL REGISTERS clause 04850000
IF hvSPECIAL_REGS <> ' ' THEN 04860000
SET LINE = hvSPECIAL_REGS; 04870000
SET RETURN_POINT = 'T100'; 04880000
GOTO INSERTLINE; 04890000
END IF; 04900000
04910000
T100: -- Output the CALLED ON NULL INPUT clause 04920000
IF hvNULL_CALL = 'Y' THEN 04930000
SET LINE = 'CALLED ON NULL INPUT'; 04940000
SET RETURN_POINT = 'U100'; 04950000
GOTO INSERTLINE; 04960000
END IF; 04970000
04980000
U100: -- Finish up 04990000
GOTO DONE; 05000000
05010000
INSERTLINE: 05020000
SET LINE_LENGTH = LENGTH(LINE); 05030000
WHILE LINE_LENGTH > 72 DO 05040000
SET ROW = SUBSTR(LINE, 1, 72) || REPEAT( ' ', 8 ); 05050000
SET LINE = SUBSTR(LINE, 73, LINE_LENGTH-72); 05060000
SET LINE_LENGTH = LENGTH(LINE); 05070000
05080000
SET ROW_SEQUENCE = ROW_SEQUENCE + 1; 05090000
INSERT INTO DSN8.DSN8ES3_RS_TBL 05100000
( RS_SEQUENCE, 05110000
RS_LINE ) 05120000
VALUES( P1.ROW_SEQUENCE, 05130000
P1.ROW ); 05140000
END WHILE; 05150000
05160000
SET ROW = SUBSTR( (LINE || REPEAT(' ', 80)), 1, 80); 05170000
SET ROW_SEQUENCE = ROW_SEQUENCE + 1; 05180000
SET OPERATION = 'INSERT'; 05190000
INSERT INTO DSN8.DSN8ES3_RS_TBL 05200000
( RS_SEQUENCE, 05210000
RS_LINE ) 05220000
VALUES( P1.ROW_SEQUENCE, 05230000
P1.ROW ); 05240000
CASE RETURN_POINT 05250000
WHEN 'A100' THEN GOTO A100; 05260000
WHEN 'B100' THEN GOTO B100; 05270000
WHEN 'C100' THEN GOTO C100; 05280000
WHEN 'D100' THEN GOTO D100; 05290000
WHEN 'E100' THEN GOTO E100; 05300000
WHEN 'F100' THEN GOTO F100; 05310000
WHEN 'G100' THEN GOTO G100; 05320000
WHEN 'H100' THEN GOTO H100; 05330000
WHEN 'I100' THEN GOTO I100; 05340000
WHEN 'J100' THEN GOTO J100; 05350000
WHEN 'K100' THEN GOTO K100; 05360000
WHEN 'L100' THEN GOTO L100; 05370000
WHEN 'M100' THEN GOTO M100; 05380000
WHEN 'N100' THEN GOTO N100; 05390000
WHEN 'O100' THEN GOTO O100; 05400000
WHEN 'P100' THEN GOTO P100; 05410000
WHEN 'Q100' THEN GOTO Q100; 05420000
WHEN 'R100' THEN GOTO R100; 05430000
WHEN 'S100' THEN GOTO S100; 05440000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1177
WHEN 'T100' THEN GOTO T100; 05450000
WHEN 'U100' THEN GOTO U100; 05460000
ELSE GOTO DONE; 05470000
END CASE; 05480000
05490000
DONE: 05500000
-- Open the cursor to the result set 05510000
SET OPERATION = 'RS CURSOR'; 05520000
OPEN DSN8ES3_RS_CSR; 05530000
END P1 05540000
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSN8DUAD
Returns the current date in one these 34 formats.
/********************************************************************* 00010000
* Module name = DSN8DUAD (DB2 sample program) * 00020000
* * 00030000
* DESCRIPTIVE NAME = Current date reformatter (UDF) * 00040000
* * 00050000
* * 00060000
* LICENSED MATERIALS - PROPERTY OF IBM * 00070000
* 5625-DB2 * 00080000
* (C) COPYRIGHT 1998, 2003 IBM CORP. ALL RIGHTS RESERVED. * 00090000
* * 00100000
* STATUS = VERSION 8 * 00110000
* * 00120000
* * 00130000
* Function: Returns the current date in one these 34 formats: * 00140000
* * 00150000
* D MONTH YY D MONTH YYYY DD MONTH YY DD MONTH YYYY * 00160000
* D.M.YY D.M.YYYY DD.MM.YY DD.MM.YYYY * 00170000
* D-M-YY D-M-YYYY DD-MM-YY DD-MM-YYYY * 00180000
* D/M/YY D/M/YYYY DD/MM/YY DD/MM/YYYY * 00190000
* M/D/YY M/D/YYYY MM/DD/YY MM/DD/YYYY * 00200000
* YY/M/D YYYY/M/D YY/MM/DD YYYY/MM/DD * 00210000
* YY.M.D YYYY.M.D YY.MM.DD YYYY.MM.DD * 00220000
* YYYY-M-D YYYY-MM-DD * 00230000
* YYYY-D-XX YYYY-DD-XX * 00240000
* YYYY-XX-D YYYY-XX-DD * 00250000
* * 00260000
* where: * 00270000
* * 00280000
* D: Suppress leading zero if the day is less than 10 * 00290000
* DD: Retain leading zero if the day is less than 10 * 00300000
* M: Suppress leading zero if the month is less than 10 * 00310000
* MM: Retain leading zero if the month is less than 10 * 00320000
* MONTH: Use English-language name of month * 00330000
* XX: Use a capital Roman numeral for month * 00340000
* XX: Use a capital Roman numeral for month * 00350000
* YY: Use non-century year format * 00360000
* YYYY: Use century year format * 00370000
* * 00380000
* Example invocation: * 00390000
* EXEC SQL SET :today = ALTDATE( "DD MONTH YY" ); * 00400000
* * 00410000
* Notes: * 00420000
* Dependencies: Requires IBM C/C++ for OS/390 V1R3 or higher * 00430000
* * 00440000
* Restrictions: * 00450000
* * 00460000
* Module type: C program * 00470000
* Processor: IBM C/C++ for OS/390 V1R3 or higher * 00480000
* Module size: See linkedit output * 00490000
* Attributes: Re-entrant and re-usable * 00500000
* * 00510000
* Entry Point: DSN8DUAD * 00520000
* Purpose: See Function * 00530000
* Linkage: DB2SQL * 00540000
* Invoked via SQL UDF call * 00550000
* * 00560000
* Input: Parameters explicitly passed to this function: * 00570000
* - *format : pointer to a char[14], null-termi- * 00580000
* nated string having the desired * 00590000
1178 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* format for the current date (see * 00600000
* "Function", above, for valid formats)* 00610000
* - *niFormat : pointer to a short integer having * 00620000
* the null indicator variable for * 00630000
* *format. * 00640000
* - *fnName : pointer to a char[138], null-termi- * 00650000
* nated string having the UDF family * 00660000
* name of this function. * 00670000
* - *specificName: pointer to a char[129], null-termi- * 00680000
* nated string having the UDF specific * 00690000
* name of this function. * 00700000
* * 00710000
* * 00720000
* Output: Parameters explicitly passed by this function: * 00730000
* - *dateOut : pointer to a char[18], null-termi- * 00740000
* nated string to receive the current * 00750000
* date in the formatted indicated by * 00760000
* *format. * 00770000
* - *niDateOut : pointer to a short integer to re- * 00780000
* ceive the null indicator variable * 00790000
* for *dateOut. * 00800000
* - *sqlstate : pointer to a char[06], null-termi- * 00810000
* nated string to receive the SQLSTATE.* 00820000
* - *message : pointer to a char[70], null-termi- * 00830000
* nated string to receive a diagnostic * 00840000
* message if one is generated by this * 00850000
* function. * 00860000
* * 00870000
* Normal Exit: Return Code: SQLSTATE = 00000 * 00880000
* - Message: none * 00890000
* * 00900000
* Error Exit: Return Code: SQLSTATE = 38601 * 00910000
* - Message: DSN8DUAD Error: No output format entered * 00920000
* - Message: DSN8DUAD Error: Unknown format specified * 00930000
* * 00940000
* External References: * 00950000
* - Routines/Services: None * 00960000
* - Data areas : None * 00970000
* - Control blocks : None * 00980000
* * 00990000
* * 01000000
* Pseudocode: * 01010000
* DSN8DUAD: * 01020000
* - Verify that a valid format for the current date was received: * 01030000
* - if *format is blank or niFormat is not 0, no format passed: * 01040000
* - issue SQLSTATE 38601 and a diagnostic message * 01050000
* - Verify that a valid format for the current date was received: * 01060000
* - Call formatDate to convert the current date in the indicated * 01070000
* format. * 01080000
* - If no errors, unset null indicators, and return SQLSTATE 00000 * 01090000
* else set null indicator and return null date out. * 01100000
* End DSN8DUAD * 01110000
* * 01120000
* formatDate: * 01130000
* - Use the date format to generate a specification string for * 01140000
* the getDate function * 01150000
* - Call getDate * 01160000
* - Perform edits on the result as appropriate: * 01170000
* - call Remove0 to strip leading zeroes from the day and/or * 01180000
* month * 01190000
* - call romanMonth to convert the month to a roman numeral * 01200000
* - If *format is not one of the 34 supported formats: * 01210000
* - issue SQLSTATE 38601 and a diagnostic message * 01220000
* End formatDate * 01230000
* * 01240000
* getDate: * 01250000
* - invoke the time() library function to query calendar time. * 01260000
* - invoke the localtime() library function to convert and correct * 01270000
* for local time * 01280000
* - invoke the strftime() library function to format the date from * 01290000
* from the time vector according to specification generated by * 01300000
* the local formatDate() function. * 01310000
* End getDate * 01320000
* * 01330000
* Remove0: * 01340000
* - check the passed string for a character zero in the passed * 01350000
* location. * 01360000
* - if a zero is found, eliminate it by shifting all bytes to its * 01370000
* right 1 byte leftward. * 01380000
* End Remove0 * 01390000
* * 01400000
* romanMonth * 01410000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1179
* - convert the month (01-12) to a roman numeral (I-XII). * 01420000
* End romanMonth * 01430000
* * 01440000
* Change Log: * 01450000
* 2002/10/17 PQ66488 Fix date truncation error @01* 01460000
* * 01470000
* * 01480000
*********************************************************************/ 01490000
01500000
#pragma linkage(DSN8DUAD,fetchable) 01510000
01520000
/********************** C library definitions ***********************/ 01530000
#include <stdio.h> 01540000
#include <string.h> 01550000
#include <time.h> 01560000
01570000
/***************************** Equates ******************************/ 01580000
#define NULLCHAR '\0' /* Null character */ 01590000
01600000
#define MATCH 0 /* Comparison status: Equal */ 01610000
#define NOT_OK 0 /* Run status indicator: Error*/ 01620000
#define OK 1 /* Run status indicator: Good */ 01630000
01640000
01650000
/*********************** DSN8DUAD functions *************************/ 01660000
void DSN8DUAD /* main routine */ 01670000
( char *format, /* in: format for dateOut */ 01680000
char *dateOut, /* out: formatted current date*/ 01690000
short int *niFormat, /* in: indic var, format */ 01700000
short int *niDateOut, /* out: indic var for dateOut */ 01710000
char *sqlstate, /* out: SQLSTATE */ 01720000
char *fnName, /* in: family name of function*/ 01730000
char *specificName, /* in: specific name of func */ 01740000
char *message /* out: diagnostic message */ 01750000
); 01760000
01770000
int formatDate /* format the current date */ 01780000
( char *dateOut, /* out: formatted curr date */ 01790000
char *message, /* out: diagnostic message */ 01800000
char *sqlstate, /* out: SQLSTATE */ 01810000
char *format /* in: desired format */ 01820000
); 01830000
01840000
void getDate /* gets curr date, formatted */ 01850000
( char *dateOut, /* out: formatted current date*/ 01860000
char *dateFmt /* in: desired date format */ 01870000
); 01880000
01890000
void Remove0 /* remove 0 from indic. byte */ 01900000
( char *string, /* in/out: character string */ 01910000
short int loc /* in: loc'n of zero to remove*/ 01920000
); 01930000
01940000
char *romanMonth(); /* get roman# of curr month# */ 01950000
01960000
01970000
/********************************************************************/ 01980000
/*************************** main routine ***************************/ 01990000
/********************************************************************/ 02000000
void DSN8DUAD /* main routine */ 02010000
( char *format, /* in: format for dateOut */ 02020000
char *dateOut, /* out: formatted current date*/ 02030000
short int *niFormat, /* in: indic var, format */ 02040000
short int *niDateOut, /* out: indic var for dateOut */ 02050000
char *sqlstate, /* out: SQLSTATE */ 02060000
char *fnName, /* in: family name of function*/ 02070000
char *specificName, /* in: specific name of func */ 02080000
char *message /* out: diagnostic message */ 02090000
) 02100000
/********************************************************************* 02110000
* * 02120000
* Assumptions: * 02130000
* - *format points to a char[14], null-terminated string * 02140000
* - *dateOut points to a char[18], null-terminated string * 02150000
* - *niFormat points to a short integer * 02160000
* - *niDateOut points to a short integer * 02170000
* - *sqlstate points to a char[06], null-terminated string * 02180000
* - *fnName points to a char[138], null-terminated string * 02190000
* - *specificName points to a char[129], null-terminated string * 02200000
* - *message points to a char[70], null-terminated string * 02210000
*********************************************************************/ 02220000
{ 02230000
1180 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
02240000
/************************ local variables *************************/ 02250000
short int status = OK; /* DSN8DUAD run status */ 02260000
02270000
02280000
/******************************************************************* 02290000
* Verify that a format has been passed in * 02300000
*******************************************************************/ 02310000
if( *niFormat || ( strlen( format ) == 0 ) ) 02320000
{ 02330000
status = NOT_OK; 02340000
strcpy( message, 02350000
"DSN8DUAD Error: No output format entered" ); 02360000
strcpy( sqlstate, "38601" ); 02370000
} 02380000
02390000
/******************************************************************* 02400000
* Call formatDate to format the current date according to format * 02410000
*******************************************************************/ 02420000
if( status == OK ) 02430000
status = formatDate( dateOut, message, sqlstate, format ); 02440000
02450000
02460000
/******************************************************************* 02470000
* If formatting was successful, clear the message buffer and sql- * 02480000
* state, and unset the SQL null indicator for dateOut. * 02490000
*******************************************************************/ 02500000
if( status == OK ) 02510000
{ 02520000
*niDateOut = 0; 02530000
message[0] = NULLCHAR; 02540000
strcpy( sqlstate,"00000" ); 02550000
} 02560000
/******************************************************************* 02570000
* If errors occurred, clear the dateOut buffer and set the SQL null* 02580000
* indicator. A diagnostic message and the SQLSTATE have been set * 02590000
* where the error was detected. * 02600000
*******************************************************************/ 02610000
else 02620000
{ 02630000
dateOut[0] = NULLCHAR; 02640000
*niDateOut = -1; 02650000
} 02660000
02670000
return; 02680000
02690000
} /* end of DSN8DUAD */ 02700000
02710000
02720000
/********************************************************************/ 02730000
/***************************** functions ****************************/ 02740000
/********************************************************************/ 02750000
int formatDate /* format the current date */ 02760000
( char *dateOut, /* out: formatted curr date */ 02770000
char *message, /* out: diagnostic message */ 02780000
char *sqlstate, /* out: SQLSTATE */ 02790000
char *format /* in: desired format */ 02800000
) 02810000
/********************************************************************* 02820000
* Places the current date formatted according to format in dateOut. * 02830000
* If processing is successful, formatDaete returns OK. Otherwise, a * 02840000
* diagnostic message is placed in message, the SQLSTATE is 38601, * 02850000
* and formatDate returns NOT_OK. * 02860000
*********************************************************************/ 02870000
{ 02880000
short int func_status = OK; /* function status indicator */ 02890000
char dateFmt[14]; /* date format work buffer */ 02900000
02910000
/******************************************************************* 02920000
* get the current date and format it according to format * 02930000
*******************************************************************/ 02940000
if( strcmp( format,"D MONTH YY" ) == MATCH ) 02950000
{ 02960000
getDate( dateOut,"%d %B %y" ); /* format date as DD MONTH YY */ 02970000
Remove0( dateOut,0 ); /* strip leading 0 if day < 10*/ 02980000
} 02990000
else if( strcmp( format,"D MONTH YYYY" ) == MATCH ) 03000000
{ 03010000
getDate( dateOut,"%d %B %Y" ); /* formt date as DD MONTH YYYY*/ 03020000
Remove0( dateOut,0 ); /* strip leading 0 if day < 10*/ 03030000
} 03040000
else if( strcmp( format,"DD MONTH YY" ) == MATCH ) 03050000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1181
{ 03060000
getDate( dateOut,"%d %B %y" );/* format date as DD MONTH YY */ 03070000
} 03080000
else if( strcmp( format,"DD MONTH YYYY" ) == MATCH ) 03090000
{ 03100000
getDate( dateOut,"%d %B %Y" ); /* formt date as DD MONTH YYYY*/ 03110000
} 03120000
else if( strcmp( format,"D.M.YY" ) == MATCH ) 03130000
{ 03140000
getDate( dateOut,"%d.%m.%y" ); /* format date as DD.MM.YY */03150000
Remove0( dateOut,3 ); /* strip leading 0 if month<10*/ 03160000
Remove0( dateOut,0 ); /* strip leading 0 if day < 10*/ 03170000
} 03180000
else if( strcmp( format,"D.M.YYYY" ) == MATCH ) 03190000
{ 03200000
getDate( dateOut,"%d.%m.%Y" ); /* format date as DD.MM.YYYY */03210000
Remove0( dateOut,3 ); /* strip leading 0 if month<10*/ 03220000
Remove0( dateOut,0 ); /* strip leading 0 if day < 10*/ 03230000
} 03240000
else if( strcmp( format,"DD.MM.YY" ) == MATCH ) 03250000
{ 03260000
getDate( dateOut,"%d.%m.%y" ); /* format date as DD.MM.YY */03270000
} 03280000
else if( strcmp( format,"DD.MM.YYYY" ) == MATCH ) 03290000
{ 03300000
getDate( dateOut,"%d.%m.%Y" ); /* format date as DD.MM.YYYY */03310000
} 03320000
else if( strcmp( format,"D-M-YY" ) == MATCH ) 03330000
{ 03340000
getDate( dateOut,"%d-%m-%y" ); /* format date as DD-MM-YY */03350000
Remove0( dateOut,3 ); /* strip leading 0 if month<10*/ 03360000
Remove0( dateOut,0 ); /* strip leading 0 if day < 10*/ 03370000
} 03380000
else if( strcmp( format,"D-M-YYYY" ) == MATCH ) 03390000
{ 03400000
getDate( dateOut,"%d-%m-%Y" ); /* format date as DD-MM-YYYY */03410000
Remove0( dateOut,3 ); /* strip leading 0 if month<10*/ 03420000
Remove0( dateOut,0 ); /* strip leading 0 if day < 10*/ 03430000
} 03440000
else if( strcmp( format,"DD-MM-YY" ) == MATCH ) 03450000
{ 03460000
getDate( dateOut,"%d-%m-%y" ); /* format date as DD-MM-YY */03470000
} 03480000
else if( strcmp( format,"DD-MM-YYYY" ) == MATCH ) 03490000
{ 03500000
getDate( dateOut,"%d-%m-%Y" ); /* format date as DD-MM-YYYY */03510000
} 03520000
else if( strcmp( format,"D/M/YY" ) == MATCH ) 03530000
{ 03540000
getDate( dateOut,"%d/%m/%y" ); /* format date as DD/MM/YY */03550000
Remove0( dateOut,3 ); /* strip leading 0 if month<10*/ 03560000
Remove0( dateOut,0 ); /* strip leading 0 if day < 10*/ 03570000
} 03580000
else if( strcmp( format,"D/M/YYYY" ) == MATCH ) 03590000
{ 03600000
getDate( dateOut,"%d/%m/%Y" ); /* format date as DD/MM/YYYY */03610000
Remove0( dateOut,3 ); /* strip leading 0 if month<10*/ 03620000
Remove0( dateOut,0 ); /* strip leading 0 if day < 10*/ 03630000
} 03640000
else if( strcmp( format,"DD/MM/YY" ) == MATCH ) 03650000
{ 03660000
getDate( dateOut,"%d/%m/%y" ); /* format date as DD/MM/YY */03670000
} 03680000
else if( strcmp( format,"DD/MM/YYYY" ) == MATCH ) 03690000
{ 03700000
getDate( dateOut,"%d/%m/%Y" ); /* format date as DD/MM/YYYY */03710000
} 03720000
else if( strcmp( format,"M/D/YY" ) == MATCH ) 03730000
{ 03740000
getDate( dateOut,"%m/%d/%y" ); /* format date as MM/DD/YY */03750000
Remove0( dateOut,3 ); /* strip leading 0 if day < 10*/ 03760000
Remove0( dateOut,0 ); /* strip leading 0 if month<10*/ 03770000
} 03780000
else if( strcmp( format,"M/D/YYYY" ) == MATCH ) 03790000
{ 03800000
getDate( dateOut,"%m/%d/%Y" ); /* format date as MM/DD/YYYY */03810000
Remove0( dateOut,3 ); /* strip leading 0 if day < 10*/ 03820000
Remove0( dateOut,0 ); /* strip leading 0 if month<10*/ 03830000
} 03840000
else if( strcmp( format,"MM/DD/YY" ) == MATCH ) 03850000
{ 03860000
getDate( dateOut,"%m/%d/%y" ); /* format date as MM/DD/YY */03870000
1182 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
} 03880000
else if( strcmp( format,"MM/DD/YYYY" ) == MATCH ) 03890000
{ 03900000
getDate( dateOut,"%m/%d/%Y" ); /* format date as MM/DD/YYYY */03910000
} 03920000
else if( strcmp( format,"YY/M/D" ) == MATCH ) 03930000
{ 03940000
getDate( dateOut,"%y/%m/%d" ); /* format date as YY/MM/DD */03950000
Remove0( dateOut,6 ); /* strip leading 0 if day < 10*/ 03960000
Remove0( dateOut,3 ); /* strip leading 0 if month<10*/ 03970000
} 03980000
else if( strcmp( format,"YY/MM/DD" ) == MATCH ) 03990000
{ 04000000
getDate( dateOut,"%y/%m/%d" ); /* format date as YY/MM/DD */04010000
} 04020000
else if( strcmp( format,"YYYY/M/D" ) == MATCH ) 04030000
{ 04040000
getDate( dateOut,"%Y/%m/%d" ); /* format date as YYYY/MM/DD */04050000
Remove0( dateOut,8 ); /* strip leading 0 if day < 10*/ 04060000
Remove0( dateOut,5 ); /* strip leading 0 if month<10*/ 04070000
} 04080000
else if( strcmp( format,"YYYY/MM/DD" ) == MATCH ) 04090000
{ 04100000
getDate( dateOut,"%Y/%m/%d" ); /* format date as YYYY/MM/DD */04110000
} 04120000
else if( strcmp( format,"YY.M.D" ) == MATCH ) 04130000
{ 04140000
getDate( dateOut,"%y.%m.%d" ); /* format date as YY.MM.DD */04150000
Remove0( dateOut,6 ); /* strip leading 0 if day < 10*/ 04160000
Remove0( dateOut,3 ); /* strip leading 0 if month<10*/ 04170000
} 04180000
else if( strcmp( format,"YY.MM.DD" ) == MATCH ) 04190000
{ 04200000
getDate( dateOut,"%y.%m.%d" ); /* format date as YY.MM.DD */04210000
} 04220000
else if( strcmp( format,"YYYY.M.D" ) == MATCH ) 04230000
{ 04240000
getDate( dateOut,"%Y.%m.%d" ); /* format date as YYYY.MM.DD */04250000
Remove0( dateOut,8 ); /* strip leading 0 if day < 10*/ 04260000
Remove0( dateOut,5 ); /* strip leading 0 if month<10*/ 04270000
} 04280000
else if( strcmp( format,"YYYY.MM.DD" ) == MATCH ) 04290000
{ 04300000
getDate( dateOut,"%Y.%m.%d" ); /* format date as YYYY.MM.DD */04310000
} 04320000
else if( strcmp( format,"YYYY-M-D" ) == MATCH ) 04330000
{ 04340000
getDate( dateOut,"%Y-%m-%d" ); /* format date as YYYY-MM-DD */04350000
Remove0( dateOut,8 ); /* strip leading 0 if day < 10*/ 04360000
Remove0( dateOut,5 ); /* strip leading 0 if month<10*/ 04370000
} 04380000
else if( strcmp( format,"YYYY-MM-DD" ) == MATCH ) 04390000
{ 04400000
getDate( dateOut,"%Y-%m-%d" ); /* format date as YYYY-MM-DD */04410000
} 04420000
else if( strcmp( format,"YYYY-D-XX" ) == MATCH ) 04430000
{ 04440000
strcpy( dateFmt, "%Y-%d-" ); /* start format as YYYY-DD- */ 04450000
strcat( dateFmt, romanMonth() );/* append roman# for curr mo. */ 04460000
getDate( dateOut,dateFmt ); /* format date as YYYY-DD-XX */ 04470000
Remove0( dateOut,5 ); /* strip leading 0 if day < 10*/ 04480000
} 04490000
else if( strcmp( format,"YYYY-DD-XX" ) == MATCH ) 04500000
{ 04510000
strcpy( dateFmt, "%Y-%d-" ); /* start format as YYYY-DD- */ 04520000
strcat( dateFmt, romanMonth() );/* append roman# for curr mo. */ 04530000
getDate( dateOut,dateFmt ); /* format date as YYYY-DD-XX */ 04540000
} 04550000
else if( strcmp( format,"YYYY-XX-D" ) == MATCH ) 04560000
{ 04570000
strcpy( dateFmt, "%Y-" ); /* start format as YYYY- */ 04580000
strcat( dateFmt, romanMonth() );/* append roman# for curr mo. */ 04590000
strcat( dateFmt, "-%d" ); /* append -DD to format */ 04600000
getDate( dateOut,dateFmt ); /* get date as YYYY-XX-DD */ 04610000
Remove0( dateOut, /* strip leading 0 if day < 10*/ 04620000
strlen(dateFmt) ); 04630000
} 04640000
else if( strcmp( format,"YYYY-XX-DD" ) == MATCH ) 04650000
{ 04660000
strcpy( dateFmt, "%Y-" ); /* start format as YYYY- */ 04670000
strcat( dateFmt, romanMonth() );/* append roman# for curr mo. */ 04680000
strcat( dateFmt, "-%d" ); /* append -DD to format */ 04690000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1183
getDate( dateOut,dateFmt ); /* get date as YYYY-XX-DD */ 04700000
} 04710000
else 04720000
{ 04730000
func_status = NOT_OK; 04740000
strcpy( message, 04750000
"DSN8DUAD Error: Unknown format specified" ); 04760000
strcpy( sqlstate, "38601" ); 04770000
} 04780000
04790000
return( func_status ); 04800000
} /* end of formatDate */ 04810000
04820000
/********************************************************************/ 04830000
/***************************** functions ****************************/ 04840000
/********************************************************************/ 04850000
void getDate /* gets curr date, formatted */ 04860000
( char *dateOut, /* out: formatted current date*/ 04870000
char *dateFmt /* in: desired date format */ 04880000
) 04890000
/********************************************************************* 04900000
* Obtains the current date from the system and formats it according * 04910000
* to the format string in *dateFmt. The result is placed in dateOut.* 04920000
* * 04930000
* This function uses the C function localtime to obtain the system * 04940000
* time and date and the C function strftime to format it according * 04950000
* to *dateFmt. For this program, the following format tokens were * 04960000
* used. See the C/C++ library reference manuals for more info. * 04970000
* * 04980000
* %B = full month name * 04990000
* %d = day of the month * 05000000
* %m = month (01-12) * 05010000
* %y = year with century * 05020000
* %Y = year with century * 05030000
*********************************************************************/ 05040000
{ 05050000
time_t t; /* buff for system time macro */ 05060000
struct tm *tmPtr; /* ->buff for time.h tm struct*/ 05070000
short int i; /* len of str rtnd by strftime*/ 05080000
char dateBuff[19]; /* gets formatted date @01*/ 05090000
05100000
/******************************************************************* 05110000
* Use the C function localtime to get the current date from the * 05120000
* system, then use the C function strftime to format it according * 05130000
* to *dateFmt. * 05140000
*******************************************************************/ 05150000
t = time(NULL); 05160000
tmPtr = localtime(&t); 05170000
i = strftime( dateBuff, 05180000
sizeof(dateBuff)-1, 05190000
dateFmt, 05200000
tmPtr ); 05210000
05220000
if( i > 0 ) 05230000
strcpy( dateOut,dateBuff ); 05240000
05250000
return; 05260000
} /* end getDate */ 05270000
05280000
05290000
void Remove0 05300000
( char *string, /* in/out: character string */ 05310000
short int loc /* in: loc'n of byte to remove*/ 05320000
) 05330000
/********************************************************************* 05340000
* Checks *string at the location indicated by loc and, if a character* 05350000
* zero resides there, removes it from *string by shifting all bytes * 05360000
* to the right of it leftward by 1 byte. * 05370000
*********************************************************************/ 05380000
{ 05390000
short int i; 05400000
05410000
if( string[loc] == '0' ) 05420000
{ 05430000
for( i=loc; i<(strlen(string)-1); i++ ) 05440000
string[i] = string[i+1]; 05450000
string[i] = NULLCHAR; 05460000
} 05470000
05480000
return; 05490000
} /* end Remove0 */ 05500000
05510000
1184 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
05520000
char *romanMonth() 05530000
/********************************************************************* 05540000
* Returns the roman numeral that corresponds to the month number of * 05550000
* the current month. * 05560000
*********************************************************************/ 05570000
{ 05580000
char romNum[5]; /* gets roman numeral */ 05590000
char monthNo[18]; /* gets current month number */ 05600000
05610000
/******************************************************************* 05620000
* call getDate to get the month number of the current month * 05630000
*******************************************************************/ 05640000
getDate( monthNo,"%m" ); /* format date as MM */ 05650000
05660000
/******************************************************************* 05670000
* look up the roman numeral that corresponds to the current month * 05680000
*******************************************************************/ 05690000
if( strcmp( monthNo,"01" ) == MATCH ) strcpy( romNum, "I" ); 05700000
else if( strcmp( monthNo,"02" ) == MATCH ) strcpy( romNum, "II" ); 05710000
else if( strcmp( monthNo,"03" ) == MATCH ) strcpy( romNum, "III" ); 05720000
else if( strcmp( monthNo,"04" ) == MATCH ) strcpy( romNum, "IV" ); 05730000
else if( strcmp( monthNo,"05" ) == MATCH ) strcpy( romNum, "V" ); 05740000
else if( strcmp( monthNo,"06" ) == MATCH ) strcpy( romNum, "VI" ); 05750000
else if( strcmp( monthNo,"07" ) == MATCH ) strcpy( romNum, "VII" ); 05760000
else if( strcmp( monthNo,"08" ) == MATCH ) strcpy( romNum, "VIII" ); 05770000
else if( strcmp( monthNo,"09" ) == MATCH ) strcpy( romNum, "IX" ); 05780000
else if( strcmp( monthNo,"10" ) == MATCH ) strcpy( romNum, "X" ); 05790000
else if( strcmp( monthNo,"11" ) == MATCH ) strcpy( romNum, "XI" ); 05800000
else strcpy( romNum, "XII" ); 05810000
05820000
/******************************************************************* 05830000
* return the result * 05840000
*******************************************************************/ 05850000
return( romNum ); 05860000
05870000
} /* end romanMonth */ 05880000
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSN8DUAT
Returns the current time in one these 8 formats.
/********************************************************************* 00010000
* Module name = DSN8DUAT (DB2 sample program) * 00020000
* * 00030000
* DESCRIPTIVE NAME = Current time reformatter (UDF) * 00040000
* * 00050000
* LICENSED MATERIALS - PROPERTY OF IBM * 00060000
* 5675-DB2 * 00170000
* (C) COPYRIGHT 1998, 2000 IBM CORP. ALL RIGHTS RESERVED. * 00180000
* * 00190000
* STATUS = VERSION 7 * 00200000
* * 00210000
* Function: Returns the current time in one these 8 formats: * 00220000
* formats: * 00230000
* * 00240000
* H:MM AM/PM HH:MM AM/PM HH:MM:SS AM/PM HH:MM:SS * 00250000
* H.MM HH.MM H.MM.SS HH.MM.SS * 00260000
* * 00270000
* where: * 00280000
* * 00290000
* H: Suppress leading zero if the hour is less than 10 * 00300000
* HH: Retain leading zero if the hour is less than 10 * 00310000
* M: Suppress leading zero if the minute is less than 10 * 00320000
* MM: Retain leading zero if the minute is less than 10 * 00330000
* AM/PM: Return time in 12-hour clock format, else 24-hour * 00340000
* * 00350000
* Example invocation: * 00360000
* EXEC SQL SET :now = ALTTIME( "HH:MM:SS AM/PM" ); * 00370000
* * 00380000
* Notes: * 00390000
* Dependencies: Requires IBM C/C++ for OS/390 V1R3 or higher * 00400000
* * 00410000
* Restrictions: * 00420000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1185
* * 00430000
* Module type: C program * 00440000
* Processor: IBM C/C++ for OS/390 V1R3 or higher * 00450000
* Module size: See linkedit output * 00460000
* Attributes: Re-entrant and re-usable * 00470000
* * 00480000
* Entry Point: DSN8DUAT * 00490000
* Purpose: See Function * 00500000
* Linkage: DB2SQL * 00510000
* Invoked via SQL UDF call * 00520000
* * 00530000
* Input: Parameters explicitly passed to this function: * 00540000
* - *format : pointer to a char[15], null-termi- * 00550000
* nated string having the desired * 00560000
* format for the current time (see * 00570000
* "Function", above, for valid formats)* 00580000
* - *niFormat : pointer to a short integer having * 00590000
* the null indicator variable for * 00600000
* *format. * 00610000
* - *fnName : pointer to a char[138], null-termi- * 00620000
* nated string having the UDF family * 00630000
* name of this function. * 00640000
* - *specificName: pointer to a char[129], null-termi- * 00650000
* nated string having the UDF specific * 00660000
* name of this function. * 00670000
* * 00680000
* * 00690000
* Output: Parameters explicitly passed by this function: * 00700000
* - *timeOut : pointer to a char[12], null-termi- * 00710000
* nated string to receive the current * 00720000
* time in the formatted indicated by * 00730000
* *format. * 00740000
* - *niTimeOut : pointer to a short integer to re- * 00750000
* ceive the null indicator variable * 00760000
* for *timeOut. * 00770000
* - *sqlstate : pointer to a char[06], null-termi- * 00780000
* nated string to receive the SQLSTATE.* 00790000
* - *message : pointer to a char[70], null-termi- * 00800000
* nated string to receive a diagnostic * 00810000
* message if one is generated by this * 00820000
* function. * 00830000
* * 00840000
* Normal Exit: Return Code: SQLSTATE = 00000 * 00850000
* - Message: none * 00860000
* * 00870000
* Error Exit: Return Code: SQLSTATE = 38601 * 00880000
* - Message: DSN8DUAT Error: No format entered * 00890000
* - Message: DSN8DUAT Error: Unknown format specified * 00900000
* * 00910000
* External References: * 00920000
* - Routines/Services: None * 00930000
* - Data areas : None * 00940000
* - Control blocks : None * 00950000
* * 00960000
* * 00970000
* Pseudocode: * 00980000
* DSN8DUAT: * 00990000
* - Verify that a valid format for the current time was received: * 01000000
* - if *format is blank or niFormat is not 0, no format passed: * 01010000
* - issue SQLSTATE 38601 and a diagnostic message * 01020000
* - Call getTime to obtain: * 01030000
* - the current 12-hour clock hour * 01040000
* - the current 24-hour clock hour * 01050000
* - the current minute * 01060000
* - the current second * 01070000
* - Set AM/PM indicator to PM if 24-hour clock hour > 11, else AM * 01080000
* - Call remove0prefix to remove leading zeroes from the hour * 01090000
* component, if appropriate * 01100000
* - Call buildTime to generate the output time using the format to * 01110000
* determine which of the time components, delimiters, and AM/PM * 01120000
* indicator (if any) to pass. * 01130000
* - If no errors, unset null indicators, and return SQLSTATE 00000 * 01140000
* else set null indicator and return null time out. * 01150000
* End DSN8DUAT * 01160000
* * 01170000
* getTime: * 01180000
* - invoke the time() library function to query calendar time. * 01190000
* - invoke the localtime() library function to convert and correct * 01200000
* for local time. * 01210000
* - invoke the strftime() library function to format 12-hour, 24- * 01220000
* hour, minute, and second components from the time vector. * 01230000
* End getTime * 01240000
1186 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* * 01250000
* buildTime: * 01260000
* - Concatenate the minutes component to the hours component with * 01270000
* an intervening delimiter (: or .). * 01280000
* - If the seconds component is not null, concatenate it to the * 01290000
* timestring with an intervening delimiter (: or .) * 01300000
* - If the AM/PM indicator is not null, concatenate it to the * 01310000
* timestring * 01320000
* End buildTime * 01330000
* * 01340000
* remove0prefix: * 01350000
* - eliminate leading zeroes from a hour component * 01360000
* End remove0prefix * 01370000
* * 01380000
* * 01390000
*********************************************************************/ 01400000
01410000
#pragma linkage(DSN8DUAT,fetchable) 01414990
01420000
/********************** C library definitions ***********************/ 01430000
#include <stdio.h> 01440000
#include <string.h> 01450000
#include <time.h> 01460000
01470000
/***************************** Equates ******************************/ 01480000
#define NULLCHAR '\0' /* Null character */ 01490000
01500000
#define MATCH 0 /* Comparison status: Equal */ 01510000
#define NOT_OK 0 /* Run status indicator: Error*/ 01520000
#define OK 1 /* Run status indicator: Good */ 01530000
01540000
01550000
/*********************** DSN8DUAT functions *************************/ 01560000
void DSN8DUAT /* main routine */ 01570000
( char *format, /* in: format for timeOut */ 01580000
char *timeOut, /* out: formatted current time*/ 01590000
short int *niFormat, /* in: indic var, format */ 01600000
short int *niTimeOut, /* out: indic var, timeOut */ 01610000
char *sqlstate, /* out: SQLSTATE */ 01620000
char *fnName, /* in: family name of function*/ 01630000
char *specificName, /* in: specific name of func */ 01640000
char *message /* out: diagnostic message */ 01650000
); 01660000
01670000
void getTime /* Get current time */ 01680000
( char *hh12, /* out: hours (12 hour clock) */ 01690000
char *hh24, /* out: hours (24 hour clock) */ 01700000
char *mm, /* out: minutes */ 01710000
char *ss /* out: seconds */ 01720000
); 01730000
01740000
void buildTime /* Format time as specified */ 01750000
( char *timeStr, /* out: reformatted time */ 01760000
char *hh, /* in: hours component */ 01770000
char *mm, /* in: minutes component */ 01780000
char *ss, /* in: seconds component */ 01790000
char *delim, /* in: delimiter of choice */ 01800000
char *suffix /* in: AM/PM suffix (if any) */ 01810000
); 01820000
01830000
void remove0prefix /* Remove leading zeroes */ 01840000
( char *string /* in/out: character string */ 01850000
); 01860000
01870000
/********************************************************************/ 01880000
/*************************** main routine ***************************/ 01890000
/********************************************************************/ 01900000
void DSN8DUAT /* main routine */ 01910000
( char *format, /* in: format for timeOut */ 01920000
char *timeOut, /* out: formatted current time*/ 01930000
short int *niFormat, /* in: indic var, format */ 01940000
short int *niTimeOut, /* out: indic var, timeOut */ 01950000
char *sqlstate, /* out: SQLSTATE */ 01960000
char *fnName, /* in: family name of function*/ 01970000
char *specificName, /* in: specific name of func */ 01980000
char *message /* out: diagnostic message */ 01990000
) 02000000
/********************************************************************* 02010000
* * 02020000
* * 02030000
* Assumptions: * 02040000
* - *format points to a char[15], null-terminated string * 02050000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1187
* - *timeOut points to a char[12], null-terminated string * 02060000
* - *niFormat points to a short integer * 02070000
* - *niTimeOut points to a short integer * 02080000
* - *sqlstate points to a char[06], null-terminated string * 02090000
* - *fnName points to a char[138], null-terminated string * 02105990
* - *specificName points to a char[129], null-terminated string * 02111980
* - *message points to a char[70], null-terminated string * 02120000
*********************************************************************/ 02130000
{ 02140000
/************************ local variables *************************/ 02150000
short int status = OK; /* DSN8DUMN run status */ 02160000
02170000
char hh12[3]; /* current time - hours */ 02180000
char hh24[3]; /* current time - hours */ 02190000
char mm[3]; /* current time - minutes */ 02200000
char ss[3]; /* current time - seconds */ 02210000
char suffix[4]; /* AM/PM indicator */ 02220000
02230000
02240000
/******************************************************************* 02250000
* Verify that a format has been passed in * 02260000
*******************************************************************/ 02270000
if( *niFormat || ( strlen( format ) == 0 ) ) 02280000
{ 02290000
status = NOT_OK; 02300000
strcpy( message, 02310000
"DSN8DUAT Error: No format entered" ); 02320000
strcpy( sqlstate, "38601" ); 02330000
} 02340000
02350000
/******************************************************************* 02360000
* Get current time in the specified format * 02370000
*******************************************************************/ 02380000
if( status == OK ) 02390000
{ 02400000
/*************************************************************** 02410000
* Get the current hour (hh), minute (mm), and second (ss) * 02420000
***************************************************************/ 02430000
getTime( hh12,hh24,mm,ss ); 02440000
02450000
/*************************************************************** 02460000
* Suffix is AM unless it's noon or later on the 24-hour clock * 02470000
***************************************************************/ 02480000
strcpy( suffix," AM" ); 02490000
if( strcmp( hh24,"11" ) > 0 ) 02500000
strcpy( suffix," PM" ); 02510000
02520000
/*************************************************************** 02530000
* Format the current time according to the input format * 02540000
***************************************************************/ 02550000
if( strcmp( format,"H:MM AM/PM" ) == MATCH ) 02560000
{ 02570000
remove0prefix( hh12 ); 02580000
buildTime( timeOut,hh12,mm,"",":",suffix ); 02590000
} 02600000
else if( strcmp( format,"HH:MM AM/PM" ) == MATCH ) 02610000
{ 02620000
buildTime( timeOut,hh12,mm,"",":",suffix ); 02630000
} 02640000
else if( strcmp( format,"HH:MM:SS AM/PM" ) == MATCH ) 02650000
{ 02660000
buildTime( timeOut,hh12,mm,ss,":",suffix ); 02670000
} 02680000
else if( strcmp( format,"HH:MM:SS" ) == MATCH ) 02690000
{ 02700000
buildTime( timeOut,hh24,mm,ss,":","" ); 02710000
} 02720000
else if( strcmp( format,"H.MM" ) == MATCH ) 02730000
{ 02740000
remove0prefix( hh24 ); 02750000
buildTime( timeOut,hh24,mm,"",".","" ); 02760000
} 02770000
else if( strcmp( format,"HH.MM" ) == MATCH ) 02780000
{ 02790000
buildTime( timeOut,hh24,mm,"",".","" ); 02800000
} 02810000
else if( strcmp( format,"H.MM.SS" ) == MATCH ) 02820000
{ 02830000
remove0prefix( hh24 ); 02840000
buildTime( timeOut,hh24,mm,ss,".","" ); 02850000
} 02860000
else if( strcmp( format,"HH.MM.SS" ) == MATCH ) 02870000
1188 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
{ 02880000
buildTime( timeOut,hh24,mm,ss,".","" ); 02890000
} 02900000
else 02910000
{ 02920000
status = NOT_OK; 02930000
strcpy( message, 02940000
"DSN8DUAT Error: Unknown format specified" ); 02950000
strcpy( sqlstate, "38601" ); 02960000
} 02970000
} /* if( status == OK ) */ 02980000
02990000
/******************************************************************* 03000000
* If operation was successful, clear the message buffer and sql- * 03010000
* state, and unset the SQL null indicator for timeOut. * 03020000
*******************************************************************/ 03030000
if( status == OK ) 03040000
{ 03050000
*niTimeOut = 0; 03060000
message[0] = NULLCHAR; 03070000
strcpy( sqlstate,"00000" ); 03080000
} 03090000
/******************************************************************* 03100000
* If errors occurred, clear the timeOut buffer and set the SQL null* 03110000
* indicator. A diagnostic message and the SQLSTATE have been set * 03120000
* where the error was detected. * 03130000
*******************************************************************/ 03140000
else 03150000
{ 03160000
timeOut[0] = NULLCHAR; 03170000
*niTimeOut = -1; 03180000
} 03190000
03200000
return; 03210000
03220000
} /* end DSN8DUAT */ 03230000
03240000
03250000
/********************************************************************/ 03260000
/***************************** functions ****************************/ 03270000
/********************************************************************/ 03280000
void getTime 03290000
( char *hh12, /* out: hours (12 hour clock) */ 03300000
char *hh24, /* out: hours (24 hour clock) */ 03310000
char *mm, /* out: minutes */ 03320000
char *ss /* out: seconds */ 03330000
) 03340000
/********************************************************************* 03350000
* Obtains the current time from the system and returns the hours in * 03360000
* *hh12 (12-hour clock hours) and *hh24 (24-hour clock hours), the * 03370000
* minutes in *mm, and the seconds in *ss. * 03380000
*********************************************************************/ 03390000
{ 03400000
time_t t; /* buff for system time macro */ 03410000
struct tm *tmptr; /* buffer for time.h tm struct*/ 03420000
char timeBuf[13]; /* buffer to receive sys time */ 03430000
03440000
short int i; /* len of str rtnd by strftime*/ 03450000
char *tokPtr; /* string ptr for token parser*/ 03460000
char hhmmss[10]; /* time in HH:MM:SS format */ 03470000
03480000
/******************************************************************* 03490000
* Use the C function localtime to get the current time from the * 03500000
* system, then use the C function strftime to format it into a * 03510000
* string containing both 12- and 24-hour clock hours and minutes * 03520000
* and seconds, all separated by slashes. * 03530000
*******************************************************************/ 03540000
t = time(NULL); 03550000
tmptr = localtime(&t); 03560000
i = strftime( timeBuf, 03570000
sizeof(timeBuf)-1, 03580000
"%I/%H/%M/%S", /* format as hh12/hh24/mm/ss */ 03590000
tmptr ); 03600000
03610000
/******************************************************************* 03620000
* Use the strtok func to extract time components from time buffer * 03630000
*******************************************************************/ 03640000
tokPtr = strtok( timeBuf,"/" ); /* Parse to first slash */ 03650000
strcpy( hh12,tokPtr ); /* for hours on 12-hour clock */ 03660000
03670000
tokPtr = strtok( NULL,"/" ); /* Parse to 2nd slash */ 03680000
strcpy( hh24,tokPtr ); /* for hours on 24-hour clock */ 03690000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1189
03700000
tokPtr = strtok( NULL,"/" ); /* Parse to 3rd slash */ 03710000
strcpy( mm,tokPtr ); /* for minutes */ 03720000
03730000
tokPtr = strtok( NULL,"/" ); /* Parse remaining bytes */ 03740000
strcpy( ss,tokPtr ); /* for seconds */ 03750000
03760000
} /* end getTime */ 03770000
03780000
03790000
void buildTime 03800000
( char *timeStr, /* out: reformatted time */ 03810000
char *hh, /* in: hours component */ 03820000
char *mm, /* in: minutes component */ 03830000
char *ss, /* in: seconds component */ 03840000
char *delim, /* in: delimiter of choice */ 03850000
char *suffix /* in: AM/PM suffix (if any) */ 03860000
) 03870000
/********************************************************************* 03880000
* Builds *timeStr from hours (*hh), minutes (*mm), and seconds (*ss, * 03890000
* if not null), separated by the value in *delim and suffixed by the * 03900000
* value, if not null, in *suffix. * 03910000
*********************************************************************/ 03920000
{ 03930000
/******************************************************************* 03940000
* Build timeStr from incoming time components * 03950000
*******************************************************************/ 03960000
strcpy( timeStr,hh ); /* Start with hours ... */ 03970000
strcat( timeStr,delim ); /* append the delimiter */ 03980000
strcat( timeStr,mm ); /* append minutes */ 03990000
if( strlen(ss) > 0 ) /* and, if seconds specified, */ 04000000
{ 04010000
strcat( timeStr,delim ); /* ..append the delimiter */ 04020000
strcat( timeStr,ss ); /* ..append seconds */ 04030000
} 04040000
if( strlen(suffix) > 0 ) /* and, if suffix specified, */ 04050000
strcat( timeStr,suffix ); /* ..append it. */ 04060000
04070000
} /* end buildTime */ 04080000
04090000
04100000
void remove0prefix 04110000
( char *string /* in/out: character string */ 04120000
) 04130000
/********************************************************************* 04140000
* Eliminates all leading zeroes from *string. Leaves a single zero * 04150000
* in the first byte of *string if *string is all zeroes. * 04160000
*********************************************************************/ 04170000
{ 04180000
short int i = 0; /* Loop control */ 04190000
short int j = 0; /* Loop control */ 04200000
04210000
/******************************************************************* 04220000
* if leading zero in first byte, skip up to first non-zero * 04230000
*******************************************************************/ 04240000
if( string[0] == '0' ) 04250000
for( i=0; string[i] == '0'; i++ ); 04260000
04270000
/******************************************************************* 04280000
* if at end of string, it was all zeroes: put zero in 1st byte * 04290000
*******************************************************************/ 04300000
if( string[i] == '\0' ) 04310000
strcpy( string,"0" ); 04320000
/******************************************************************* 04330000
* otherwise, left-shift non-zero chars and terminate string * 04340000
*******************************************************************/ 04350000
else 04360000
{ 04370000
for( j=0; string[i] != NULLCHAR; j++ ) 04380000
string[j] = string[i++]; 04390000
string[j] = NULLCHAR; 04400000
} 04410000
} /* end remove0prefix */ 04420000
Related reference
“Sample applications in TSO” on page 1025
1190 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
A set of Db2 sample applications run in the TSO environment.
DSN8DUCD
Converts a given date from one to another of these 34 formats.
/********************************************************************* 00010000
* Module name = DSN8DUCD (DB2 sample program) * 00020000
* * 00030000
* DESCRIPTIVE NAME = General date reformatter (UDF) * 00040000
* * 00050000
* * 00120000
* LICENSED MATERIALS - PROPERTY OF IBM * 00130000
* 5675-DB2 * 00140000
* (C) COPYRIGHT 2000 IBM CORP. ALL RIGHTS RESERVED. * 00150000
* * 00160000
* STATUS = VERSION 7 * 00170000
* * 00190000
* * 00210000
* Function: Converts a given date from one to another of these 34 * 00220000
* formats: * 00230000
* * 00240000
* D MONTH YY D MONTH YYYY DD MONTH YY DD MONTH YYYY * 00250000
* D.M.YY D.M.YYYY DD.MM.YY DD.MM.YYYY * 00260000
* D-M-YY D-M-YYYY DD-MM-YY DD-MM-YYYY * 00270000
* D/M/YY D/M/YYYY DD/MM/YY DD/MM/YYYY * 00280000
* M/D/YY M/D/YYYY MM/DD/YY MM/DD/YYYY * 00290000
* YY/M/D YYYY/M/D YY/MM/DD YYYY/MM/DD * 00300000
* YY.M.D YYYY.M.D YY.MM.DD YYYY.MM.DD * 00310000
* YYYY-M-D YYYY-MM-DD * 00320000
* YYYY-D-XX YYYY-DD-XX * 00330000
* YYYY-XX-D YYYY-XX-DD * 00340000
* * 00350000
* where: * 00360000
* * 00370000
* D: Suppress leading zero if the day is less than 10 * 00380000
* DD: Retain leading zero if the day is less than 10 * 00390000
* M: Suppress leading zero if the month is less than 10 * 00400000
* MM: Retain leading zero if the month is less than 10 * 00410000
* MONTH: Use English-language name of month * 00420000
* XX: Use a capital Roman numeral for month * 00430000
* XX: Use a capital Roman numeral for month * 00440000
* YY: Use non-century year format * 00450000
* YYYY: Use century year format * 00460000
* * 00470000
* Example invocation: * 00480000
* EXEC SQL SET :newDate = ALTDATE( "3/15/1947", * 00490000
* "M/D/YYYY", * 00500000
* "DD MONTH YY" ); * 00510000
* ==> newDate = "15 March 47" * 00520000
* Notes: * 00530000
* Dependencies: Requires IBM C/C++ for OS/390 V1R3 or higher * 00540000
* * 00550000
* Restrictions: * 00560000
* * 00570000
* Module type: C program * 00580000
* Processor: IBM C/C++ for OS/390 V1R3 or higher * 00590000
* Module size: See linkedit output * 00600000
* Attributes: Re-entrant and re-usable * 00610000
* * 00620000
* Entry Point: DSN8DUCD * 00630000
* Purpose: See Function * 00640000
* Linkage: DB2SQL * 00650000
* Invoked via SQL UDF call * 00660000
* * 00670000
* Input: Parameters explicitly passed to this function: * 00680000
* - *dateIn : pointer to a char[18], null-termi- * 00690000
* nated string having a date in the * 00700000
* format indicated by *formatIn. * 00710000
* - *formatIn : pointer to a char[14], null-termi- * 00720000
* nated string having the format of * 00730000
* date found in *dateIn (see "Func- * 00740000
* tion", above, for valid formats). * 00750000
* - *formatOut : pointer to a char[14], null-termi- * 00760000
* nated string having the format to * 00770000
* which the date found in *dateIn is * 00780000
* to be converted. See "Function", * 00790000
* above, for valid formats. * 00800000
* - *niDateIn : pointer to a short integer having * 00810000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1191
* the null indicator variable for * 00820000
* *dateIn. * 00830000
* - *niFormatIn : pointer to a short integer having * 00840000
* the null indicator variable for * 00850000
* *formatIn. * 00860000
* - *niFormatOut : pointer to a short integer having * 00870000
* the null indicator variable for * 00880000
* *formatOut. * 00890000
* - *fnName : pointer to a char[138], null-termi- * 00900000
* nated string having the UDF family * 00910000
* name of this function. * 00920000
* - *specificName: pointer to a char[129], null-termi- * 00930000
* nated string having the UDF specific * 00940000
* name of this function. * 00950000
* * 00960000
* * 00970000
* Output: Parameters explicitly passed by this function: * 00980000
* - *dateOut : pointer to a char[18], null-termi- * 00990000
* nated string to receive the refor- * 01000000
* matted date. * 01010000
* - *niDateOut : pointer to a short integer to re- * 01020000
* ceive the null indicator variable * 01030000
* for *dateOut. * 01040000
* - *sqlstate : pointer to a char[06], null-termi- * 01050000
* nated string to receive the SQLSTATE.* 01060000
* - *message : pointer to a char[70], null-termi- * 01070000
* nated string to receive a diagnostic * 01080000
* message if one is generated by this * 01090000
* function. * 01100000
* * 01110000
* Normal Exit: Return Code: SQLSTATE = 00000 * 01120000
* - Message: none * 01130000
* * 01140000
* Error Exit: Return Code: SQLSTATE = 38601 * 01150000
* - Message: DSN8DUCD Error: No input date entered * 01160000
* - Message: DSN8DUCD Error: No input format entered * 01170000
* - Message: DSN8DUCD Error: No output format entered * 01180000
* * 01190000
* Return Code: SQLSTATE = 38602 * 01200000
* - Message: DSN8DUCD Error: Unknown input format * 01210000
* specified * 01220000
* - Message: DSN8DUCD Error: Value for year is incor- * 01230000
* rect or does not conform * 01240000
* to input format * 01250000
* - Message: DSN8DUCD Error: Value for month is incor- * 01260000
* rect or does not conform * 01270000
* to input format * 01280000
* - Message: DSN8DUCD Error: Value for day is incor- * 01290000
* rect or does not conform * 01300000
* to input format * 01310000
* * 01320000
* Return Code: SQLSTATE = 38602 * 01330000
* - Message: DSN8DUCD Error: Unknown output format * 01340000
* specified * 01350000
* * 01370000
* External References: * 01380000
* - Routines/Services: None * 01390000
* - Data areas : None * 01400000
* - Control blocks : None * 01410000
* * 01420000
* * 01430000
* Pseudocode: * 01440000
* DSN8DUCD: * 01450000
* - Issue sqlstate 38601 and a diagnostic message if no input date * 01460000
* was provided. * 01470000
* - Issue sqlstate 38601 and a diagnostic message if no input for- * 01480000
* mat was provided. * 01490000
* - Issue sqlstate 38601 and a diagnostic message if no output * 01500000
* format was provided. * 01510000
* - Call deconDate to deconstruct the input date into year, month, * 01520000
* and day components according to the input format. * 01530000
* - Call reconDate to create an output date from the year, month, * 01540000
* and day components according to the output format. * 01550000
* - If no errors, unset null indicators, and return SQLSTATE 00000 * 01560000
* else set null indicator and return null date out. * 01570000
* End DSN8DUCD * 01580000
* * 01590000
* deconDate * 01600000
* - Parse day, month, and year (sequence unknown) components from * 01610000
* the input date by breaking on delimiters (blank, /, ., and -). * 01620000
* - Use the input format to determine sequence of date components. * 01630000
* - if format invalid, issue SQLSTATE 38602 and a diag. message * 01640000
1192 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* - Call checkDay to validate the day component * 01650000
* - if not valid day, issue SQLSTATE 38602 and a diag. message * 01660000
* - Call checkMonth to validate the month component and convert it * 01670000
* (if required) from a calendar month name or roman numeral to * 01680000
* a month number (1-12). * 01690000
* - if not valid month, issue SQLSTATE 38602 and a diag. message * 01700000
* - Call checkYear to validate the year component. * 01710000
* - if not valid year, issue SQLSTATE 38602 and a diag. message * 01720000
* End deconDate * 01730000
* * 01740000
* reconDate * 01750000
* - Use the output format to edit and sequence the date components * 01760000
* - call add0prefix to prepend leading 0's to the day and/or * 01770000
* month component(s), as appropriate * 01780000
* - or call remove0prefix to drop leading 0's from the day and/ * 01790000
* or month component(s), as appropriate * 01800000
* - call nameMonth to convert the month number (1-12) to calen- * 01810000
* dar name, if appropriate * 01820000
* - call romanMonth to convert the month number (1-12) to roman * 01830000
* numeral, if appropriate * 01840000
* - call addCentury to convert a non-century year to century * 01850000
* date, if appropriate * 01860000
* - call removeCentury to convert a century year to non-century * 01870000
* if appropriate * 01880000
* - convert the month to a calendar name or roman numeral, if * 01890000
* appropriate * 01900000
* - convert the year to a non-century format, if appropriate * 01910000
* - if output format is invalid, issue SQLSTATE 38603 and a * 01920000
* diagnostic message * 01930000
* - Call buildDate to create the output date from the edited, re- * 01940000
* sequenced date components * 01950000
* End reconDate * 01960000
* * 01970000
* buildDate * 01980000
* - Generate the date out by concatenating the date componentents * 01990000
* (month, day, and year) with intervening delimiters (blank, ., * 02000000
* /, or -) in the sequence directed by reconDate * 02010000
* End buildDate * 02020000
* * 02030000
* nameMonth * 02040000
* - convert a month in the standard form, 1-12, to the correspond- * 02050000
* ing caldendar month name. * 02060000
* End nameMonth * 02070000
* * 02080000
* unnameMonth * 02090000
* - convert a calendar month name to the corresponding month no. * 02100000
* in the standard form, 1-12. * 02110000
* End unnameMonth * 02120000
* * 02130000
* romanMonth * 02140000
* - convert a month in the standard form, 1-12, to the correspond- * 02150000
* ing roman numeral, I-XII. * 02160000
* End romanMonth * 02170000
* * 02180000
* unromanMonth * 02190000
* - convert a roman numeral (I-XII) to the corresponding month no. * 02200000
* in the standard form, 1-12. * 02210000
* End unromanMonth * 02220000
* * 02230000
* checkYear * 02240000
* - Verify that the year component of the input date is one of the * 02250000
* following, in accordance with the input format: * 02260000
* - A valid century year (0000-9999) * 02270000
* - A valid non-century year (00-99) * 02280000
* - If not valid, set error flag and return null value for year * 02290000
* End checkYear * 02300000
* * 02310000
* checkMonth * 02320000
* - Verify the month component of the input date in accordance * 02330000
* with the input format: * 02340000
* - if the month is a calendar name, call unnameMonth to convert * 02350000
* it to a month number (1-12). * 02360000
* - if the month is a roman numeral, call unromanMonth to con- * 02370000
* vert it to a month number (1-12). * 02380000
* - If not valid, set error flag and return null value for month * 02390000
* End checkMonth * 02400000
* * 02410000
* checkDay * 02420000
* - Verify that the day component of the input date is one or two * 02430000
* numeric characters * 02440000
* - If not valid, set error flag and return null value for day * 02450000
* End checkDay * 02460000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1193
* * 02470000
* add0prefix * 02480000
* - prepend a day or month with a leading 0 if it is less than 10 * 02490000
* End add0prefix * 02500000
* * 02510000
* remove0prefix * 02520000
* - strip leading zero from a day or month if it is less than 10 * 02530000
* End remove0prefix * 02540000
* * 02550000
* addCentury * 02560000
* - If the year component is non-century format, prepend it with * 02570000
* the current century. * 02580000
* End addCentury * 02590000
* * 02600000
* removeCentury * 02610000
* - If the year component is century format, strip off the century * 02620000
* portion. * 02630000
* End removeCentury * 02640000
* * 02650000
* * 02660000
*********************************************************************/ 02670000
02680000
#pragma linkage(DSN8DUCD,fetchable) 02682990
02685980
/********************** C library definitions ***********************/ 02690000
#include <stdio.h> 02700000
#include <string.h> 02710000
#include <ctype.h> 02720000
#include <time.h> 02730000
02740000
/***************************** Equates ******************************/ 02750000
#define NULLCHAR '\0' /* Null character */ 02760000
02770000
#define MATCH 0 /* Comparison status: Equal */ 02780000
#define NOT_OK 0 /* Run status indicator: Error*/ 02790000
#define OK 1 /* Run status indicator: Good */ 02800000
02810000
02820000
/************************* Global constants *************************/ 02830000
char *char0 = "0"; 02840000
02850000
char *delimiters /* Valid format delimiters */ 02860000
= " .-/"; 02870000
02880000
char *monthNames[12] /* Month names */ 02890000
= { "January", "February", "March", 02900000
"April", "May", "June", 02910000
"July", "August", "September", 02920000
"October", "November", "December" }; 02930000
02940000
char *monthNums[12] /* Month numbers (as strings) */ 02950000
= { "1", "2", "3", 02960000
"4", "5", "6", 02970000
"7", "8", "9", 02980000
"10", "11", "12" }; 02990000
03000000
char *romanNums[12] /* Roman numerals */ 03010000
= { "I", "II", "III", 03020000
"IV", "V", "VI", 03030000
"VII", "VIII", "IX", 03040000
"X", "XI", "XII" }; 03050000
03060000
03070000
/*********************** DSN8DUCD functions *************************/ 03080000
void DSN8DUCD /* main routine */ 03090000
( char *dateIn, /* in: date to be converted */ 03100000
char *formatIn, /* in: format of dateIn */ 03110000
char *formatOut, /* in: format for dateOut */ 03120000
char *dateOut, /* out: reformatted date */ 03130000
short int *nullDateIn, /* in: indic var for dateIn */ 03140000
short int *nullFormatIn, /* in: indic var for formatIn */ 03150000
short int *nullFormatOut, /* in: indic var, formatOut */ 03160000
short int *nullDateOut, /* out: indic var for dateOut */ 03170000
char *sqlstate, /* out: SQLSTATE */ 03180000
char *fnName, /* in: family name of function*/ 03190000
char *specificName, /* in: specific name of func */ 03200000
char *message /* out: diagnostic message */ 03210000
); 03220000
03230000
int deconDate /* get yr, mo, dy from dateIn */ 03240000
( char *yr, /* out: year component */ 03250000
char *mo, /* out: month component */ 03260000
1194 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
char *dy, /* out: day component */ 03270000
char *message, /* out: diagnostic message */ 03280000
char *sqlstate, /* out: SQLSTATE */ 03290000
char *dateIn, /* in: inputted date string */ 03300000
char *fmtIn /* in: format of dateIn */ 03310000
); 03320000
03330000
int reconDate /* get dateOut from yr,mo,dy */ 03340000
( char *dateOut, /* out: reformatted date str */ 03350000
char *message, /* out: diagnostic message */ 03360000
char *sqlstate, /* out: SQLSTATE */ 03370000
char *yr, /* in: year component */ 03380000
char *mo, /* in: month component */ 03390000
char *dy, /* in: day component */ 03400000
char *fmtOut /* in: format for dateOut */ 03410000
); 03420000
03430000
void buildDate /* build date from parts */ 03440000
( char *dtOut, /* out: date */ 03450000
char *d1, /* in: year, month, or day */ 03460000
char *d2, /* in: year, month, or day */ 03470000
char *d3, /* in: year, month, or day */ 03480000
char *delim /* in: delimiter */ 03490000
); 03500000
03510000
void add0prefix /* add leading zero to string */ 03520000
( char *str3 /* in/out: string to prefix */ 03530000
); 03540000
03550000
void remove0prefix /* strips leading zeroes */ 03560000
( char *string /* in/out: string to strip */ 03570000
); 03580000
03590000
int nameMonth /* converts month num to name */ 03600000
( char *monthIn /* in/out: month to convert */ 03610000
); 03620000
03630000
int unnameMonth /* converts month name to num */ 03640000
( char *monthIn /* in/out: month to convert */ 03650000
); 03660000
03670000
int romanMonth /* converts month# to roman# */ 03680000
( char *monthIn /* in/out: month to convert */ 03690000
); 03700000
03710000
int unromanMonth /* converts roman# to month# */ 03720000
( char *monthIn /* in/out: month to convert */ 03730000
); 03740000
03750000
int checkYear /* verify/standardize yearIn */ 03760000
( char *yearOut, /* out: 4-digit yr, validated */ 03770000
char *yearIn, /* in: 2- or 4-digit year */ 03780000
char *style /* in: style of yearIn */ 03790000
); 03800000
03810000
int checkMonth /* verify/standardize monthIn */ 03820000
( char *monthOut, /* out: month#, validated */ 03830000
char *monthIn, /* in: month name, #, roman# */ 03840000
char *style /* in: style of monthIn */ 03850000
); 03860000
03870000
int checkDay /* verify/standardize dayIn */ 03880000
( char *dayOut, /* out: day, validated */ 03890000
char *dayIn /* in: day number */ 03900000
); 03910000
03920000
void addCentury /* adds century to yearIn */ 03930000
( char *yearIn /* in/out: year */ 03940000
); 03950000
03960000
void removeCentury /* strip century from yearIn */ 03970000
( char *yearIn /* in/out: year */ 03980000
); 03990000
04000000
/********************************************************************/ 04010000
/*************************** main routine ***************************/ 04020000
/********************************************************************/ 04030000
void DSN8DUCD /* main routine */ 04040000
( char *dateIn, /* in: date to be converted */ 04050000
char *formatIn, /* in: format of dateIn */ 04060000
char *formatOut, /* in: format for dateOut */ 04070000
char *dateOut, /* out: reformatted date */ 04080000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1195
short int *nullDateIn, /* in: indic var for dateIn */ 04090000
short int *nullFormatIn, /* in: indic var for formatIn */ 04100000
short int *nullFormatOut, /* in: indic var, formatOut */ 04110000
short int *nullDateOut, /* out: indic var for dateOut */ 04120000
char *sqlstate, /* out: SQLSTATE */ 04130000
char *fnName, /* in: family name of function*/ 04140000
char *specificName, /* in: specific name of func */ 04150000
char *message /* out: diagnostic message */ 04160000
) 04170000
/********************************************************************* 04180000
* * 04190000
* Assumptions: * 04200000
* - *dateIn points to a char[18], null-terminated string * 04210000
* - *formatIn, points to a char[14], null-terminated string * 04220000
* - *formatOut points to a char[14], null-terminated string * 04230000
* - *dateOut points to a char[18], null-terminated string * 04240000
* - *nullDateIn points to a short integer * 04250000
* - *nullFormatIn points to a short integer * 04260000
* - *nullFormatOut points to a short integer * 04270000
* - *nullDateOut points to a short integer * 04280000
* - *sqlstate points to a char[06], null-terminated string * 04290000
* - *fnName points to a char[138], null-terminated string * 04305990
* - *specificName points to a char[129], null-terminated string * 04311980
* - *message points to a char[70], null-terminated string * 04320000
*********************************************************************/ 04330000
{ 04340000
/************************ Local variables *************************/ 04350000
short int i; /* loop control vars */ 04360000
char year[5]; /* gets year from dateIn */ 04370000
char month[10]; /* gets month from dateIn */ 04380000
char day[3]; /* gets day from dateIn */ 04390000
04400000
short int status = OK; /* DSN8DUCD run status */ 04410000
04420000
/******************************************************************* 04430000
* Verify that an input date, its current format, and its new format* 04440000
* have been passed in. * 04450000
*******************************************************************/ 04460000
if( *nullDateIn || ( strlen( dateIn ) == 0 ) ) 04470000
{ 04480000
status = NOT_OK; 04490000
strcpy( message, 04500000
"DSN8DUCD Error: No input date entered" ); 04510000
strcpy( sqlstate, "38601" ); 04520000
} 04530000
else if( *nullFormatIn || ( strlen( formatIn ) == 0 ) ) 04540000
{ 04550000
status = NOT_OK; 04560000
strcpy( message, 04570000
"DSN8DUCD Error: No input format entered" ); 04580000
strcpy( sqlstate, "38601" ); 04590000
} 04600000
else if( *nullFormatOut || ( strlen( formatOut ) == 0 ) ) 04610000
{ 04620000
status = NOT_OK; 04630000
strcpy( message, 04640000
"DSN8DUCD Error: No output format entered" ); 04650000
strcpy( sqlstate, "38601" ); 04660000
} 04670000
04680000
/******************************************************************* 04690000
* Use formatIn to deconstruct date in into year, month, and day * 04700000
*******************************************************************/ 04710000
if( status == OK ) 04720000
status = deconDate( year, month, day, message, sqlstate, 04730000
dateIn, formatIn ); 04740000
04750000
/******************************************************************* 04760000
* Use formatOut to reconstruct date from year, month, and day * 04770000
*******************************************************************/ 04780000
if( status == OK ) 04790000
status = reconDate( dateOut, message, sqlstate, 04800000
year, month, day, formatOut ); 04810000
04820000
/******************************************************************* 04830000
* If conversion was successful, clear the message buffer and sql- * 04840000
* state, and unset the SQL null indicator for dateOut. * 04850000
*******************************************************************/ 04860000
if( status == OK ) 04870000
{ 04880000
*nullDateOut = 0; 04890000
message[0] = NULLCHAR; 04900000
1196 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
strcpy( sqlstate,"00000" ); 04910000
} 04920000
/******************************************************************* 04930000
* If errors occurred, clear the dateOut buffer and set the SQL null* 04940000
* indicator. A diagnostic message and the SQLSTATE have been set * 04950000
* where the error was detected. * 04960000
*******************************************************************/ 04970000
else 04980000
{ 04990000
dateOut[0] = NULLCHAR; 05000000
*nullDateOut = -1; 05010000
} 05020000
05030000
return; 05040000
} /* end of DSN8DUCD */ 05050000
05060000
05070000
/********************************************************************/ 05080000
/***************************** Functions ****************************/ 05090000
/********************************************************************/ 05100000
int deconDate /* get yr, mo, dy from dateIn */ 05110000
( char *yr, /* out: year component */ 05120000
char *mo, /* out: month component */ 05130000
char *dy, /* out: day component */ 05140000
char *message, /* out: diagnostic message */ 05150000
char *sqlstate, /* out: SQLSTATE */ 05160000
char *dateIn, /* in: inputted date string */ 05170000
char *fmtIn /* in: format of dateIn */ 05180000
) 05190000
/********************************************************************* 05200000
* Deconstructs *dateIn into *yr, *mo, and *dy according to *fmtIn. * 05210000
* Returns 1 if deconstruction succeeds, otherwise places diagnostic * 05220000
* text in *message and returns 0. * 05230000
*********************************************************************/ 05240000
{ 05250000
/************************ Local variables *************************/ 05260000
05270000
short int func_status = OK; /* function status indicator */ 05280000
short int yrStatus = OK; /* indicates if year is OK */ 05290000
short int moStatus = OK; /* " " month " " */ 05300000
short int dyStatus = OK; /* " " day " " */ 05310000
short int ftStatus = OK; /* " " format " " */ 05320000
05330000
char workDateIn[18]; /* work copy of dateIn */ 05340000
char *token; /* Value from token parser */ 05350000
05360000
char tok1[17]; /* Gets 1st date component */ 05370000
char tok2[17]; /* " 2nd " " */ 05380000
char tok3[17]; /* " 3rd " " */ 05390000
05400000
/******************************************************************* 05410000
* Parse day, month, and year (order unknown) from dateIn * 05420000
*******************************************************************/ 05430000
strcpy( workDateIn,dateIn ); 05440000
token = strtok( workDateIn," .-/" ); 05450000
strcpy( tok1,token ); 05460000
token = strtok( NULL," .-/" ); 05470000
strcpy( tok2,token ); 05480000
token = strtok( NULL," .-/" ); 05490000
strcpy( tok3,token ); 05500000
05510000
/******************************************************************* 05520000
* Use fmtIn to check and set year, month, and day from date tokens * 05530000
*******************************************************************/ 05540000
if( ( strcmp( fmtIn,"D MONTH YY" ) == MATCH ) 05550000
|| ( strcmp( fmtIn,"DD MONTH YY" ) == MATCH ) ) 05560000
{ 05570000
dyStatus = checkDay( dy,tok1 ); 05580000
moStatus = checkMonth( mo,tok2,"MONTH" ); 05590000
yrStatus = checkYear( yr,tok3,"YY" ); 05600000
} 05610000
else if( ( strcmp( fmtIn,"D MONTH YYYY" ) == MATCH ) 05620000
|| ( strcmp( fmtIn,"DD MONTH YYYY" ) == MATCH ) ) 05630000
{ 05640000
dyStatus = checkDay( dy,tok1 ); 05650000
moStatus = checkMonth( mo,tok2,"MONTH" ); 05660000
yrStatus = checkYear( yr,tok3,"YYYY" ); 05670000
} 05680000
else if( ( strcmp( fmtIn,"D.M.YY" ) == MATCH ) 05690000
|| ( strcmp( fmtIn,"DD.MM.YY" ) == MATCH ) 05700000
|| ( strcmp( fmtIn,"D-M-YY" ) == MATCH ) 05710000
|| ( strcmp( fmtIn,"DD-MM-YY" ) == MATCH ) 05720000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1197
|| ( strcmp( fmtIn,"D/M/YY" ) == MATCH ) 05730000
|| ( strcmp( fmtIn,"DD/MM/YY" ) == MATCH ) ) 05740000
{ 05750000
dyStatus = checkDay( dy,tok1 ); 05760000
moStatus = checkMonth( mo,tok2,"M/MM" ); 05770000
yrStatus = checkYear( yr,tok3,"YY" ); 05780000
} 05790000
else if( ( strcmp( fmtIn,"D.M.YYYY" ) == MATCH ) 05800000
|| ( strcmp( fmtIn,"DD.MM.YYYY" ) == MATCH ) 05810000
|| ( strcmp( fmtIn,"D-M-YYYY" ) == MATCH ) 05820000
|| ( strcmp( fmtIn,"DD-MM-YYYY" ) == MATCH ) 05830000
|| ( strcmp( fmtIn,"D/M/YYYY" ) == MATCH ) 05840000
|| ( strcmp( fmtIn,"DD/MM/YYYY" ) == MATCH ) ) 05850000
{ 05860000
dyStatus = checkDay( dy,tok1 ); 05870000
moStatus = checkMonth( mo,tok2,"M/MM" ); 05880000
yrStatus = checkYear( yr,tok3,"YYYY" ); 05890000
} 05900000
else if( ( strcmp( fmtIn,"M/D/YY" ) == MATCH ) 05910000
|| ( strcmp( fmtIn,"MM/DD/YY" ) == MATCH ) ) 05920000
{ 05930000
moStatus = checkMonth( mo,tok1,"M/MM" ); 05940000
dyStatus = checkDay( dy,tok2 ); 05950000
yrStatus = checkYear( yr,tok3,"YY" ); 05960000
} 05970000
else if( ( strcmp( fmtIn,"M/D/YYYY" ) == MATCH ) 05980000
|| ( strcmp( fmtIn,"MM/DD/YYYY" ) == MATCH ) ) 05990000
{ 06000000
moStatus = checkMonth( mo,tok1,"M/MM" ); 06010000
dyStatus = checkDay( dy,tok2 ); 06020000
yrStatus = checkYear( yr,tok3,"YYYY" ); 06030000
} 06040000
else if( ( strcmp( fmtIn,"YY/M/D" ) == MATCH ) 06050000
|| ( strcmp( fmtIn,"YY/MM/DD" ) == MATCH ) 06060000
|| ( strcmp( fmtIn,"YY.M.D" ) == MATCH ) 06070000
|| ( strcmp( fmtIn,"YY.MM.DD" ) == MATCH ) ) 06080000
{ 06090000
yrStatus = checkYear( yr,tok1,"YY" ); 06100000
moStatus = checkMonth( mo,tok2,"M/MM" ); 06110000
dyStatus = checkDay( dy,tok3 ); 06120000
} 06130000
else if( ( strcmp( fmtIn,"YYYY/M/D" ) == MATCH ) 06140000
|| ( strcmp( fmtIn,"YYYY/MM/DD" ) == MATCH ) 06150000
|| ( strcmp( fmtIn,"YYYY.M.D" ) == MATCH ) 06160000
|| ( strcmp( fmtIn,"YYYY.MM.DD" ) == MATCH ) 06170000
|| ( strcmp( fmtIn,"YYYY-M-D" ) == MATCH ) 06180000
|| ( strcmp( fmtIn,"YYYY-MM-DD" ) == MATCH ) ) 06190000
{ 06200000
yrStatus = checkYear( yr,tok1,"YYYY" ); 06210000
moStatus = checkMonth( mo,tok2,"M/MM" ); 06220000
dyStatus = checkDay( dy,tok3 ); 06230000
} 06240000
else if( ( strcmp( fmtIn,"YYYY-D-XX" ) == MATCH ) 06250000
|| ( strcmp( fmtIn,"YYYY-DD-XX" ) == MATCH ) ) 06260000
{ 06270000
yrStatus = checkYear( yr,tok1,"YYYY" ); 06280000
dyStatus = checkDay( dy,tok2 ); 06290000
moStatus = checkMonth( mo,tok3,"XX" ); 06300000
} 06310000
else if( ( strcmp( fmtIn,"YYYY-XX-D" ) == MATCH ) 06320000
|| ( strcmp( fmtIn,"YYYY-XX-DD" ) == MATCH ) ) 06330000
{ 06340000
yrStatus = checkYear( yr,tok1,"YYYY" ); 06350000
moStatus = checkMonth( mo,tok2,"XX" ); 06360000
dyStatus = checkDay( dy,tok3 ); 06370000
} 06380000
else /* date-in format is invalid or unknown */ 06390000
ftStatus = NOT_OK; 06400000
06410000
/******************************************************************* 06420000
* set up error handling * 06430000
*******************************************************************/ 06440000
func_status = NOT_OK; 06450000
strcpy( message,"DSN8DUCD Error: " ); 06460000
strcpy( sqlstate, "38602" ); 06470000
06480000
/******************************************************************* 06490000
* if error detected, issue diagnostic message and return NOT_OK * 06500000
*******************************************************************/ 06510000
if( ftStatus != OK ) 06520000
strcpy( message, 06530000
"Unknown input format specified" ); 06540000
1198 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
else if( yrStatus != OK ) 06550000
strcpy( message, 06560000
"Value for year " 06570000
"is incorrect or does not " 06580000
"conform to input format" ); 06590000
else if( moStatus != OK ) 06600000
strcpy( message, 06610000
"Value for month " 06620000
"is incorrect or does not " 06630000
"conform to input format " ); 06640000
else if( dyStatus != OK ) 06650000
strcpy( message, 06660000
"Value for day " 06670000
"is incorrect or does not " 06680000
"conform to input format " ); 06690000
06700000
/******************************************************************* 06710000
* if no error detected, clear message and sqlstate and return OK * 06720000
*******************************************************************/ 06730000
else 06740000
{ 06750000
*message = NULLCHAR; 06760000
func_status = OK; 06770000
strcpy( sqlstate, "00000" ); 06780000
} 06790000
06800000
return( func_status ); 06810000
} /* end deconDate */ 06820000
06830000
int reconDate /* get dateOut from yr,mo,dy */ 06840000
( char *dateOut, /* out: reformatted date str */ 06850000
char *message, /* out: diagnostic message */ 06860000
char *sqlstate, /* out: SQLSTATE */ 06870000
char *yr, /* in: year component */ 06880000
char *mo, /* in: month component */ 06890000
char *dy, /* in: day component */ 06900000
char *fmtOut /* in: format for dateOut */ 06910000
) 06920000
/********************************************************************* 06930000
* Reconstructs *yr, *mo, and *dy into *dateOut according to *fmtOut. * 06940000
* Returns 1 if reconstruction succeeds, otherwise places diagnostic * 06950000
* text in *message and returns 0. * 06960000
*********************************************************************/ 06970000
{ 06980000
/************************ Local variables *************************/ 06990000
07000000
short int func_status = OK; /* function status indicator */ 07010000
07020000
/******************************************************************* 07030000
* Use fmtOut to reformat date from year, month, and day tokens * 07040000
*******************************************************************/ 07050000
if( strcmp( fmtOut,"D MONTH YY" ) == MATCH ) 07060000
{ 07070000
remove0prefix( dy ); /* strip leading 0 if day < 10*/ 07080000
nameMonth( mo ); /* convert month no. to name */ 07090000
removeCentury( yr ); /* strip century from year */ 07100000
buildDate( dateOut, dy, mo, yr, " " ); 07110000
} 07120000
else if( strcmp( fmtOut,"DD MONTH YY" ) == MATCH ) 07130000
{ 07140000
add0prefix( dy ); /* add leading 0 if day < 10 */ 07150000
nameMonth( mo ); /* convert month no. to name */ 07160000
removeCentury( yr ); /* strip century from year */ 07170000
buildDate( dateOut, dy, mo, yr, " " ); 07180000
} 07190000
else if( strcmp( fmtOut,"D MONTH YYYY" ) == MATCH ) 07200000
{ 07210000
remove0prefix( dy ); /* strip leading 0 if day < 10*/ 07220000
nameMonth( mo ); /* convert month no. to name */ 07230000
addCentury( yr ); /* ensure year has century */ 07240000
buildDate( dateOut, dy, mo, yr, " " ); 07250000
} 07260000
else if( strcmp( fmtOut,"DD MONTH YYYY" ) == MATCH ) 07270000
{ 07280000
add0prefix( dy ); /* add leading 0 if day < 10 */ 07290000
nameMonth( mo ); /* convert month no. to name */ 07300000
addCentury( yr ); /* ensure year has century */ 07310000
buildDate( dateOut, dy, mo, yr, " " ); 07320000
} 07330000
else if( strcmp( fmtOut,"D.M.YY" ) == MATCH ) 07340000
{ 07350000
remove0prefix( dy ); /* strip leading 0 if day < 10*/ 07360000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1199
remove0prefix( mo ); /* strip leading 0 if mon < 10*/ 07370000
removeCentury( yr ); /* strip century from year */ 07380000
buildDate( dateOut, dy, mo, yr, "." ); 07390000
} 07400000
else if( strcmp( fmtOut,"DD.MM.YY" ) == MATCH ) 07410000
{ 07420000
add0prefix( dy ); /* add leading 0 if day < 10 */ 07430000
add0prefix( mo ); /* add leading 0 if mon < 10 */ 07440000
removeCentury( yr ); /* strip century from year */ 07450000
buildDate( dateOut, dy, mo, yr, "." ); 07460000
} 07470000
else if( strcmp( fmtOut,"D-M-YY" ) == MATCH ) 07480000
{ 07490000
remove0prefix( dy ); /* strip leading 0 if day < 10*/ 07500000
remove0prefix( mo ); /* strip leading 0 if mon < 10*/ 07510000
removeCentury( yr ); /* strip century from year */ 07520000
buildDate( dateOut, dy, mo, yr, "-" ); 07530000
} 07540000
else if( strcmp( fmtOut,"DD-MM-YY" ) == MATCH ) 07550000
{ 07560000
add0prefix( dy ); /* add leading 0 if day < 10 */ 07570000
add0prefix( mo ); /* add leading 0 if mon < 10 */ 07580000
removeCentury( yr ); /* strip century from year */ 07590000
buildDate( dateOut, dy, mo, yr, "-" ); 07600000
} 07610000
else if( strcmp( fmtOut,"D/M/YY" ) == MATCH ) 07620000
{ 07630000
remove0prefix( dy ); /* strip leading 0 if day < 10*/ 07640000
remove0prefix( mo ); /* strip leading 0 if mon < 10*/ 07650000
removeCentury( yr ); /* strip century from year */ 07660000
buildDate( dateOut, dy, mo, yr, "/" ); 07670000
} 07680000
else if( strcmp( fmtOut,"DD/MM/YY" ) == MATCH ) 07690000
{ 07700000
add0prefix( dy ); /* add leading 0 if day < 10 */ 07710000
add0prefix( mo ); /* add leading 0 if mon < 10 */ 07720000
removeCentury( yr ); /* strip century from year */ 07730000
buildDate( dateOut, dy, mo, yr, "/" ); 07740000
} 07750000
else if( strcmp( fmtOut,"D.M.YYYY" ) == MATCH ) 07760000
{ 07770000
remove0prefix( dy ); /* strip leading 0 if day < 10*/ 07780000
remove0prefix( mo ); /* strip leading 0 if mon < 10*/ 07790000
addCentury( yr ); /* ensure year has century */ 07800000
buildDate( dateOut, dy, mo, yr, "." ); 07810000
} 07820000
else if( strcmp( fmtOut,"DD.MM.YYYY" ) == MATCH ) 07830000
{ 07840000
add0prefix( dy ); /* add leading 0 if day < 10 */ 07850000
add0prefix( mo ); /* add leading 0 if mon < 10 */ 07860000
addCentury( yr ); /* ensure year has century */ 07870000
buildDate( dateOut, dy, mo, yr, "." ); 07880000
} 07890000
else if( strcmp( fmtOut,"D-M-YYYY" ) == MATCH ) 07900000
{ 07910000
remove0prefix( dy ); /* strip leading 0 if day < 10*/ 07920000
remove0prefix( mo ); /* strip leading 0 if mon < 10*/ 07930000
addCentury( yr ); /* ensure year has century */ 07940000
buildDate( dateOut, dy, mo, yr, "-" ); 07950000
} 07960000
else if( strcmp( fmtOut,"DD-MM-YYYY" ) == MATCH ) 07970000
{ 07980000
add0prefix( dy ); /* add leading 0 if day < 10 */ 07990000
add0prefix( mo ); /* add leading 0 if mon < 10 */ 08000000
addCentury( yr ); /* ensure year has century */ 08010000
buildDate( dateOut, dy, mo, yr, "-" ); 08020000
} 08030000
else if( strcmp( fmtOut,"D/M/YYYY" ) == MATCH ) 08040000
{ 08050000
remove0prefix( dy ); /* strip leading 0 if day < 10*/ 08060000
remove0prefix( mo ); /* strip leading 0 if mon < 10*/ 08070000
addCentury( yr ); /* ensure year has century */ 08080000
buildDate( dateOut, dy, mo, yr, "/" ); 08090000
} 08100000
else if( strcmp( fmtOut,"DD/MM/YYYY" ) == MATCH ) 08110000
{ 08120000
add0prefix( dy ); /* add leading 0 if day < 10 */ 08130000
add0prefix( mo ); /* add leading 0 if mon < 10 */ 08140000
addCentury( yr ); /* ensure year has century */ 08150000
buildDate( dateOut, dy, mo, yr, "/" ); 08160000
} 08170000
else if( strcmp( fmtOut,"M/D/YY" ) == MATCH ) 08180000
1200 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
{ 08190000
remove0prefix( mo ); /* strip leading 0 if day < 10*/ 08200000
remove0prefix( dy ); /* strip leading 0 if mon < 10*/ 08210000
removeCentury( yr ); /* strip century from year */ 08220000
buildDate( dateOut, mo, dy, yr,"/" ); 08230000
} 08240000
else if( strcmp( fmtOut,"MM/DD/YY" ) == MATCH ) 08250000
{ 08260000
add0prefix( mo ); /* add leading 0 if mon < 10 */ 08270000
add0prefix( dy ); /* add leading 0 if day < 10 */ 08280000
removeCentury( yr ); /* strip century from year */ 08290000
buildDate( dateOut, mo, dy, yr, "/" ); 08300000
} 08310000
else if( strcmp( fmtOut,"M/D/YYYY" ) == MATCH ) 08320000
{ 08330000
remove0prefix( mo ); /* strip leading 0 if mon < 10*/ 08340000
remove0prefix( dy ); /* strip leading 0 if day < 10*/ 08350000
addCentury( yr ); /* ensure year has century */ 08360000
buildDate( dateOut, mo, dy, yr, "/" ); 08370000
} 08380000
else if( strcmp( fmtOut,"MM/DD/YYYY" ) == MATCH ) 08390000
{ 08400000
add0prefix( mo ); /* add leading 0 if mon < 10 */ 08410000
add0prefix( dy ); /* add leading 0 if day < 10 */ 08420000
addCentury( yr ); /* ensure year has century */ 08430000
buildDate( dateOut, mo, dy, yr, "/" ); 08440000
} 08450000
else if( strcmp( fmtOut,"YY/M/D" ) == MATCH ) 08460000
{ 08470000
removeCentury( yr ); /* strip century from year */ 08480000
remove0prefix( mo ); /* strip leading 0 if mon < 10*/ 08490000
remove0prefix( dy ); /* strip leading 0 if day < 10*/ 08500000
buildDate( dateOut, yr, mo, dy, "/" ); 08510000
} 08520000
else if( strcmp( fmtOut,"YY/MM/DD" ) == MATCH ) 08530000
{ 08540000
removeCentury( yr ); /* strip century from year */ 08550000
add0prefix( mo ); /* add leading 0 if mon < 10 */ 08560000
add0prefix( dy ); /* add leading 0 if day < 10 */ 08570000
buildDate( dateOut, yr, mo, dy, "/" ); 08580000
} 08590000
else if( strcmp( fmtOut,"YY.M.D" ) == MATCH ) 08600000
{ 08610000
removeCentury( yr ); /* strip century from year */ 08620000
remove0prefix( mo ); /* strip leading 0 if mon < 10*/ 08630000
remove0prefix( dy ); /* strip leading 0 if day < 10*/ 08640000
buildDate( dateOut, yr, mo, dy, "." ); 08650000
} 08660000
else if( strcmp( fmtOut,"YY.MM.DD" ) == MATCH ) 08670000
{ 08680000
removeCentury( yr ); /* strip century from year */ 08690000
add0prefix( mo ); /* add leading 0 if mon < 10 */ 08700000
add0prefix( dy ); /* add leading 0 if day < 10 */ 08710000
buildDate( dateOut, yr, mo, dy, "." ); 08720000
} 08730000
else if( strcmp( fmtOut,"YYYY/M/D" ) == MATCH ) 08740000
{ 08750000
addCentury( yr ); /* ensure year has century */ 08760000
remove0prefix( mo ); /* strip leading 0 if mon < 10*/ 08770000
remove0prefix( dy ); /* strip leading 0 if day < 10*/ 08780000
buildDate( dateOut, yr, mo, dy, "/" ); 08790000
} 08800000
else if( strcmp( fmtOut,"YYYY/MM/DD" ) == MATCH ) 08810000
{ 08820000
addCentury( yr ); /* ensure year has century */ 08830000
add0prefix( mo ); /* add leading 0 if mon < 10 */ 08840000
add0prefix( dy ); /* add leading 0 if day < 10 */ 08850000
buildDate( dateOut, yr, mo, dy, "/" ); 08860000
} 08870000
else if( strcmp( fmtOut,"YYYY.M.D" ) == MATCH ) 08880000
{ 08890000
addCentury( yr ); /* ensure year has century */ 08900000
remove0prefix( mo ); /* strip leading 0 if mon < 10*/ 08910000
remove0prefix( dy ); /* strip leading 0 if day < 10*/ 08920000
buildDate( dateOut, yr, mo, dy, "." ); 08930000
} 08940000
else if( strcmp( fmtOut,"YYYY.MM.DD" ) == MATCH ) 08950000
{ 08960000
addCentury( yr ); /* ensure year has century */ 08970000
add0prefix( mo ); /* add leading 0 if mon < 10 */ 08980000
add0prefix( dy ); /* add leading 0 if day < 10 */ 08990000
buildDate( dateOut, yr, mo, dy, "." ); 09000000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1201
} 09010000
else if( strcmp( fmtOut,"YYYY-M-D" ) == MATCH ) 09020000
{ 09030000
addCentury( yr ); /* ensure year has century */ 09040000
remove0prefix( mo ); /* strip leading 0 if mon < 10*/ 09050000
remove0prefix( dy ); /* strip leading 0 if day < 10*/ 09060000
buildDate( dateOut, yr, mo, dy, "-" ); 09070000
} 09080000
else if( strcmp( fmtOut,"YYYY-MM-DD" ) == MATCH ) 09090000
{ 09100000
addCentury( yr ); /* ensure year has century */ 09110000
add0prefix( mo ); /* add leading 0 if mon < 10 */ 09120000
add0prefix( dy ); /* add leading 0 if day < 10 */ 09130000
buildDate( dateOut, yr, mo, dy, "-" ); 09140000
} 09150000
else if( strcmp( fmtOut,"YYYY-D-XX" ) == MATCH ) 09160000
{ 09170000
addCentury( yr ); /* ensure year has century */ 09180000
remove0prefix( dy ); /* strip leading 0 if day < 10*/ 09190000
romanMonth( mo ); /* convert month# to roman no.*/ 09200000
buildDate( dateOut, yr, dy, mo, "-" ); 09210000
} 09220000
else if( strcmp( fmtOut,"YYYY-DD-XX" ) == MATCH ) 09230000
{ 09240000
addCentury( yr ); /* ensure year has century */ 09250000
add0prefix( dy ); /* add leading 0 if day < 10 */ 09260000
romanMonth( mo ); /* convert month# to roman no.*/ 09270000
buildDate( dateOut, yr, dy, mo, "-" ); 09280000
} 09290000
else if( strcmp( fmtOut,"YYYY-XX-D" ) == MATCH ) 09300000
{ 09310000
addCentury( yr ); /* ensure year has century */ 09320000
romanMonth( mo ); /* convert month# to roman no.*/ 09330000
remove0prefix( dy ); /* strip leading 0 if day < 10*/ 09340000
buildDate( dateOut, yr, mo, dy, "-" ); 09350000
} 09360000
else if( strcmp( fmtOut,"YYYY-XX-DD" ) == MATCH ) 09370000
{ 09380000
addCentury( yr ); /* ensure year has century */ 09390000
romanMonth( mo ); /* convert month# to roman no.*/ 09400000
add0prefix( dy ); /* add leading 0 if day < 10 */ 09410000
buildDate( dateOut, yr, mo, dy, "-" ); 09420000
} 09430000
else /* date-in format is invalid or unknown */ 09440000
func_status = NOT_OK; 09450000
09460000
if( func_status != OK ) 09470000
{ 09480000
strcpy( sqlstate, "38603" ); 09490000
strcpy( message, 09500000
"Unknown output format specified" ); 09510000
} 09520000
else 09530000
{ 09540000
*message = NULLCHAR; 09550000
strcpy( sqlstate, "00000" ); 09560000
} 09570000
09580000
return( func_status ); 09590000
} /* end reconDate */ 09600000
09610000
09620000
void buildDate /* build date from parts */ 09630000
( char *dtOut, /* out: date */ 09640000
char *d1, /* in: year, month, or day */ 09650000
char *d2, /* in: year, month, or day */ 09660000
char *d3, /* in: year, month, or day */ 09670000
char *delim /* in: delimiter */ 09680000
) 09690000
/********************************************************************* 09700000
* Forms a date by concatenating d1, delim, d2, delim, and d3. * 09710000
*********************************************************************/ 09720000
{ 09730000
strcpy( dtOut, d1 ); 09740000
strcat( dtOut, delim ); 09750000
strcat( dtOut, d2 ); 09760000
strcat( dtOut, delim ); 09770000
strcat( dtOut, d3 ); 09780000
} /* end buildDate */ 09790000
09800000
09810000
int nameMonth /* converts month num to name */ 09820000
1202 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
( char *monthIn /* in/out: month to convert */ 09830000
) 09840000
/********************************************************************* 09850000
* Converts *monthIn from a number string to a name. Returns 1 if * 09860000
* conversion succeeds, otherwise returns 0. * 09870000
*********************************************************************/ 09880000
{ 09890000
/************************ Local variables *************************/ 09900000
09910000
short int i; /* loop control */ 09920000
short int func_status = OK; /* function status indicator */ 09930000
09940000
/******************************************************************* 09950000
* Strip leading zero (if any) from monthIn * 09960000
*******************************************************************/ 09970000
remove0prefix( monthIn ); 09980000
09990000
/******************************************************************* 10000000
* Look up *monthIn in the month number strings array * 10010000
*******************************************************************/ 10020000
for( i=0; i<12 && strcmp( monthIn,monthNums[i] ) != MATCH; i++ ); 10030000
10040000
/******************************************************************* 10050000
* If found assign month name else set function error indicator * 10060000
*******************************************************************/ 10070000
if( i < 12 ) 10080000
strcpy( monthIn,monthNames[i] ); 10090000
else 10100000
func_status = NOT_OK; 10110000
10120000
return( func_status ); 10130000
10140000
} /* end nameMonth */ 10150000
10160000
10170000
int unnameMonth /* converts month name to num */ 10180000
( char *monthIn /* in/out: month to convert */ 10190000
) 10200000
/********************************************************************* 10210000
* Converts *monthIn from a name to a number string. Returns 1 if * 10220000
* conversion succeeds, otherwise returns 0. * 10230000
*********************************************************************/ 10240000
{ 10250000
/************************ Local variables *************************/ 10260000
10270000
short int i; /* loop control */ 10280000
short int func_status = OK; /* function status indicator */ 10290000
10300000
/******************************************************************* 10310000
* Make 1st char of month name upper case and the rest lower case * 10320000
*******************************************************************/ 10330000
monthIn[0] = toupper(monthIn[0]); 10340000
for( i=1;i<strlen(monthIn);i++ ) 10350000
monthIn[i] = tolower(monthIn[i]); 10360000
10370000
/******************************************************************* 10380000
* Look up *monthIn in the month names array * 10390000
*******************************************************************/ 10400000
for( i=0; i<12 && strcmp( monthIn,monthNames[i] ) != MATCH; i++ ); 10410000
10420000
/******************************************************************* 10430000
* If found assign month no. str else set function error indicator * 10440000
*******************************************************************/ 10450000
if( i < 12 ) 10460000
strcpy( monthIn,monthNums[i] ); 10470000
else 10480000
func_status = NOT_OK; 10490000
10500000
return( func_status ); 10510000
10520000
} /* end unnameMonth */ 10530000
10540000
10550000
int romanMonth /* converts month# to roman# */ 10560000
( char *monthIn /* in/out: month to convert */ 10570000
) 10580000
/********************************************************************* 10590000
* Converts *monthIn from a number string to a roman numeral. Returns * 10600000
* 1 if conversion succeeds, otherwise returns 0. * 10610000
*********************************************************************/ 10620000
{ 10630000
/************************ Local variables *************************/ 10640000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1203
10650000
short int i; /* loop control */ 10660000
short int func_status = OK; /* function status indicator */ 10670000
10680000
/******************************************************************* 10690000
* Strip leading zero (if any) from monthIn * 10700000
*******************************************************************/ 10710000
remove0prefix( monthIn ); 10720000
10730000
/******************************************************************* 10740000
* Look up *monthIn in the month number strings array * 10750000
*******************************************************************/ 10760000
for( i=0; i<12 && strcmp( monthIn,monthNums[i] ) != MATCH; i++ ); 10770000
10780000
/******************************************************************* 10790000
* If found assign roman numeral else set function error indicator * 10800000
*******************************************************************/ 10810000
if( i < 12 ) 10820000
strcpy( monthIn,romanNums[i] ); 10830000
else 10840000
func_status = NOT_OK; 10850000
10860000
return( func_status ); 10870000
10880000
} /* end romanMonth */ 10890000
10900000
10910000
int unromanMonth /* converts roman# to month# */ 10920000
( char *monthIn /* in/out: month to convert */ 10930000
) 10940000
/********************************************************************* 10950000
* Converts *monthIn from a roman numeral to a number string. Returns * 10960000
* 1 if conversion succeeds, otherwise returns 0. * 10970000
*********************************************************************/ 10980000
{ 10990000
/************************ Local variables *************************/ 11000000
11010000
short int i; /* loop control */ 11020000
short int func_status = OK; /* function status indicator */ 11030000
11040000
/******************************************************************* 11050000
* Convert all chars of *monthIn to upper case * 11060000
*******************************************************************/ 11070000
for( i=0; i<strlen(monthIn); i++ ) 11080000
monthIn[i] = toupper(monthIn[i]); 11090000
11100000
/******************************************************************* 11110000
* Look up *monthIn in the roman numerals array * 11120000
*******************************************************************/ 11130000
for( i=0; i<12 && strcmp( monthIn,romanNums[i] ) != MATCH; i++ ); 11140000
11150000
/******************************************************************* 11160000
* If found assign month no. str else set function error indicator * 11170000
*******************************************************************/ 11180000
if( i < 12 ) 11190000
strcpy( monthIn,monthNums[i] ); 11200000
else 11210000
func_status = NOT_OK; 11220000
11230000
return( func_status ); 11240000
11250000
} /* end unromanMonth */ 11260000
11270000
11280000
int checkYear /* verify/standardize yearIn */ 11290000
( char *yearOut, /* out: 4-digit yr, validated */ 11300000
char *yearIn, /* in: 2- or 4-digit year */ 11310000
char *style /* in: style of yearIn */ 11320000
) 11330000
/********************************************************************* 11340000
* Verifies that *yearIn is either of the following: * 11350000
* - 2 numeric characters if *style is YY; or * 11360000
* - 4 numeric characters if *style is YYYY. * 11370000
* If criteria satisfied, copies *yearIn to *yearOut and returns 1. * 11380000
* If criteria not satisfied, sets *yearOut to null and returns 0. * 11390000
*********************************************************************/ 11400000
{ 11410000
/************************ Local variables *************************/ 11420000
11430000
short int i; /* loop control */ 11440000
short int yearIn_len /* length of *yearIn */ 11450000
= strlen( yearIn ); 11460000
1204 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
short int func_status = OK; /* function status indicator */ 11470000
11480000
/******************************************************************* 11490000
* Verify that all bytes of *yearIn are numeric characters * 11500000
*******************************************************************/ 11510000
for( i=0; (i<yearIn_len) && (isdigit(yearIn[i])); i++ ); 11520000
if( i < yearIn_len ) 11530000
func_status = NOT_OK; 11540000
/******************************************************************* 11550000
* If input format is YY, verify that *yearIn has 2 bytes * 11560000
*******************************************************************/ 11570000
else if( (strcmp( style,"YY" ) == MATCH) && (yearIn_len != 2) ) 11580000
func_status = NOT_OK; 11590000
/******************************************************************* 11600000
* If input format is YYYY, verify that *yearIn has 4 bytes * 11610000
*******************************************************************/ 11620000
else if( (strcmp( style,"YYYY" ) == MATCH) && (yearIn_len != 4) ) 11630000
func_status = NOT_OK; 11640000
11650000
/******************************************************************* 11660000
* If all checks satisfied, copy *yearIn to *yearOut and return 1 * 11670000
*******************************************************************/ 11680000
if( func_status == OK ) 11690000
strcpy( yearOut, yearIn ); 11700000
/******************************************************************* 11710000
* If a check failed, sets *yearOut to null and return 0 * 11720000
*******************************************************************/ 11730000
else 11740000
*yearOut = NULLCHAR; 11750000
11760000
return( func_status ); 11770000
} /* end checkYear */ 11780000
11790000
11800000
int checkMonth /* verify/standardize monthIn */ 11810000
( char *monthOut, /* out: month#, validated */ 11820000
char *monthIn, /* in: month name, #, roman# */ 11830000
char *style /* in: style of monthIn */ 11840000
) 11850000
/********************************************************************* 11860000
* Verifies that *monthIn is one of the following: * 11870000
* - A valid month name, January - December, if *style is MONTH; or * 11880000
* - A valid roman numeral, I - XII, if *style is XX; or * 11890000
* - 1 or 2 numeric characters between 1 and 12 if *style is M or MM. * 11900000
* If criteria satisfied, copies *monthIn to *monthOut and returns 1. * 11910000
* - if *monthIn is a month name or a roman numeral, it will have * 11920000
* been standardized to the form 1-12. * 11930000
* If criteria not satisfied, sets *monthOut to null and returns 0. * 11940000
*********************************************************************/ 11950000
{ 11960000
/************************ Local variables *************************/ 11970000
11980000
short int i; /* loop control */ 11990000
short int func_status = OK; /* function status indicator */ 12000000
12010000
/******************************************************************* 12020000
* If *style is MONTH, verify that *monthIn is a valid month name * 12030000
*******************************************************************/ 12040000
if( strcmp( style,"MONTH" ) == MATCH ) 12050000
func_status = unnameMonth( monthIn ); 12060000
/******************************************************************* 12070000
* If *style is XX, verify that *monthIn is a roman numeral, I - XII* 12080000
*******************************************************************/ 12090000
else if( strcmp( style,"XX" ) == MATCH ) 12100000
func_status = unromanMonth( monthIn ); 12110000
/******************************************************************* 12120000
* Otherwise, verify that *monthIn is valid month number, 1 - 12 * 12130000
*******************************************************************/ 12140000
else 12150000
{ 12160000
remove0prefix( monthIn ); /* strip any leading zero */ 12170000
for( i=0; i<12 && strcmp( monthIn,monthNums[i] ) != MATCH; i++ );12180000
if( i >= 12 ) 12190000
func_status = NOT_OK; 12200000
} 12210000
/******************************************************************* 12220000
* If all checks satisfied, copy *monthIn to *monthOut and return 1 * 12230000
*******************************************************************/ 12240000
if( func_status == OK ) 12250000
strcpy( monthOut, monthIn ); 12260000
/******************************************************************* 12270000
* If a check failed, set *monthOut to null and return 0 * 12280000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1205
*******************************************************************/ 12290000
else 12300000
*monthOut = NULLCHAR; 12310000
12320000
return( func_status ); 12330000
} /* end checkMonth */ 12340000
12350000
12360000
int checkDay /* verify/standardize dayIn */ 12370000
( char *dayOut, /* out: day, validated */ 12380000
char *dayIn /* in: day number */ 12390000
) 12400000
/********************************************************************* 12410000
* Verifies that *dayIn is either 1 or 2 numeric characters. * 12420000
* If criteria satisfied, copies *dayIn to *dayOut and returns 1. * 12430000
* If criteria not satisfied, set *dayOut to null and returns 0. * 12440000
*********************************************************************/ 12450000
{ 12460000
/************************ Local variables *************************/ 12470000
12480000
short int i; /* loop control */ 12490000
short int dayIn_len /* length of *dayIn */ 12500000
= strlen( dayIn ); 12510000
short int func_status = OK; /* function status indicator */ 12520000
12530000
/******************************************************************* 12540000
* Verify that *dayIn is 1 or 2 numeric characters * 12550000
*******************************************************************/ 12560000
for( i=0; ( i<dayIn_len ) && ( isdigit(dayIn[i]) ); i++ ); 12570000
if( i < dayIn_len || dayIn_len < 1 || dayIn_len > 2 ) 12580000
func_status = NOT_OK; 12590000
/******************************************************************* 12600000
* If all checks satisfied, copy *dayIn to *dayOut and return 1 * 12610000
*******************************************************************/ 12620000
if( func_status == OK ) 12630000
strcpy( dayOut, dayIn ); 12640000
/******************************************************************* 12650000
* If a check failed, set *dayOut to null and return 0 * 12660000
*******************************************************************/ 12670000
else 12680000
*dayOut = NULLCHAR; 12690000
12700000
return( func_status ); 12710000
} /* end checkDay */ 12720000
12730000
12740000
void add0prefix 12750000
( char *str3 /* in/out: string to prefix */ 12760000
) 12770000
/********************************************************************* 12780000
* Prefixes *str3 with a leading 0 if it is only 1 byte long. * 12790000
*********************************************************************/ 12800000
{ 12810000
/************************ Local variables *************************/ 12820000
12830000
if( strlen( str3 ) == 1 ) 12840000
{ 12850000
str3[1] = str3[0]; /* Right-shift *str3 1 byte */ 12860000
str3[0] = *char0; /* Prefix it with "0" */ 12870000
str3[2] = NULLCHAR; /* And terminate it */ 12880000
} 12890000
12900000
} /* end add0prefix */ 12910000
12920000
12930000
void remove0prefix /* strips leading zeroes */ 12940000
( char *string /* in/out: string to strip */ 12950000
) 12960000
/********************************************************************* 12970000
* Strips the leading zero from *string, if it has one. * 12980000
*********************************************************************/ 12990000
{ 13000000
if( strncmp( string,"0",1 ) == MATCH ) 13010000
{ 13020000
string[0] = string[1]; /* Left-shift *string */ 13030000
string[1] = NULLCHAR; /* And terminate it */ 13040000
} 13050000
13060000
} /* end remove0prefix */ 13070000
13080000
13090000
void addCentury /* adds century to yearIn */ 13100000
1206 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
( char *yearIn /* in/out: year */ 13110000
) 13120000
/********************************************************************* 13130000
* Prefixes *yearIn with the current century (according to the system * 13140000
* date) if *yearIn is 2 bytes long. * 13150000
*********************************************************************/ 13160000
{ 13170000
/************************ Local variables *************************/ 13180000
13190000
time_t t; /* receives calendar time */ 13200000
struct tm *timeptr; /* recieves local time */ 13210000
char centyear[4]; /* receives current century */ 13220000
13230000
13240000
/******************************************************************* 13250000
* If *yearIn is 2 bytes long, prefix it with the current century * 13260000
*******************************************************************/ 13270000
if( strlen( yearIn ) == 2 ) 13280000
{ 13290000
t = time(NULL); /* Get calendar time from sys */ 13300000
timeptr = localtime(&t); /* Convert to local time */ 13310000
strftime( centyear, /* Format current century year*/ 13320000
sizeof(centyear)-1, /* ..sized for receiving field*/ 13330000
"%Y", /* ..as century year */ 13340000
timeptr ); /* ..from current local time */ 13350000
13360000
/* Prefix *yearIn with century*/ 13370000
yearIn[3] = yearIn[1]; /* ..Right-shift *yearIn */ 13380000
yearIn[2] = yearIn[0]; /* ..by 2 bytes */ 13390000
yearIn[1] = centyear[1]; /* ..Place the century portion*/ 13400000
yearIn[0] = centyear[0]; /* ..in bytes 1-2 */ 13410000
yearIn[4] = NULLCHAR; /* ..Terminate the string */ 13420000
} 13430000
13440000
} /* end addCentury */ 13450000
13460000
13470000
void removeCentury /* strip century from yearIn */ 13480000
( char *yearIn /* in/out: year */ 13490000
) 13500000
/********************************************************************* 13510000
* Strips the century portion from *yearIn if it consists of 4 bytes. * 13520000
*********************************************************************/ 13530000
{ 13540000
/******************************************************************* 13550000
* If *yearIn is 4 bytes long, strip off the century portion * 13560000
*******************************************************************/ 13570000
if( strlen( yearIn ) == 4 ) 13580000
{ 13590000
yearIn[0] = yearIn[2]; /* Shift non-century portion */ 13600000
yearIn[1] = yearIn[3]; /* of *yearIn to 1st 2 bytes */ 13610000
yearIn[2] = NULLCHAR; /* and terminate string */ 13620000
} 13630000
} /* end removeCentury */ 13640000
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSN8DUCT
Converts a given time from one to another of these 8 formats.
/********************************************************************* 00010000
* Module name = DSN8DUCT (DB2 sample program) * 00020000
* * 00030000
* DESCRIPTIVE NAME = General time reformatter (UDF) * 00040000
* * 00050000
* LICENSED MATERIALS - PROPERTY OF IBM * 00060000
* 5675-DB2 * 00109990
* (C) COPYRIGHT 2000 IBM CORP. ALL RIGHTS RESERVED. * 00149980
* * 00190000
* STATUS = VERSION 7 * 00200000
* * 00210000
* Function: Converts a given time from one to another of these 8 * 00220000
* formats: * 00230000
* * 00240000
* H:MM AM/PM HH:MM AM/PM HH:MM:SS AM/PM HH:MM:SS * 00250000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1207
* H.MM HH.MM H.MM.SS HH.MM.SS * 00260000
* * 00270000
* where: * 00280000
* * 00290000
* H: Suppress leading zero if the hour is less than 10 * 00300000
* HH: Retain leading zero if the hour is less than 10 * 00310000
* M: Suppress leading zero if the minute is less than 10 * 00320000
* MM: Retain leading zero if the minute is less than 10 * 00330000
* AM/PM: Return time in 12-hour clock format, else 24-hour * 00340000
* * 00350000
* Example invocation: * 00360000
* EXEC SQL SET :then = ALTTIME( "01:34:59 PM", * 00370000
* "HH:MM:SS AM/PM", * 00380000
* "H.MM" ); * 00390000
* ==> then = "13.34" * 00400000
* * 00410000
* Notes: * 00420000
* Dependencies: Requires IBM C/C++ for OS/390 V1R3 or higher * 00430000
* * 00440000
* Restrictions: * 00450000
* * 00460000
* Module type: C program * 00470000
* Processor: IBM C/C++ for OS/390 V1R3 or higher * 00480000
* Module size: See linkedit output * 00490000
* Attributes: Re-entrant and re-usable * 00500000
* * 00510000
* Entry Point: DSN8DUCT * 00520000
* Purpose: See Function * 00530000
* Linkage: DB2SQL * 00540000
* Invoked via SQL UDF call * 00550000
* * 00560000
* Input: Parameters explicitly passed to this function: * 00570000
* - *timeIn : pointer to a char[12], null-termi- * 00580000
* nated string having a time in the * 00590000
* format indicated by *formatIn. * 00600000
* - *formatIn : pointer to a char[15], null-termi- * 00610000
* nated string having the format of * 00620000
* time found in *timeIn (see "Func- * 00630000
* tion", above, for valid formats). * 00640000
* - *formatOut : pointer to a char[15], null-termi- * 00650000
* nated string having the format to * 00660000
* which the time found in *timeIn is * 00670000
* to be converted. See "Function", * 00680000
* above, for valid formats. * 00690000
* - *niTimeIn : pointer to a short integer having * 00700000
* the null indicator variable for * 00710000
* *timeIn. * 00720000
* - *niFormatIn : pointer to a short integer having * 00730000
* the null indicator variable for * 00740000
* *formatIn. * 00750000
* - *niFormatOut : pointer to a short integer having * 00760000
* the null indicator variable for * 00770000
* *formatOut. * 00780000
* - *fnName : pointer to a char[138], null-termi- * 00790000
* nated string having the UDF family * 00800000
* name of this function. * 00810000
* - *specificName: pointer to a char[129], null-termi- * 00820000
* nated string having the UDF specific * 00830000
* name of this function. * 00840000
* * 00850000
* * 00860000
* Output: Parameters explicitly passed by this function: * 00870000
* - *timeOut : pointer to a char[15], null-termi- * 00880000
* nated string to receive the refor- * 00890000
* matted time. * 00900000
* - *niTimeOut : pointer to a short integer to re- * 00910000
* ceive the null indicator variable * 00920000
* for *timeOut. * 00930000
* - *sqlstate : pointer to a char[06], null-termi- * 00940000
* nated string to receive the SQLSTATE.* 00950000
* - *message : pointer to a char[70], null-termi- * 00960000
* nated string to receive a diagnostic * 00970000
* message if one is generated by this * 00980000
* function. * 00990000
* * 01000000
* Normal Exit: Return Code: SQLSTATE = 00000 * 01010000
* - Message: none * 01020000
* * 01030000
* Error Exit: Return Code: SQLSTATE = 38601 * 01040000
* - Message: DSN8DUCT Error: No input time entered * 01050000
* - Message: DSN8DUCT Error: No input format entered * 01060000
* - Message: DSN8DUCT Error: No output format entered * 01070000
1208 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* * 01080000
* Return Code: SQLSTATE = 38602 * 01090000
* - Message: DSN8DUCT Error: Unknown input format * 01100000
* specified * 01110000
* - Message: DSN8DUCT Error: Inputted time must indi- * 01120000
* cate either AM or PM * 01130000
* - Message: DSN8DUCT Error: Hour not in expected range * 01140000
* of 1-12 * 01150000
* - Message: DSN8DUCT Error: Hour not in expected range * 01160000
* of 0-23 * 01170000
* - Message: DSN8DUCT Error: Minute must be 2 numerics * 01180000
* between 00 and 59 * 01190000
* to input format * 01200000
* - Message: DSN8DUCT Error: Second must be 2 numerics * 01210000
* between 00 and 59 * 01220000
* to input format * 01230000
* * 01240000
* Return Code: SQLSTATE = 38603 * 01250000
* - Message: DSN8DUCT Error: Unknown output format * 01260000
* specified * 01270000
* * 01280000
* External References: * 01290000
* - Routines/Services: None * 01300000
* - Data areas : None * 01310000
* - Control blocks : None * 01320000
* * 01330000
* * 01340000
* Pseudocode: * 01350000
* DSN8DUCT: * 01360000
* - Issue sqlstate 38601 and a diagnostic message if no input time * 01370000
* was provided. * 01380000
* - Issue sqlstate 38601 and a diagnostic message if no input for- * 01390000
* mat was provided. * 01400000
* - Issue sqlstate 38601 and a diagnostic message if no output * 01410000
* format was provided. * 01420000
* - Call decontime to deconstruct the input time into hour, minute,* 01430000
* and, if either, second and AM/PM indicator, according to the * 01440000
* input format. * 01450000
* - Call recontime to create an output time from the hour, minute, * 01460000
* and, if either, second and AM/PM indicator, according to the * 01470000
* output format. * 01480000
* - If no errors, unset null indicators, and return SQLSTATE 00000 * 01490000
* else set null indicator and return null time out. * 01500000
* End DSN8DUCT * 01510000
* * 01520000
* deconTime * 01530000
* - Parse hour, minute, and, if either, second and AM/PM indicator * 01540000
* from the input time by breaking on delimiters (: and .). * 01550000
* - Use the input format to determine sequence of time components. * 01560000
* - if format invalid, issue SQLSTATE 38602 and a diag. message * 01570000
* - Call checkHour to validate the hour component and to standard- * 01580000
* ize it (if required) from a 12-hour clock to a 24-hour clock. * 01590000
* - if not valid hour, issue SQLSTATE 38602 and a diag. message * 01600000
* - Call checkMinute to validate the minute component * 01610000
* - if not valid minute, issue SQLSTATE 38602 and a diag. msg. * 01620000
* - If applicable, call checkSecond to validate the second comp. * 01630000
* - if not valid second, issue SQLSTATE 38602 and a diag. msg. * 01640000
* - If applicable, call checkAMPMindicator to validate the AM/PM * 01650000
* indicator * 01660000
* - if not valid indicator, issue SQLSTATE 38602 and a diag. msg.* 01670000
* End deconTime * 01680000
* * 01690000
* reconTime * 01700000
* - Use the output format to edit the time components * 01710000
* - call set12HrClock to convert the hours component from 24- * 01720000
* hour clock format, as appropriate * 01730000
* - call remove0prefix to strip the leading 0 from the hour com- * 01740000
* ponent, if appropriate * 01750000
* - if output format is invalid, issue SQLSTATE 38603 and a * 01760000
* diagnostic message * 01770000
* - Call buildTime to create the output time from the edited time * 01780000
* components * 01790000
* End reconTime * 01800000
* * 01810000
* buildTime * 01820000
* - Generate the time out by concatenating the time componentents * 01830000
* (hour, minute, and, optionally, second and/or AM/PM indicator) * 01840000
* with intervening delimiters (: or .). * 01850000
* End buildTime * 01860000
* * 01870000
* checkHour * 01880000
* - Verify that the hour component of the input time is: * 01890000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1209
* - in the range 01 - 12 if the input format carries an AM/PM * 01900000
* indicator * 01910000
* - call set24HrClock to standardize the hour to a 24-hour * 01920000
* clock format. * 01930000
* - in the range 00 - 23 if the input format does not carry an * 01940000
* AM/PM indicator * 01950000
* - If not valid, set error flag and return null value for hour * 01960000
* End checkHour * 01970000
* * 01980000
* checkMinute * 01990000
* - Verify the minute component is 2 digits ranging from 00 - 59. * 02000000
* - If not valid, set error flag and return null value for minute * 02010000
* End checkMinute * 02020000
* * 02030000
* checkSecond * 02040000
* - Verify the second component is 2 digits ranging from 00 - 59. * 02050000
* - If not valid, set error flag and return null value for second * 02060000
* End checkSecond * 02070000
* * 02080000
* checkAMPMindicator * 02090000
* - Verify the AM/PM indicator is either "AM" or "PM" * 02100000
* - If not valid, set error flag and return null value for * 02110000
* AM/PM indicator * 02120000
* End checkAMPMindicator * 02130000
* * 02140000
* set12HrClock * 02150000
* - Convert a 24-hour clock hour to a 12-hour clock hour * 02160000
* End set12HrClock * 02170000
* * 02180000
* set24HrClock * 02190000
* - Convert a 12-hour clock hour to a 24-hour clock hour * 02200000
* End set24HrClock * 02210000
* * 02220000
* add0prefix * 02230000
* - prepend an hour with a leading 0 if it is less than 10 * 02240000
* End add0prefix * 02250000
* * 02260000
* remove0prefix * 02270000
* - strip leading zero from an hour if it is less than 10 * 02280000
* End remove0prefix * 02290000
* * 02300000
* * 02310000
*********************************************************************/ 02320000
02321990
#pragma linkage(DSN8DUCT,fetchable) 02323980
02325970
/********************** C library definitions ***********************/ 02330000
#include <stdio.h> 02340000
#include <string.h> 02350000
#include <time.h> 02360000
#include <ctype.h> 02370000
02380000
/***************************** Equates ******************************/ 02390000
#define NULLCHAR '\0' /* Null character */ 02400000
#define MATCH 0 /* Comparison status: Equal */ 02410000
#define NOT_OK 1 /* Run status indicator: Error*/ 02420000
#define OK 0 /* Run status indicator: Good */ 02430000
02440000
/************************ Global constants **************************/ 02450000
char *clock12[24] /* map of 12-hour clock */ 02460000
= { "12", "01", "02", "03", "04", "05", 02470000
"06", "07", "08", "09", "10", "11" }; 02480000
02490000
char *clock24[24] /* map of 24-hour clock */ 02500000
= { "00", "01", "02", "03", "04", "05", 02510000
"06", "07", "08", "09", "10", "11", 02520000
"12", "13", "14", "15", "16", "17", 02530000
"18", "19", "20", "21", "22", "23" }; 02540000
02550000
char *char0 = "0"; /* string with character "0" */ 02560000
02570000
02580000
/*********************** DSN8DUCT functions *************************/ 02590000
02600000
void DSN8DUCT /* main routine */ 02610000
( char *timeIn, /* in: time to be converted */ 02620000
char *formatIn, /* in: format of timeIn */ 02630000
char *formatOut, /* in: format for timeOut */ 02640000
char *timeOut, /* out: reformatted time */ 02650000
short int *nullTimeIn, /* in: indic var for timeIn */ 02660000
short int *nullFormatIn, /* in: indic var for formatIn */ 02670000
short int *nullFormatOut, /* in: indic var, formatOut */ 02680000
1210 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
short int *nullTimeOut, /* out: indic var for timeOut */ 02690000
char *sqlstate, /* out: SQLSTATE */ 02700000
char *fnName, /* in: family name of function*/ 02710000
char *specificName, /* in: specific name of func */ 02720000
char *message /* out: diagnostic message */ 02730000
); 02740000
02750000
int deconTime /* get hr,min,sec from timeIn */ 02760000
( char *hour, /* out: hour component */ 02770000
char *minute, /* out: minute component */ 02780000
char *second, /* out: second component */ 02790000
char *message, /* out: diagnostic message */ 02800000
char *sqlstate, /* out: SQLSTATE */ 02810000
char *timeIn, /* in: time to deconstruct */ 02820000
char *formatIn /* in: format of timeIn */ 02830000
); 02840000
02850000
int reconTime /* get timeOut from hr,min,sec*/ 02860000
( char *timeOut, /* out: reformatted time */ 02870000
char *message, /* out: diagnostic message */ 02880000
char *sqlstate, /* out: SQLSTATE */ 02890000
char *hour, /* in: hour component */ 02900000
char *minute, /* in: minute component */ 02910000
char *second, /* in: second component */ 02920000
char *formatOut /* in: format for timeOut */ 02930000
); 02940000
02950000
void buildTime /* bld timeOut from hr,min,sec*/ 02960000
( char *timeOut, /* out: reformatted time */ 02970000
char *hour, /* in: hour component */ 02980000
char *minute, /* in: minute component */ 02990000
char *second, /* in: second component */ 03000000
char *delim, /* in: delimiter */ 03010000
char *AMPMind /* in: AM/PM indic. (if any) */ 03020000
); 03030000
03040000
int checkHour /* verify/standardize hourIn */ 03050000
( char *hourOut, /* out: hour (24 hour clock) */ 03060000
char *hourIn, /* in: hour (12- or 24-hr clk)*/ 03070000
char *AMPMind /* in: AM/PM indicator */ 03080000
); 03090000
03100000
int checkMinute /* verify minute from timeIn */ 03110000
( char *minOut, /* out: minute, validated */ 03120000
char *minIn /* in: minute, unvalidated */ 03130000
); 03140000
03150000
int checkSecond /* verify second from timeIn */ 03160000
( char *secOut, /* out: second, validated */ 03170000
char *secIn /* in: second, unvalidated */ 03180000
); 03190000
03200000
int checkAMPMindicator /* verify AM/PM ind. of timeIn*/ 03210000
( char *indOut, /* out: AM/PM indic, validated*/ 03220000
char *indIn /* in: AM/PM ind, unvalidated */ 03230000
); 03240000
03250000
int set12HrClock /* hour to 12-hr clock format */ 03260000
( char *hour, /* in/out: hour */ 03270000
char *AMPMind /* out: AM/PM indicator */ 03280000
); 03290000
03300000
int set24HrClock /* hour to 24-hr clock format */ 03310000
( char *hour, /* in/out: hour */ 03320000
char *AMPMind /* in: AM/PM indicator */ 03330000
); 03340000
03350000
void add0Pref /* add leading zero to string */ 03360000
( char *str3 /* in/out: string to prefix */ 03370000
); 03380000
03390000
void remove0prefix /* strip leading zeroes */ 03400000
( char *string /* in/out: character string */ 03410000
); 03420000
03430000
/********************************************************************/ 03440000
/*************************** main routine ***************************/ 03450000
/********************************************************************/ 03460000
void DSN8DUCT 03470000
( char *timeIn, /* in: time to be converted */ 03480000
char *formatIn, /* in: format of timeIn */ 03490000
char *formatOut, /* in: format for timeOut */ 03500000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1211
char *timeOut, /* out: reformatted time */ 03510000
short int *nullTimeIn, /* in: indic var for timeIn */ 03520000
short int *nullFormatIn, /* in: indic var for formatIn */ 03530000
short int *nullFormatOut, /* in: indic var, formatOut */ 03540000
short int *nullTimeOut, /* out: indic var for timeOut */ 03550000
char *sqlstate, /* out: SQLSTATE */ 03560000
char *fnName, /* in: family name of function*/ 03570000
char *specificName, /* in: specific name of func */ 03580000
char *message /* out: diagnostic message */ 03590000
) 03600000
/********************************************************************* 03610000
* * 03620000
* Assumptions: * 03630000
* - *timeIn points to a char[12], null-terminated string * 03640000
* - *formatIn, points to a char[15], null-terminated string * 03650000
* - *formatOut points to a char[15], null-terminated string * 03660000
* - *timeOut points to a char[12], null-terminated string * 03670000
* - *nullTimeIn points to a short integer * 03680000
* - *nullFormatIn points to a short integer * 03690000
* - *nullFormatOut points to a short integer * 03700000
* - *nullTimeOut points to a short integer * 03710000
* - *sqlstate points to a char[06], null-terminated string * 03720000
* - *fnName points to a char[138], null-terminated string * 03735990
* - *specificName points to a char[129], null-terminated string * 03741980
* - *message points to a char[70], null-terminated string * 03750000
*********************************************************************/ 03760000
{ 03770000
/************************ Local variables *************************/ 03780000
short int i; /* loop control */ 03790000
char hour[3]; /* gets hour from timeIn */ 03800000
char minute[3]; /* gets minute from timeIn */ 03810000
char second[3]; /* gets second from timeIn */ 03820000
03830000
short int status = OK; /* DSN8DUCT run status */ 03840000
03850000
03860000
/******************************************************************* 03870000
* Verify that an input time, its current format, and its new format* 03880000
* have been passed in. * 03890000
*******************************************************************/ 03900000
if( *nullTimeIn || ( strlen( timeIn ) == 0 ) ) 03910000
{ 03920000
status = NOT_OK; 03930000
strcpy( message, 03940000
"DSN8DUCT Error: No input time entered" ); 03950000
strcpy( sqlstate, "38601" ); 03960000
} 03970000
else if( *nullFormatIn || ( strlen( formatIn ) == 0 ) ) 03980000
{ 03990000
status = NOT_OK; 04000000
strcpy( message, 04010000
"DSN8DUCT Error: No input format entered" ); 04020000
strcpy( sqlstate, "38601" ); 04030000
} 04040000
else if( *nullFormatOut || ( strlen( formatOut ) == 0 ) ) 04050000
{ 04060000
status = NOT_OK; 04070000
strcpy( message, 04080000
"DSN8DUCT Error: No output format entered" ); 04090000
strcpy( sqlstate, "38601" ); 04100000
} 04110000
04120000
/******************************************************************* 04130000
* Use formatIn to deconstruct timeIn into hour and minute and, if * 04140000
* applicable, second. * 04150000
*******************************************************************/ 04160000
if( status == OK ) 04170000
status = deconTime( hour, minute, second, message, sqlstate, 04180000
timeIn, formatIn ); 04190000
04200000
/******************************************************************* 04210000
* Use formatOut to reconstruct timeOut from ours and minute and, * 04220000
* if applicable, second. * 04230000
*******************************************************************/ 04240000
if( status == OK ) 04250000
status = reconTime( timeOut, message, sqlstate, 04260000
hour, minute, second, formatOut ); 04270000
04280000
/******************************************************************* 04290000
* If conversion was successful, clear the message buffer and sql- * 04300000
* state, and unset the SQL null indicator for timeOut. * 04310000
*******************************************************************/ 04320000
1212 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
if( status == OK ) 04330000
{ 04340000
*nullTimeOut = 0; 04350000
message[0] = NULLCHAR; 04360000
strcpy( sqlstate,"00000" ); 04370000
} 04380000
/******************************************************************* 04390000
* If errors occurred, clear the timeOut buffer and set the SQL null* 04400000
* indicator. A diagnostic message and the SQLSTATE have been set * 04410000
* where the error was detected. * 04420000
*******************************************************************/ 04430000
else 04440000
{ 04450000
timeOut[0] = NULLCHAR; 04460000
*nullTimeOut = -1; 04470000
} 04480000
04490000
return; 04500000
04510000
} /* end DSN8DUCT */ 04520000
04530000
04540000
/********************************************************************/ 04550000
/**************************** functions *****************************/ 04560000
/********************************************************************/ 04570000
int deconTime 04580000
( char *hour, /* out: hour component */ 04590000
char *minute, /* out: minute component */ 04600000
char *second, /* out: second component */ 04610000
char *message, /* out: diagnostic message */ 04620000
char *sqlstate, /* out: SQLSTATE */ 04630000
char *timeIn, /* in: time to deconstruct */ 04640000
char *formatIn /* in: format of timeIn */ 04650000
) 04660000
/********************************************************************* 04670000
* Deconstructs *timeIn into *hour and *minute and, if applicable, * 04680000
* *second. The deconstruction is done according to the value in * 04690000
* formatIn. Returns OK if deconstruction succeeds, otherwise places * 04700000
* diagnostic text in *message and returns NOT_OK. * 04710000
*********************************************************************/ 04720000
{ 04730000
char AMPMind[3]; /* AM/PM indicator */ 04740000
04750000
char workTimeIn[12]; /* work copy of timeIn */ 04760000
char *token; /* string ptr for token parser*/ 04770000
char tok1[3]; /* holds 1st time component */ 04780000
char tok2[3]; /* holds 2nd time component */ 04790000
char tok3[3]; /* holds 3rd time component */ 04800000
char tok4[3]; /* holds 4th time component */ 04810000
04820000
short int func_status = OK; /* function status indicator */ 04830000
short int fmtStatus = OK; /* indicates if format is OK */ 04840000
short int hrStatus = OK; /* indicates if hour is OK */ 04850000
short int minStatus = OK; /* indicates if minute is OK */ 04860000
short int secStatus = OK; /* indicates if second is OK */ 04870000
short int indStatus = OK; /* indicates if AMPMind is OK */ 04880000
04890000
/******************************************************************* 04900000
* Use C strtok function to parse the hour and minute from timeIn * 04910000
*******************************************************************/ 04920000
strcpy( workTimeIn,timeIn ); 04930000
token = strtok( workTimeIn,".: " ); 04940000
strcpy( tok1,token ); 04950000
token = strtok( NULL,".: " ); 04960000
strcpy( tok2,token ); 04970000
04980000
/******************************************************************* 04990000
* Parse second, if any, and AM/PM indicator, if any, from timeIn * 05000000
*******************************************************************/ 05010000
token = strtok( NULL,".: " ); 05020000
strcpy( tok3,token ); 05030000
token = strtok( NULL," " ); 05040000
strcpy( tok4,token ); 05050000
05060000
/******************************************************************* 05070000
* Use formatIn to check and set hour, minute, etc. * 05080000
*******************************************************************/ 05090000
if( ( strcmp( formatIn,"H:MM AM/PM" ) == MATCH ) 05100000
|| ( strcmp( formatIn,"HH:MM AM/PM" ) == MATCH ) ) 05110000
{ 05120000
indStatus = checkAMPMindicator( AMPMind,tok3 ); 05130000
hrStatus = checkHour( hour,tok1,AMPMind ); 05140000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1213
minStatus = checkMinute( minute,tok2 ); 05150000
strcpy( second,"00" ); 05160000
} 05170000
else if( strcmp( formatIn,"HH:MM:SS AM/PM" ) == MATCH ) 05180000
{ 05190000
indStatus = checkAMPMindicator( AMPMind,tok4 ); 05200000
hrStatus = checkHour( hour,tok1,AMPMind ); 05210000
minStatus = checkMinute( minute,tok2 ); 05220000
secStatus = checkSecond( second,tok3 ); 05230000
} 05240000
else if( ( strcmp( formatIn,"HH:MM:SS" ) == MATCH ) 05250000
|| ( strcmp( formatIn,"H.MM.SS" ) == MATCH ) 05260000
|| ( strcmp( formatIn,"HH.MM.SS" ) == MATCH ) ) 05270000
{ 05280000
hrStatus = checkHour( hour,tok1,"" ); 05290000
minStatus = checkMinute( minute,tok2 ); 05300000
secStatus = checkSecond( second,tok3 ); 05310000
} 05320000
else if( ( strcmp( formatIn,"H.MM" ) == MATCH ) 05330000
|| ( strcmp( formatIn,"HH.MM" ) == MATCH ) ) 05340000
{ 05350000
hrStatus = checkHour( hour,tok1,"" ); 05360000
minStatus = checkMinute( minute,tok2 ); 05370000
strcpy( second,"00" ); 05380000
} 05390000
else 05400000
fmtStatus = NOT_OK; 05410000
05420000
/******************************************************************* 05430000
* set up error handling * 05440000
*******************************************************************/ 05450000
func_status = NOT_OK; 05460000
strcpy( message,"DSN8DUCT Error: " ); 05470000
strcpy( sqlstate, "38602" ); 05480000
05490000
/******************************************************************* 05500000
* if error detected, issue diagnostic message and return NOT_OK * 05510000
*******************************************************************/ 05520000
if( fmtStatus != OK ) 05530000
strcat( message,"Unknown input format specified" ); 05540000
05550000
else if( indStatus != OK ) 05560000
strcat( message,"Inputted time must indicate either AM or PM" ); 05570000
05580000
else if( hrStatus != OK ) 05590000
if( strcmp( AMPMind,"AM" ) == MATCH 05600000
|| strcmp( AMPMind,"PM" ) == MATCH ) 05610000
strcat( message,"Hour not in expected range of 1-12" ); 05620000
else 05630000
strcat( message,"Hour not in expected range of 0-23" ); 05640000
05650000
else if( minStatus != OK ) 05660000
strcat( message,"minute must be 2 numerics between 00 and 59" ); 05670000
05680000
else if( secStatus != OK ) 05690000
strcat( message,"second must be 2 numerics between 00 and 59" ); 05700000
05710000
/******************************************************************* 05720000
* if no error detected, clear message and sqlstate and return OK * 05730000
*******************************************************************/ 05740000
else 05750000
{ 05760000
*message = NULLCHAR; 05770000
func_status = OK; 05780000
strcpy( sqlstate, "00000" ); 05790000
} 05800000
05810000
return( func_status ); 05820000
05830000
} /* end deconTime */ 05840000
05850000
05860000
int reconTime 05870000
( char *timeOut, /* out: reformatted time */ 05880000
char *message, /* out: diagnostic message */ 05890000
char *sqlstate, /* out: SQLSTATE */ 05900000
char *hour, /* in: hour component */ 05910000
char *minute, /* in: minute component */ 05920000
char *second, /* in: second component */ 05930000
char *formatOut /* in: format for timeOut */ 05940000
) 05950000
/********************************************************************* 05960000
1214 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* Reconstructs *timeOut from *hour and *minute and, if applicable, * 05970000
* *second. The reconstruction is done according to the value in * 05980000
* formatOut. Returns OK if reconstruction succeeds, otherwise * 05990000
* places diagnostic text in *message and returns NOT_OK. * 06000000
*********************************************************************/ 06010000
{ 06020000
short int func_status = OK; /* function status indicator */ 06030000
char AMPMind[3]; /* AM/PM indicator */ 06040000
06050000
06060000
/******************************************************************* 06070000
* Use formatOut to reformat time from hour, minute, second * 06080000
*******************************************************************/ 06090000
if( strcmp( formatOut,"H:MM AM/PM" ) == MATCH ) 06100000
{ 06110000
set12HrClock( hour,AMPMind ); 06120000
remove0prefix( hour ); 06130000
buildTime( timeOut, hour, minute, "", ":", AMPMind ); 06140000
} 06150000
else if( strcmp( formatOut,"HH:MM AM/PM" ) == MATCH ) 06160000
{ 06170000
set12HrClock( hour,AMPMind ); 06180000
buildTime( timeOut, hour, minute, "", ":", AMPMind ); 06190000
} 06200000
else if( strcmp( formatOut,"HH:MM:SS AM/PM" ) == MATCH ) 06210000
{ 06220000
set12HrClock( hour,AMPMind ); 06230000
buildTime( timeOut, hour, minute, second, ":", AMPMind ); 06240000
} 06250000
else if( strcmp( formatOut,"HH:MM:SS" ) == MATCH ) 06260000
{ 06270000
buildTime( timeOut, hour, minute, second, ":", "" ); 06280000
} 06290000
else if( strcmp( formatOut,"H.MM.SS" ) == MATCH ) 06300000
{ 06310000
remove0prefix( hour ); 06320000
buildTime( timeOut, hour, minute, second, ".", "" ); 06330000
} 06340000
else if( strcmp( formatOut,"HH.MM.SS" ) == MATCH ) 06350000
{ 06360000
buildTime( timeOut, hour, minute, second, ".", "" ); 06370000
} 06380000
else if( strcmp( formatOut,"H.MM" ) == MATCH ) 06390000
{ 06400000
remove0prefix( hour ); 06410000
buildTime( timeOut, hour, minute, "", ".", "" ); 06420000
} 06430000
else if( strcmp( formatOut,"HH.MM" ) == MATCH ) 06440000
{ 06450000
buildTime( timeOut, hour, minute, "", ".", "" ); 06460000
} 06470000
else 06480000
{ 06490000
func_status = NOT_OK; 06500000
strcpy( message,"DSN8DUCT Error: " ); 06510000
strcat( message,"Unknown output format specified" ); 06520000
strcpy( sqlstate, "38603" ); 06530000
} 06540000
06550000
return( func_status ); 06560000
06570000
} /* end reconTime */ 06580000
06590000
06600000
void buildTime 06610000
( char *timeOut, /* out: reformatted time */ 06620000
char *hour, /* in: hour component */ 06630000
char *minute, /* in: minute component */ 06640000
char *second, /* in: second component */ 06650000
char *delim, /* in: delimiter */ 06660000
char *AMPMind /* in: AM/PM indic. (if any) */ 06670000
) 06680000
/********************************************************************* 06690000
* Builds *timeOut from *hour, *minute, and (if specified) *second, * 06700000
* separated by the value in *delim and, if specified, suffixed by the* 06710000
* value in *AMPMind. * 06720000
*********************************************************************/ 06730000
{ 06740000
/******************************************************************* 06750000
* Build timeOut from incoming time components * 06760000
*******************************************************************/ 06770000
strcpy( timeOut,hour ); /* Start with hour ... */ 06780000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1215
strcat( timeOut,delim ); /* append the delimiter */ 06790000
strcat( timeOut,minute ); /* append minute */ 06800000
if( strlen(second) > 0 ) /* and, if second specified, */ 06810000
{ 06820000
strcat( timeOut,delim ); /* ..append the delimiter */ 06830000
strcat( timeOut,second ); /* ..append second */ 06840000
} 06850000
if( strlen(AMPMind) > 0 ) /* and, if AM/PM ind. spec'd */ 06860000
{ 06870000
strcat( timeOut," " ); /* ..append separator blank */ 06880000
strcat( timeOut,AMPMind ); /* ..append AM/PM indicator */ 06890000
} 06900000
06910000
} /* end buildTime */ 06920000
06930000
06940000
int checkHour 06950000
( char *hourOut, /* out: hour (24-hour clock) */ 06960000
char *hourIn, /* in: hour (12- or 24-hr clk)*/ 06970000
char *AMPMind /* in: AM/PM indicator */ 06980000
) 06990000
/********************************************************************* 07000000
* Verifies that *hourIn meets one of these criteria: * 07010000
* - if *AMPMind is "AM" or "PM", *hourIn ranges from "01" to "12" * 07020000
* - otherwise, *hourIn ranges from "0" to "23" * 07030000
* * 07040000
* If the appropriate criterion is met, *hourOut is assigned as * 07050000
* follows: * 07060000
* - if *AMPMind is "AM" or "PM", *hourOut is assigned the 24-hour * 07070000
* clock equivalent of *hourIn. * 07080000
* - otherwise, *hourIn is copied to *hourOut * 07090000
* and checkHour returns OK. * 07100000
* * 07110000
* If the appropriate critierion is not met, *hourOut is assigned * 07120000
* NULLCHAR, and checkHour returns NOT_OK. * 07130000
*********************************************************************/ 07140000
{ 07150000
short int i; /* loop control */ 07160000
short int func_status = OK; /* function status indicator */ 07170000
07180000
/******************************************************************* 07190000
* add leading 0, if needed, to *hourIn * 07200000
*******************************************************************/ 07210000
add0Pref( hourIn ); 07220000
07230000
/******************************************************************* 07240000
* if AMPMind is AM or PM, convert *hourIn to 24-clock format * 07250000
*******************************************************************/ 07260000
if( strcmp( AMPMind,"AM" ) == MATCH 07270000
|| strcmp( AMPMind,"PM" ) == MATCH ) 07280000
func_status = set24HrClock( hourIn,AMPMind ); 07290000
07300000
/******************************************************************* 07310000
* if AMPMind not "AM" or "PM", verify hourIn ranges from 00 to 23 * 07320000
*******************************************************************/ 07330000
else 07340000
{ 07350000
for( i=0; i<24 && strcmp( hourIn,clock24[i] ) != MATCH; i++ ); 07360000
if( i >= 24 ) /* if hourIn < 00 & > 23 */ 07370000
func_status = NOT_OK; /* ..set error flag */ 07380000
} 07390000
07400000
/******************************************************************* 07410000
* if *hourIn is valid, copy it to *hourOut else set *hourOut to * 07420000
* NULLCHAR * 07430000
*******************************************************************/ 07440000
if( func_status == OK ) 07450000
strcpy( hourOut,hourIn ); 07460000
else 07470000
hourOut[0] = NULLCHAR; 07480000
07490000
return( func_status ); 07500000
} /* end checkHour */ 07510000
07520000
07530000
int checkMinute 07540000
( char *minOut, /* out: minute, validated */ 07550000
char *minIn /* in: minute, unvalidated */ 07560000
) 07570000
/********************************************************************* 07580000
* Verifies that *minIn is 2 bytes of numeric characters between "00" * 07590000
* and "59". * 07600000
1216 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* * 07610000
* If so, minIn is copied to minOut and checkMinute returns OK. * 07620000
* If not, NULLCHAR is copied to minOut and checkMinute returns * 07630000
* NOT_OK. * 07640000
*********************************************************************/ 07650000
{ 07660000
short int i; /* loop control */ 07670000
short int func_status = OK; /* function status indicator */ 07680000
07690000
/******************************************************************* 07700000
* verify that *minIn is 2 numeric characters between "00" and "59" * 07710000
*******************************************************************/ 07720000
if( strlen( minIn ) != 2 ) 07730000
func_status = NOT_OK; 07740000
else if( isdigit(minIn[0]) == MATCH || isdigit(minIn[1]) == MATCH ) 07750000
func_status = NOT_OK; 07760000
else if( strcmp( minIn,"00" ) < 0 || strcmp( minIn,"59" ) > 0 ) 07770000
func_status = NOT_OK; 07780000
07790000
/******************************************************************* 07800000
* if minIn is valid, assign it to minOut * 07810000
*******************************************************************/ 07820000
if( func_status == OK ) 07830000
strcpy( minOut,minIn ); 07840000
else 07850000
minOut[0] = NULLCHAR; 07860000
07870000
return( func_status ); 07880000
} /* end checkMinute */ 07890000
07900000
07910000
int checkSecond 07920000
( char *secOut, /* out: second, validated */ 07930000
char *secIn /* in: second, unvalidated */ 07940000
) 07950000
/********************************************************************* 07960000
* Verifies that *secIn is 2 bytes of numeric characters between "00" * 07970000
* and "59". * 07980000
* * 07990000
* If so, secIn is copied to secOut and checkSecond returns OK. * 08000000
* If not, NULLCHAR is copied to secOut and checkSecond returns * 08010000
* NOT_OK. * 08020000
*********************************************************************/ 08030000
{ 08040000
short int i; /* loop control */ 08050000
short int func_status = OK; /* function status indicator */ 08060000
08070000
/******************************************************************* 08080000
* verify that *secIn is 2 numeric characters between "00" and "59" * 08090000
*******************************************************************/ 08100000
if( strlen( secIn ) != 2 ) 08110000
func_status = NOT_OK; 08120000
else if( isdigit(secIn[0]) == MATCH || isdigit(secIn[1]) == MATCH ) 08130000
func_status = NOT_OK; 08140000
else if( strcmp( secIn,"00" ) < 0 || strcmp( secIn,"59" ) > 0 ) 08150000
func_status = NOT_OK; 08160000
08170000
/******************************************************************* 08180000
* if secIn is valid, assign it to secOut * 08190000
*******************************************************************/ 08200000
if( func_status == OK ) 08210000
strcpy( secOut,secIn ); 08220000
else 08230000
secOut[0] = NULLCHAR; 08240000
08250000
return( func_status ); 08260000
} /* end checkSecond */ 08270000
08280000
08290000
int checkAMPMindicator 08300000
( char *indOut, /* out: AM/PM indic, validated*/ 08310000
char *indIn /* in: AM/PM ind, unvalidated */ 08320000
) 08330000
/********************************************************************* 08340000
* Verifies that *indIn is 2 bytes, containing either "AM" or "PM". * 08350000
* * 08360000
* If so, indIn is copied to indOut and checkAMPMindicator returns * 08370000
* OK. * 08380000
* If not, NULLCHAR is copied to indOut and checkAMPMindicator re- * 08390000
* turns NOT_OK. * 08400000
*********************************************************************/ 08410000
{ 08420000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1217
short int i; /* loop control */ 08430000
short int func_status = OK; /* function status indicator */ 08440000
08450000
/******************************************************************* 08460000
* verify that *indIn is 2 bytes containing either "AM" or "PM" * 08470000
*******************************************************************/ 08480000
if( strlen( indIn ) != 2 ) 08490000
func_status = NOT_OK; 08500000
else if( strcmp(indIn,"AM") != MATCH && strcmp(indIn,"PM") != MATCH )08510000
func_status = NOT_OK; 08520000
08530000
/******************************************************************* 08540000
* if indIn is valid, assign it to indOut * 08550000
*******************************************************************/ 08560000
if( func_status == OK ) 08570000
strcpy( indOut,indIn ); 08580000
else 08590000
indOut[0] = NULLCHAR; 08600000
08610000
return( func_status ); 08620000
} /* end checkAMPMindicator */ 08630000
08640000
08650000
int set12HrClock 08660000
( char *hour, /* in/out: hour */ 08670000
char *AMPMind /* out: AM/PM indicator */ 08680000
) 08690000
/********************************************************************* 08700000
* Changes *hour from 24-hour clock format to 12-hour clock format. * 08710000
* * 08720000
* If the incoming value for *hour is: * 08730000
* - between "00" and "11", *hour is assigned the 12-hour clock * 08740000
* equivalent ("12" - "11"), *AMPMind is assigned "AM", and * 08750000
* set12HrClock returns OK. * 08760000
* - between "12" and "23", *hour is assigned the 12-hour clock * 08770000
* equivalent ("12" - "11"), *AMPMind is assigned "PM", and * 08780000
* set12HrClock returns OK. * 08790000
* - any other value, *hour is unchanged, *AMPMind is assigned * 08800000
* NULLCHAR, and set12HrClock returns NOT_OK. * 08810000
*********************************************************************/ 08820000
{ 08830000
short int i; /* loop control */ 08840000
short int func_status = OK; /* function status indicator */ 08850000
08860000
/******************************************************************* 08870000
* locate *hour in the 24-hour clock map * 08880000
*******************************************************************/ 08890000
for( i=0; i<24 && strcmp( hour,clock24[i] ) != MATCH; i++ ); 08900000
08910000
/******************************************************************* 08920000
* assign *hour its 12-hour clock equivalent * 08930000
*******************************************************************/ 08940000
if( i < 12 ) /* if hour betw/ "00" & "11" */ 08950000
{ 08960000
strcpy( hour,clock12[i] ); /* ..set hour in 12-hour fmt */ 08970000
strcpy( AMPMind,"AM" ); /* ..set AM/PM indic to AM */ 08980000
} 08990000
else if( i < 24 ) /* if hour betw/ "12" & "23" */ 09000000
{ 09010000
strcpy( hour,clock12[i-12] ); /* ..set hour in 12-hour fmt */ 09020000
strcpy( AMPMind,"PM" ); /* ..set AM/PM indic to PM */ 09030000
} 09040000
else /* otherwise .. */ 09050000
{ 09060000
func_status = NOT_OK; /* ..set error flag */ 09070000
AMPMind[0] = NULLCHAR; /* ..null out AM/PM indicator */ 09080000
} 09090000
09100000
return( func_status ); /* return function status */ 09110000
} /* end set12HrClock */ 09120000
09130000
09140000
int set24HrClock 09150000
( char *hour, /* in/out: hour */ 09160000
char *AMPMind /* in: AM/PM indicator */ 09170000
) 09180000
/********************************************************************* 09190000
* Changes *hour from 12-hour clock format to 24-hour clock format. * 09200000
* * 09210000
* If the incoming value for *hour is not between "01" and "12", * 09220000
* then *hour is unchanged and set24HrClock returns NOT_OK. * 09230000
* * 09240000
1218 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* Otherwise: * 09250000
* - if *AMPMind is "AM", then *hour is assigned the 24-hour equiva- * 09260000
* lent of morning hour ("00"-"11") and set24HrClock returns OK. * 09270000
* - else *hour is assigned the 24-hour equivalent of afternoon * 09280000
* hour ("12"-"23") and set24HrClock returns OK. * 09290000
*********************************************************************/ 09300000
{ 09310000
short int i; /* loop control */ 09320000
short int func_status = OK; /* function status indicator */ 09330000
09340000
/******************************************************************* 09350000
* locate *hour in the 12-hour clock map * 09360000
*******************************************************************/ 09370000
for( i=0; i<12 && strcmp( hour,clock12[i] ) != MATCH; i++ ); 09380000
09390000
/******************************************************************* 09400000
* assign *hour its 24-hour clock equivalent * 09410000
*******************************************************************/ 09420000
if( i > 11 ) /* if hour not betw/ 01 & 12 */ 09430000
func_status = NOT_OK; /* ..set error flag */ 09440000
else if(strcmp(AMPMind,"AM")==MATCH)/* else if betw/ 12 AM - 11 AM*/ 09450000
strcpy( hour,clock24[i] ); /* ..set hour in 12-hour fmt */ 09460000
else /* else betw/ 12 PM - 11 PM */ 09470000
strcpy( hour,clock24[i+12] ); /* ..set hour in 12-hour fmt */ 09480000
09490000
return( func_status ); /* return function status */ 09500000
} /* end set24HrClock */ 09510000
09520000
09530000
void add0Pref 09540000
( char *str3 /* in/out: string to prefix */ 09550000
) 09560000
/********************************************************************* 09570000
* Prefixes *str3 with a leading 0 if it is only 1 byte long * 09580000
*********************************************************************/ 09590000
{ 09600000
/******************************************************************* 09610000
* if str3 is just 1 byte long, prefix it with a "0" * 09620000
*******************************************************************/ 09630000
if( strlen( str3 ) == 1 ) 09640000
{ 09650000
str3[1] = str3[0]; /* Right-shift *str3 1 byte */ 09660000
str3[0] = *char0; /* Prefix it with "0" */ 09670000
str3[2] = NULLCHAR; /* And terminate it */ 09680000
} 09690000
} /* end add0Pref */ 09700000
09710000
09720000
void remove0prefix 09730000
( char *string /* in/out: character string */ 09740000
) 09750000
/********************************************************************* 09760000
* Eliminates all leading zeroes from *str3. Leaves a single zero in * 09770000
* the first byte of *str3 if *str3 is all zeroes. * 09780000
*********************************************************************/ 09790000
{ 09800000
short int i = 0; /* Loop control */ 09810000
short int j = 0; /* Loop control */ 09820000
09830000
/******************************************************************* 09840000
* if leading zero in first byte, skip up to first non-zero * 09850000
*******************************************************************/ 09860000
if( string[0] == '0' ) 09870000
for( i=0; string[i] == '0'; i++ ); 09880000
09890000
/******************************************************************* 09900000
* if at end of string, it was all zeroes: put zero in 1st byte * 09910000
*******************************************************************/ 09920000
if( string[i] == '\0' ) 09930000
strcpy( string,"0" ); 09940000
/******************************************************************* 09950000
* otherwise, left-shift non-zero chars and terminate string * 09960000
*******************************************************************/ 09970000
else 09980000
{ 09990000
for( j=0; string[i] != NULLCHAR; j++ ) 10000000
string[j] = string[i++]; 10010000
string[j] = NULLCHAR; 10020000
} 10030000
} /* end remove0prefix */ 10040000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1219
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSN8DUCY
Formats a given numeric amount with a specified currency symbol and, if specified, one of the following
debit/ credit indicators.
/********************************************************************* 00000100
* Module name = DSN8DUCY (DB2 sample program) * 00000200
* * 00000300
* DESCRIPTIVE NAME = General currency formatter (UDF) * 00000400
* * 00000500
* * 00000600
* LICENSED MATERIALS - PROPERTY OF IBM * 00000700
* 5675-DB2 * 00000800
* (C) COPYRIGHT 1998, 2000 IBM CORP. ALL RIGHTS RESERVED. * 00000900
* * 00001000
* STATUS = VERSION 7 * 00001100
* * 00001200
* Function: Formats a given numeric amount with a specified currency * 00001300
* symbol and, if specified, one of the following debit/ * 00001400
* credit indicators. * 00001500
* * 00001600
* +/-: Place a hyphen between the currency symbol and the * 00001700
* amount if the amount is less than 0. * 00001800
* (/): Place a left parenthesis between currency symbol * 00001900
* and the amount and place a right parenthesis to the * 00002000
* right of the amount if the amount is less than 0. * 00002100
* CR/DB: Place CR to the right of the amount if it is less * 00002200
* than 0; otherwise place DB to the right of the * 00002300
* amount. * 00002400
* * 00002500
* Example invocations: * 00002600
* EXEC SQL SET :money = CURRENCY( -123, * 00002700
* "DM" ); * 00002800
* ==> money = DM -123.00 * 00002900
* * 00003000
* * 00003100
* EXEC SQL SET :money = CURRENCY( -123, * 00003200
* "DM", * 00003300
* "(/)" ); * 00003400
* ==> money = DM (123.00) * 00003500
* * 00003600
* Notes: * 00003700
* Dependencies: Requires IBM C/C++ for OS/390 V1R3 or higher * 00003800
* * 00003900
* Restrictions: * 00004000
* * 00004100
* Module type: C program * 00004200
* Processor: IBM C/C++ for OS/390 V1R3 or higher * 00004300
* Module size: See linkedit output * 00004400
* Attributes: Re-entrant and re-usable * 00004500
* * 00004600
* Entry Point: DSN8DUCY * 00004700
* Purpose: See Function * 00004800
* Linkage: DB2SQL * 00004900
* Invoked via SQL UDF call * 00005000
* * 00005100
* Parameters: DSN8DUCY uses the C "main" argument convention of * 00005200
* argv (argument vector) and argc (argument count). * 00005300
* * 00005400
* The location of input and output parameters depends * 00005500
* on whether the CURRENCY UDF is invoked with two * 00005600
* input arguments (amount and currency symbol) or with * 00005700
* three input arguments (amount, currency symbol, and * 00005800
* credit/debit indicator). * 00005900
* * 00006000
* If the CURRENCY UDF is invoked with two arguments * 00006100
* only (an amount and a currency symbol): * 00006200
* - ARGV[0] = (input) pointer to a char[9], null- * 00006300
* terminated string having the name of * 00006400
* this program (DSN8DUCY) * 00006500
* - ARGV[1] = (input) pointer to a double word having * 00006600
* the amount to be formatted as currency. * 00006700
* - ARGV[2] = (input) pointer to a char[3], null- * 00006800
* terminated string having the currency * 00006900
1220 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* symbol. * 00007000
* - ARGV[3] = (output) pointer to a char[20], null- * 00007100
* terminated string to receive the cur- * 00007200
* rency result. * 00007300
* - ARGV[4] = (input) pointer to a short integer * 00007400
* having the null indicator for the input * 00007500
* amount * 00007600
* - ARGV[5] = (input) pointer to a short integer * 00007700
* having the null indicator for the cur- * 00007800
* rency symbol * 00007900
* - ARGV[6] = (output) pointer to a short integer * 00008000
* having the null indicator for the result * 00008100
* - ARGV[7] = (output) pointer to a char[6], null- * 00008200
* terminated string to receive the * 00008300
* SQLSTATE * 00008400
* - ARGV[8] = (input) pointer to a char[138], null- * 00008500
* terminated string having the UDF family * 00008600
* name of the function * 00008700
* - ARGV[9] = (input) pointer to a char[129], null- * 00008800
* terminated string having the UDF * 00008900
* specific name of the function * 00009000
* - ARGV[10] = (output) pointer to a char[70], * 00009100
* null- terminated string to receive any * 00009200
* diagnostic message issued by this * 00009300
* function * 00009400
* * 00009500
* If the CURRENCY UDF is invoked with three arguments * 00009600
* (an amount, a currency symbol, and a credit/debit * 00009700
* indicator): * 00009800
* - ARGV[0] = (input) pointer to a char[9], null- * 00009900
* terminated string having the name of * 00010000
* this program (DSN8DUCY) * 00010100
* - ARGV[1] = (input) pointer to a double word having * 00010200
* the amount to be formatted as currency. * 00010300
* - ARGV[2] = (input) pointer to a char[3], null- * 00010400
* terminated string having the currency * 00010500
* symbol. * 00010600
* - ARGV[3] = (input) pointer to a char[6], null- * 00010700
* terminated string having the credit/ * 00010800
* debit indicator (see under "Function:", * 00010900
* above, for valid credit/debit indicators)* 00011000
* - ARGV[4] = (output) pointer to a char[20], null- * 00011100
* terminated string to receive the cur- * 00011200
* rency result. * 00011300
* - ARGV[5] = (input) pointer to a short integer * 00011400
* having the null indicator for the input * 00011500
* amount * 00011600
* - ARGV[6] = (input) pointer to a short integer * 00011700
* having the null indicator for the cur- * 00011800
* rency symbol * 00011900
* - ARGV[7] = (input) pointer to a short integer * 00012000
* having the null indicator for the * 00012100
* credit/debit indicator * 00012200
* - ARGV[8] = (output) pointer to a short integer * 00012300
* having the null indicator for the result * 00012400
* - ARGV[9] = (output) pointer to a char[6], null- * 00012500
* terminated string to receive the * 00012600
* SQLSTATE * 00012700
* - ARGV[10] = (input) pointer to a char[138], null- * 00012800
* terminated string having the UDF family * 00012900
* name of the function * 00013000
* - ARGV[11] = (input) pointer to a char[129], null- * 00013100
* terminated string having the UDF * 00013200
* specific name of the function * 00013300
* - ARGV[12] = (output) pointer to a char[70], * 00013400
* null- terminated string to receive any * 00013500
* diagnostic message issued by this * 00013600
* function * 00013700
* * 00013800
* Normal Exit: Return Code: SQLSTATE = 00000 * 00013900
* - Message: none * 00014000
* * 00014100
* Error Exit: Return Code: SQLSTATE = 38601 * 00014200
* - Message: DSN8DUCY Error: No amount entered * 00014300
* - Message: DSN8DUCY Error: No currency symbol entered * 00014400
* * 00014500
* Return Code: SQLSTATE = 38602 * 00014600
* - Message: DSN8DUCY Error: Error performing * 00014700
* setlocale() * 00014800
* * 00014900
* External References: * 00015000
* - Routines/Services: None * 00015100
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1221
* - Data areas : None * 00015200
* - Control blocks : None * 00015300
* * 00015400
* * 00015500
* Pseudocode: * 00015600
* DSN8DUCY: * 00015700
* - Walk down the argv list, locating the input and output parms * 00015800
* - Issue sqlstate 38601 and a diagnostic message if no input * 00015900
* amount was provided. * 00016000
* - Issue sqlstate 38601 and a diagnostic message if no currency * 00016100
* symbol was provided. * 00016200
* - Call formatAmount to assemble the currency expression from the * 00016300
* input amount and the currency symbol and, optionally, the * 00016400
* credit/debit indicator. * 00016500
* - If no errors, unset null indicators, and return SQLSTATE 00000 * 00016600
* else set null indicator and return null time out. * 00016700
* End DSN8DUCY * 00016800
* * 00016900
* formatAmount * 00017000
* - If the amount in is less than zero ... * 00017100
* - if a CR/DB indicator of -/+ has been specified, prefix * 00017200
* the currency expression with a hyphen * 00017300
* - else if a CR/DB of (/) has been specified, prefix the curr- * 00017400
* rency expression with a left parenthesis * 00017500
* - Append the currency symbol to the currency expression * 00017600
* - if the currency symbol is just 1 byte, concatentate a blank * 00017700
* - Call the C function setlocale() to initialize the C function * 00017800
* strfmon(). * 00017900
* - if error, issue SQLSTATE 38602 and a diagnostic message * 00018000
* - Call the C function strfmon() to reformat the input amount * 00018100
* with the currency symbol. * 00018200
* - If the amount in is less than zero ... * 00018300
* - if a CR/DB of (/) has been specified, append a right paren- * 00018400
* thesis to the currency expression. * 00018500
* End formatAmount * 00018600
* * 00018700
* * 00018800
*********************************************************************/ 00018900
/********************** C library definitions ***********************/ 00019000
#include <localdef.h> 00019100
#include <monetary.h> 00019200
#include <stdio.h> 00019300
#include <stdlib.h> 00019400
#include <string.h> 00019500
00019600
/***************************** Equates ******************************/ 00019700
#define NULLCHAR '\0' /* Null character */ 00019800
00019900
#define MATCH 0 /* Comparison status: Equal */ 00020000
#define NOT_OK 0 /* Run status indicator: Error*/ 00020100
#define OK 1 /* Run status indicator: Good */ 00020200
00020300
00020400
/*********************** DSN8DUCY functions *************************/ 00020500
int main /* main routine */ 00020600
( int argc, /* standard argument count */ 00020700
char *argv[] /* standard argument vector */ 00020800
); 00020900
00021000
int formatAmount /* format amountIn as currency*/ 00021100
( char *moneyOut, /* out: formatted amountIn */ 00021200
char *message, /* out: diagnostic message */ 00021300
char *sqlstate, /* out: SQLSTATE */ 00021400
double *amountIn, /* in: value to be formatted */ 00021500
char *currSymbol, /* in: currency symbol */ 00021600
char *CRDBInd /* in: credit/debit indicator */ 00021700
); 00021800
00021900
/********************************************************************/ 00022000
/*************************** main routine ***************************/ 00022100
/********************************************************************/ 00022200
int main /* main routine */ 00022300
( int argc, /* standard argument count */ 00022400
char *argv[] /* standard argument vector */ 00022500
) 00022600
/********************************************************************* 00022700
* * 00022800
*********************************************************************/ 00022900
{ 00023000
00023100
/************************ local variables *************************/ 00023200
short int minus1 = -1; /* default null indic setting */ 00023300
1222 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
00023400
/* vars for argument vector */ 00023500
double *amountIn; /* in: value to be formatted */ 00023600
char currSymbol[3]; /* in: currency symbol */ 00023700
char CRDBInd[6]; /* in: credit/debit indicator */ 00023800
char *moneyOut; /* out: formatted amountIn */ 00023900
short int *niAmountIn; /* in: indic var, amountIn */ 00024000
short int *niCurrSymbol; /* in: indic var, currSymbol */ 00024100
short int *niCRDBInd; /* in: indic var, CRDBInd */ 00024200
short int *niMoneyOut; /* out: indic var, moneyOut */ 00024300
char *sqlstate; /* out: SQLSTATE */ 00024400
char fnName[138]; /* in: family name of function*/ 00024500
char specificName[129]; /* in: specific name of func */ 00024600
char *message; /* out: diagnostic message */ 00024700
00024800
short int status = OK; /* DSN8DUCY run status */ 00024900
00025000
00025100
00025200
/******************************************************************* 00025300
* Walk down the argv list, locating the input and output parms * 00025400
*******************************************************************/ 00025500
argc--; /* convert argc to base 0 index*/ 00025600
00025700
message = (char *)argv[argc--]; /* out: point to UDF diag msg */ 00025800
00025900
strcpy( specificName, /* in: save UDF specific name */ 00026000
argv[argc--]); 00026100
00026200
strcpy( fnName,argv[argc--] ); /* in: save UDF function name */ 00026300
00026400
sqlstate = (char *)argv[argc--]; /* out: point to UDF sqlstate */ 00026500
00026600
niMoneyOut /* out: point to null indicator*/ 00026700
= (short int *)argv[argc--]; /* variable for result */ 00026800
00026900
if( argc == 7 ) /* if 3 input parms passed */ 00027000
niCRDBInd /* ..in: point to null indic. */ 00027100
= (short int *)argv[argc--]; /* var for CR/DB indic. */ 00027200
else /* otherwise it wasn't passed */ 00027300
niCRDBInd = &minus1; /* ..so define it as null */ 00027400
00027500
niCurrSymbol /* in: point to null indicator */ 00027600
= (short int *)argv[argc--]; /* var for currency symbol */ 00027700
00027800
niAmountIn /* in: point to null indicator */ 00027900
= (short int *)argv[argc--]; /* var for input amount */ 00028000
00028100
moneyOut = (char *)argv[argc--]; /* out: point to UDF result */ 00028200
00028300
if( argc == 3 ) /* if 3 input parms passed */ 00028400
strcpy( CRDBInd, /* ..in: save object location */ 00028500
argv[argc--] ); /* name */ 00028600
else /* otherwise it wasn't passed */ 00028700
CRDBInd[0] = NULLCHAR; /* ..so define it as null */ 00028800
00028900
strcpy( currSymbol,argv[argc--] ); /* in: save currency symbol */ 00029000
00029100
amountIn = (double *)argv[argc]; /* in: save input amount */ 00029200
00029300
00029400
/******************************************************************* 00029500
* Initialize output parms * 00029600
*******************************************************************/ 00029700
message[0] = NULLCHAR; 00029800
strcpy( sqlstate,"00000" ); 00029900
*niMoneyOut = 0; 00030000
moneyOut[0] = NULLCHAR; 00030100
00030200
/******************************************************************* 00030300
* Verify that an amount and a currency symbol have been passed in * 00030400
*******************************************************************/ 00030500
if( *niAmountIn ) 00030600
{ 00030700
status = NOT_OK; 00030800
strcpy( message, 00030900
"DSN8DUCY Error: No amount entered" ); 00031000
strcpy( sqlstate, "38601" ); 00031100
} 00031200
else if( *niCurrSymbol || ( strlen( currSymbol ) == 0 ) ) 00031300
{ 00031400
status = NOT_OK; 00031500
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1223
strcpy( message, 00031600
"DSN8DUCY Error: No currency symbol entered" ); 00031700
strcpy( sqlstate, "38601" ); 00031800
} 00031900
00032000
/******************************************************************* 00032100
* Format the amount into currency notation * 00032200
*******************************************************************/ 00032300
if( status == OK ) 00032400
status = formatAmount( moneyOut, message, sqlstate, 00032500
amountIn, currSymbol, CRDBInd ); 00032600
00032700
/******************************************************************* 00032800
* If formatting was successful, clear the message buffer and sql- * 00032900
* state, and unset the SQL null indicator for moneyOut. * 00033000
*******************************************************************/ 00033100
if( status == OK ) 00033200
{ 00033300
*niMoneyOut = 0; 00033400
message[0] = NULLCHAR; 00033500
strcpy( sqlstate,"00000" ); 00033600
} 00033700
/******************************************************************* 00033800
* If errors occurred, clear the moneyOut buff and set the SQL null * 00033900
* indicator. A diagnostic message and the SQLSTATE have been set * 00034000
* where the error was detected. * 00034100
*******************************************************************/ 00034200
else 00034300
{ 00034400
moneyOut[0] = NULLCHAR; 00034500
*niMoneyOut = -1; 00034600
} 00034700
00034800
return( 0 ); 00034900
} /* end main */ 00035000
00035100
/********************************************************************/ 00035200
/***************************** functions ****************************/ 00035300
/********************************************************************/ 00035400
int formatAmount /* format amountIn as currency*/ 00035500
( char *moneyOut, /* out: formatted amountIn */ 00035600
char *message, /* out: diagnostic message */ 00035700
char *sqlstate, /* out: SQLSTATE */ 00035800
double *amountIn, /* in: value to be formatted */ 00035900
char *currSymbol, /* in: currency symbol */ 00036000
char *CRDBInd /* in: credit/debit indicator */ 00036100
) 00036200
/********************************************************************* 00036300
* Converts amountIn to a string, including the currency type in * 00036400
* currSymbol and, if specified, the credit/debit indicator in CRDB- * 00036500
* Symbol. The result is placed in moneyOut. * 00036600
* * 00036700
* currSymbol may be any string of characters, up to 2 bytes long. * 00036800
* CRDBInd is used only its value is: * 00036900
* - "+/-", indicating that moneyOut and its prefix from currSymbol * 00037000
* should be prefixed by a hyphen ("-") if amountIn is negative. * 00037100
* - "(/)", indicating that moneyOut should be enclosed, with the * 00037200
* prefix from currSymbol, in parentheses if amountIn is negative. * 00037300
* - "CR/DB", indicating that moneyOut should be prefixed with DB * 00037400
* if amountIn is negative, otherwise with CR. * 00037500
*********************************************************************/ 00037600
{ 00037700
int i; /* loop control */ 00037800
int negFlag = 0; /* negative currency flag */ 00037900
00038000
double amount; /* work var for amountIn */ 00038100
char moneyStr[200]; /* work string for type conv. */ 00038200
00038300
/******************************************************************* 00038400
* Clear any residual value from moneyOut * 00038500
*******************************************************************/ 00038600
for( i=0;i<strlen(moneyOut);i++) 00038700
moneyOut[i] = NULLCHAR; 00038800
00038900
/******************************************************************* 00039000
* If amountIn is negative, prefix moneyOut with neg curr indicators* 00039100
*******************************************************************/ 00039200
amount = *amountIn; 00039300
if( amount < 0 ) 00039400
{ 00039500
negFlag = 1; 00039600
if( CRDBInd[0] != NULLCHAR ) 00039700
1224 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
{ 00039800
amount = -amount; 00039900
00040000
if( strcmp( CRDBInd,"+/-" ) == 0 ) 00040100
strcpy( moneyOut,"-" ); 00040200
else if( strcmp( CRDBInd,"(/)" ) == 0 ) 00040300
strcpy( moneyOut,"(" ); 00040400
} 00040500
} 00040600
00040700
/******************************************************************* 00040800
* Append the currency type (currSymbol) to moneyOut. If currSymbol* 00040900
* is more than one byte, place a blank between it and the amount * 00041000
*******************************************************************/ 00041100
strcat( moneyOut,currSymbol ); 00041200
if( strlen( currSymbol ) > 1 ) 00041300
strcat( moneyOut," " ); 00041400
00041500
/******************************************************************* 00041600
* Set the local for the strfmon function * 00041700
*******************************************************************/ 00041800
if( setlocale( LC_ALL, "En_US" ) == NULL ) 00041900
{ 00042000
strcpy( message, 00042100
"DSN8DUCY Error: Error performing setlocale()" ); 00042200
strcpy( sqlstate, "38602" ); 00042300
return( NOT_OK ); 00042400
} 00042500
00042600
/******************************************************************* 00042700
* Reformat amount to a string type with thousands grouping * 00042800
*******************************************************************/ 00042900
strfmon( moneyStr,100,"%!n",amount ); 00043000
strcat( moneyOut,moneyStr ); 00043100
00043200
/******************************************************************* 00043300
* If amount < 0, append negative currency indicators, if passed * 00043400
*******************************************************************/ 00043500
if( CRDBInd[0] != NULLCHAR ) 00043600
{ 00043700
if( negFlag == 1 ) 00043800
{ 00043900
if( strcmp( CRDBInd,"CR/DB" ) == 0 ) 00044000
strcat( moneyOut," DB" ); 00044100
else if( strcmp( CRDBInd,"(/)" ) == 0 ) 00044200
strcat( moneyOut,")" ); 00044300
} 00044400
else 00044500
{ 00044600
if( strcmp( CRDBInd,"CR/DB" ) == 0 ) 00044700
strcat( moneyOut," CR" ); 00044800
} 00044900
} 00045000
00045100
return( OK ); 00045200
} /* end formatAmount */ 00045300
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSN8DUTI
Returns the name or the schema name or the location name of an alias according to the name of the UDF
and the number of input parameters passed, as follows.
/********************************************************************* 00010000
* Module name = DSN8DUTI (DB2 sample program) * 00020000
* * 00030000
* DESCRIPTIVE NAME = Resolve a fully-qualified (3 part), partially- * 00040000
* qualified (2 part), or unqualified alias to the * 00050000
* name, schema, or location of its base table or * 00060000
* view. * 00070000
* * 00080000
* LICENSED MATERIALS - PROPERTY OF IBM * 00090000
* 5675-DB2 * 00100000
* (C) COPYRIGHT 1997, 2000 IBM CORP. ALL RIGHTS RESERVED. * 00110000
* * 00150000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1225
* STATUS = VERSION 7 * 00160000
* * 00190000
* Function: Returns the name or the schema name or the location name * 00250000
* of an alias according to the name of the UDF and the * 00260000
* number of input parameters passed, as follows: * 00270000
* * 00280000
* TABLE_NAME( objectname ) * 00290000
* returns the unqualified name of the object found after * 00300000
* any alias chains have been resolved. The specified * 00310000
* object name, the default schema, and a location name * 00320000
* of "%" (for any location) are used as the starting * 00330000
* point of the resolution. If the starting point does * 00340000
* not refer to an alias, the unqualified name of the * 00350000
* starting point is returned. The resulting name may be * 00360000
* of a table, view, or undefined object. * 00370000
* * 00380000
* TABLE_NAME( objectname, objectschema ) * 00390000
* returns the unqualified name of the object found after * 00400000
* any alias chains have been resolved. The specified * 00410000
* object name and schema, and a location name of "%" * 00420000
* (for any location), are used as the starting point of * 00430000
* the resolution. If the starting point does not refer * 00440000
* to an alias, the unqualified name of the starting * 00450000
* point is returned. The resulting name may be of a * 00460000
* table, view, or undefined object. * 00470000
* * 00480000
* TABLE_NAME( objectname, objectschema, objectlocation ) * 00490000
* returns the unqualified name of the object found after * 00500000
* any alias chains have been resolved. The specified * 00510000
* object name, schema, and location name are used as the * 00520000
* starting point of the resolution. If the starting * 00530000
* point does not refer to an alias, the unqualified name * 00540000
* of the starting point is returned. The resulting name * 00550000
* may be of a table, view, or undefined object. * 00560000
* * 00570000
* TABLE_SCHEMA( objectname ) returns the schema name of * 00580000
* the object found after any alias chains have been * 00590000
* resolved. The specified object name, the default * 00600000
* schema, and a location name of "%" (for any location) * 00610000
* are used as the starting point of the resolution. If * 00620000
* the starting point does not refer to an alias, the * 00630000
* schema name of the starting point is returned. The * 00640000
* resulting schema name may be of a table, view, or * 00650000
* undefined object. * 00660000
* * 00670000
* TABLE_SCHEMA( objectname, objectschema ) returns the * 00680000
* schema name of the object found after any alias chains * 00690000
* have been resolved. The specified object name and * 00700000
* schema and a location name of "%" (for any location) * 00710000
* are used as the starting point of the resolution. If * 00720000
* the starting point does not refer to an alias, the * 00730000
* schema name of the starting point is returned. The * 00740000
* resulting schema name may be of a table, view, or * 00750000
* undefined object. * 00760000
* * 00770000
* TABLE_SCHEMA( objectname, objectschema, objectlocation ) * 00780000
* returns the schema name of the object found after any * 00790000
* alias chains have been resolved. The specified object * 00800000
* name, schema, and location name are used as the * 00810000
* starting point of the resolution. If the starting * 00820000
* point does not refer to an alias, the schema name of * 00830000
* starting point is returned. The resulting schema name * 00840000
* may be of a table, view, or undefined object. * 00850000
* * 00860000
* TABLE_LOCATION( objectname ) returns the location name * 00870000
* of the object found after any alias chains have been * 00880000
* resolved. The specified object name, the default * 00890000
* schema, and a location name of "%" (for any location) * 00900000
* are used as the starting point of the resolution. If * 00910000
* the starting point does not refer to an alias, a blank * 00920000
* location name (indicating the current server) is * 00930000
* returned. The resulting location name may be of a * 00940000
* table, view, or undefined object. * 00950000
* * 00960000
* TABLE_LOCATION( objectname, objectschema ) returns the * 00970000
* location name of the object found after any alias * 00980000
* chains have been resolved. The specified object name, * 00990000
* schema, and a location name of "%" (for any location) * 01000000
* are used as the starting point of the resolution. If * 01010000
* the starting point does not refer to an alias, a blank * 01020000
* location name (indicating the current server) is * 01030000
* returned. The resulting location name may be of a * 01040000
1226 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* table, view, or undefined object. * 01050000
* * 01060000
* TABLE_LOCATION( objectname,objectschema,objectlocation ) * 01070000
* returns the location name of the object found after * 01080000
* any alias chains have been resolved. The specified * 01090000
* object name, schema, and location name are used as the * 01100000
* starting point of the resolution. If the starting * 01110000
* point does not refer to an alias, a blank location * 01120000
* name (indicating the current server) is returned. The * 01130000
* resulting location name may be of a table, view, or * 01140000
* undefined object. * 01150000
* * 01160000
* Notes: * 01170000
* Dependencies: Requires IBM C/C++ for OS/390 V1R3 or higher * 01180000
* * 01190000
* Restrictions: * 01200000
* * 01210000
* Module type: C program * 01220000
* Processor: IBM C/C++ for OS/390 V1R3 or subsequent release * 01230000
* Module size: See linkedit output * 01240000
* Attributes: Re-entrant and re-usable * 01250000
* * 01260000
* Entry Point: CEESTART (Language Environment entry point) * 01270000
* Purpose: See Function * 01280000
* Linkage: DB2SQL * 01290000
* Invoked via SQL UDF call * 01300000
* * 01310000
* Parameters: DSN8DUTI uses the C "main" argument convention of * 01320000
* argv (argument vector) and argc (argument count). * 01330000
* * 01340000
* The location of input and output parameters depends * 01350000
* on whether the UDF (TABLE_NAME, TABLE_SCHEMA, or * 01360000
* TABLE_SCHEMA) is invoked with one, two, or three * 01370000
* input arguments. * 01380000
* * 01390000
* If the UDF was invoked with the object name only: * 01400000
* - ARGV[0] = (input) pointer to a char[9], null- * 01410000
* terminated string having the name of * 01420000
* this program (DSN8DUTI) * 01430000
* - ARGV[1] = (input) pointer to a char[19], null- * 01440000
* terminated string having the object name * 01450000
* to be used as the starting point of the * 01460000
* alias resolution * 01470000
* - ARGV[2] = (output) pointer to a null-terminated * 01480000
* string to receive the result as follows: * 01490000
* - char[19] for the TABLE_NAME UDF * 01500000
* - char[9] for the TABLE_SCHEMA UDF * 01510000
* - char[17] for the TABLE_LOCATION UDF * 01520000
* - ARGV[3] = (input) pointer to a short integer * 01530000
* having the null indicator for the object * 01540000
* name * 01550000
* - ARGV[4] = (output) pointer to a short integer * 01560000
* having the null indicator for the result * 01570000
* - ARGV[5] = (output) pointer to a char[6], null- * 01580000
* terminated string to receive the * 01590000
* SQLSTATE * 01600000
* - ARGV[6] = (input) pointer to a char[138], null- * 01610000
* terminated string having the UDF family * 01620000
* name of the function * 01630000
* - ARGV[7] = (input) pointer to a char[129], * 01645990
* null-terminated * 01651980
* string having the UDF specific name of * 01660000
* the function * 01670000
* - ARGV[8] = (output) pointer to a char[70], * 01680000
* null-terminated string to receive any * 01690000
* diagnostic message issued by this * 01700000
* function * 01710000
* * 01720000
* If the UDF was invoked with the object name and the * 01730000
* object schema (but not the object location name): * 01740000
* - ARGV[0] = (input) pointer to a char[9], null- * 01750000
* terminated string having the name of * 01760000
* this program (DSN8DUTI) * 01770000
* - ARGV[1] = (input) pointer to a char[19], null- * 01780000
* terminated string having the object name * 01790000
* to be used in conjunction with the * 01800000
* object schema as the starting point of * 01810000
* the alias resolution * 01820000
* - ARGV[2] = (input) pointer to a char[9], null- * 01830000
* terminated string having the object * 01840000
* schema to be in used in conjunction with * 01850000
* the object name as the starting point of * 01860000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1227
* the alias resolution * 01870000
* - ARGV[3] = (output) pointer to a null-terminated * 01880000
* string to receive the result as follows: * 01890000
* - char[19] for the TABLE_NAME UDF * 01900000
* - char[9] for the TABLE_SCHEMA UDF * 01910000
* - char[17] for the TABLE_LOCATION UDF * 01920000
* - ARGV[4] = (input) pointer to a short integer * 01930000
* having the null indicator for the object * 01940000
* name * 01950000
* - ARGV[5] = (input) pointer to a short integer * 01960000
* having the null indicator for the object * 01970000
* schema * 01980000
* - ARGV[6] = (output) pointer to a short integer * 01990000
* having the null indicator for the result * 02000000
* - ARGV[7] = (output) pointer to a char[6], null- * 02010000
* terminated string to receive the * 02020000
* SQLSTATE * 02030000
* - ARGV[8] = (input) pointer to a char[138], null- * 02040000
* terminated string having the UDF family * 02050000
* name of the function * 02060000
* - ARGV[9] = (input) pointer to a char[129], * 02070000
* null- terminated * 02080000
* string having the UDF specific name of * 02090000
* the function * 02100000
* - ARGV[10] = (output) pointer to a char[70], * 02110000
* null- terminated string to receive any * 02120000
* diagnostic message issued by this * 02130000
* function * 02140000
* * 02150000
* If the UDF was invoked with the object name and the * 02160000
* object schema and the object location name: * 02170000
* - ARGV[0] = (input) pointer to a char[9], null- * 02180000
* terminated string having the name of * 02190000
* this program (DSN8DUTI) * 02200000
* - ARGV[1] = (input) pointer to a char[19], null- * 02210000
* terminated string having the object name * 02220000
* to be used in conjunction with the * 02230000
* object schema and the object location * 02240000
* name as the starting point of the alias * 02250000
* resolution * 02260000
* - ARGV[2] = (input) pointer to a char[9], null- * 02270000
* terminated string having the object * 02280000
* schema to be in used in conjunction with * 02290000
* the object name and the object location * 02300000
* name as the starting point of the alias * 02310000
* resolution * 02320000
* - ARGV[3] = (input) pointer to a char[17], null- * 02330000
* terminated string having the object * 02340000
* location name to be used in conjunction * 02350000
* with the object name and the object * 02360000
* schema as the starting point of the * 02370000
* alias resolution * 02380000
* - ARGV[4] = (output) pointer to a null-terminated * 02390000
* string to receive the result as follows: * 02400000
* - char[19] for the TABLE_NAME UDF * 02410000
* - char[9] for the TABLE_SCHEMA UDF * 02420000
* - char[17] for the TABLE_LOCATION UDF * 02430000
* - ARGV[5] = (input) pointer to a short integer * 02440000
* having the null indicator for the object * 02450000
* name * 02460000
* - ARGV[6] = (input) pointer to a short integer * 02470000
* having the null indicator for the object * 02480000
* schema * 02490000
* - ARGV[7] = (input) pointer to a short integer * 02500000
* having the null indicator for the object * 02510000
* location name * 02520000
* - ARGV[8] = (output) pointer to a short integer * 02530000
* having the null indicator for the result * 02540000
* - ARGV[9] = (output) pointer to a char[6], null- * 02550000
* terminated string to receive the * 02560000
* SQLSTATE * 02570000
* - ARGV[10] = (input) pointer to a char[138], null- * 02580000
* terminated string having the UDF family * 02590000
* name of the function * 02600000
* - ARGV[11] = (input) pointer to a char[129], * 02610000
* null- terminated * 02620000
* string having the UDF specific name of * 02630000
* the function * 02640000
* - ARGV[12] = (output) pointer to a char[70], * 02650000
* null- terminated string to receive any * 02660000
* diagnostic message issued by this * 02670000
* function * 02680000
1228 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* * 02690000
* Normal Exit: Return Code: SQLSTATE = 00000 * 02700000
* - Message: none * 02710000
* * 02720000
* Error Exit: Return Code: SQLSTATE = 38601 * 02730000
* - Message: DSN8DUTI Error: Invocation by unexpected * 02740000
* UDF having specific name * 02750000
* <specific name> * 02760000
* Return Code: SQLSTATE = 38602 * 02770000
* - Message: DSN8DUTI Error: Unexpected SQLCODE, * 02780000
* <SQLCODE>, from SQL SELECT * 02790000
* * 02800000
* External References: * 02810000
* - Routines/Services: None * 02820000
* - Data areas : None * 02830000
* - Control blocks : None * 02840000
* * 02850000
* * 02860000
* Pseudocode: * 02870000
* DSN8DUTI: * 02880000
* - Walk down the argv list, locating the input and output parms * 02890000
* - If no object name passed, return null result * 02900000
* - If no object schema passed, assign default schema (current * 02910000
* SQLID) to object schema * 02920000
* - Concatenate wildcard ("%") to object location name * 02930000
* - SELECT TBNAME, TBCREATOR, and LOCATION from SYSIBM.SYSTABLES * 02940000
* where NAME is the object name, CREATOR is the object creator, * 02950000
* LOCATION is LIKE the object location name, and TYPE is "A" for * 02960000
* alias. * 02970000
* - if there's a result (SQLCODE = 0) then * 02980000
* - if the TABLE_NAME UDF is the invoker, assign the result * 02990000
* from TBNAME and return * 03000000
* - else if the TABLE_SCHEMA UDF is the invoker, assign the * 03010000
* result from TBCREATOR and return * 03020000
* - else if the TABLE_LOCATION UDF is the invoker, assign the * 03030000
* result from LOCATION and return * 03040000
* - else an unexpected UDF is the invoker so issue SQLSTATE * 03050000
* 38601 and a diagnstic message and return * 03060000
* - else if there's no result (SQLCODE = 100) then * 03070000
* - if the TABLE_NAME UDF is the invoker, assign the result * 03080000
* from the object name and return * 03090000
* - else if the TABLE_SCHEMA UDF is the invoker, assign the * 03100000
* result from the object schema and return * 03110000
* - else if the TABLE_LOCATION UDF is the invoker, remove the * 03120000
* trailing search wildcard ("%") from and assign the result * 03130000
* from LOCATION and return * 03140000
* - else an unexpected UDF is the invoker so issue SQLSTATE * 03150000
* 38601 and a diagnstic message and return * 03160000
* - else there's an unexpected SQLCODE so issue SQLSTATE 38602 * 03170000
* and a diagnostic message and return * 03180000
* End DSN8DUTI * 03190000
* * 03200000
* * 03210000
*********************************************************************/ 03220000
03230000
/********************** C library definitions ***********************/ 03270000
#include <stdio.h> 03280000
#include <stdlib.h> 03290000
#include <string.h> 03300000
03310000
/***************************** Equates ******************************/ 03320000
#define NULLCHAR '\0' /* Null character */ 03330000
03340000
#define MATCH 0 /* Comparison status: Equal */ 03350000
#define NOT_OK 0 /* Run status indicator: Error*/ 03360000
#define OK 1 /* Run status indicator: Good */ 03370000
03380000
03390000
/******************** DB2 SQL Communication Area ********************/ 03400000
EXEC SQL INCLUDE SQLCA; 03410000
03420000
03430000
/************************ DB2 Host Variables ************************/ 03440000
EXEC SQL BEGIN DECLARE SECTION; 03450000
char hvObjName[19]; /* host var for object name */ 03460000
short int *niObjName; /* indic var for hvObjName */ 03470000
char hvObjSchema[9]; /* host var for obj schema */ 03480000
short int *niObjSchema; /* indic var for hvObjSchema */ 03490000
char hvObjLocation[18]; /* host var for obj location */ 03500000
short int *niObjLocation; /* indic var for hvObjLocation*/ 03510000
char hvLOCATION[17]; /* host var for LOCATION col */ 03520000
char hvTBCREATOR[9]; /* host var for TBCREATOR col */ 03530000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1229
char hvTBNAME[19]; /* host var for TBNAME column */ 03540000
EXEC SQL END DECLARE SECTION; 03550000
03560000
03570000
int main( int argc, char *argv[] ) 03580000
{ 03590000
/************************ local variables *************************/ 03600000
03610000
short int minus1 = -1; /* default null indic setting */ 03620000
03630000
char *result; /* result of this function */ 03640000
short int *niResult; /* indic var, result */ 03650000
char *sqlstate; /* SQLSTATE */ 03660000
char fnName[138]; /* function name */ 03675990
char specificName[129]; /* specific name of function */ 03681980
char *message; /* diagnostic message */ 03690000
03700000
short int status = OK; /* DSN8DUTI run status */ 03710000
03720000
03730000
/******************************************************************* 03740000
* Walk down the argv list, locating the input and output parms * 03750000
*******************************************************************/ 03760000
argc--; /* convert argc to base 0 index*/ 03763000
03766000
message = (char *)argv[argc--]; /* out: point to UDF diag msg */ 03770000
03780000
strcpy( specificName, /* in: save UDF specific name */ 03790000
argv[argc--]); 03800000
03810000
strcpy( fnName,argv[argc--] ); /* in: save UDF function name */ 03820000
03830000
sqlstate = (char *)argv[argc--]; /* out: point to UDF sqlstate */ 03840000
03850000
niResult /* out: point to null indicator*/ 03860000
= (short int *)argv[argc--]; /* variable for result */ 03870000
03880000
if( argc == 7 ) /* if 3 input parms passed */ 03890000
niObjLocation /* ..in: point to null indic. */ 03900000
= (short int *)argv[argc--]; /* var for object loc'n */ 03910000
else /* otherwise it wasn't passed */ 03920000
niObjLocation = &minus1; /* ..so define it as null */ 03930000
03940000
if( argc >= 5 ) /* if 2 or 3 input parms passed*/ 03950000
niObjSchema /* ..in: point to null indic. */ 03960000
= (short int *)argv[argc--]; /* var for object schema */ 03970000
else /* otherwise it wasn't passed */ 03980000
niObjSchema = &minus1; /* ..so define it as null */ 03990000
04000000
niObjName /* in: point to null indicator */ 04010000
= (short int *)argv[argc--]; /* var for object name */ 04020000
04030000
result = (char *)argv[argc--]; /* out: point to UDF result */ 04040000
04050000
if( argc == 3 ) /* if 3 input parms passed */ 04060000
strcpy( hvObjLocation, /* ..in: save object location */ 04070000
argv[argc--] ); /* name */ 04080000
else /* otherwise it wasn't passed */ 04090000
hvObjLocation[0] = NULLCHAR; /* ..so define it as null */ 04100000
04110000
if( argc >= 2 ) /* if 2 or 3 input parms passed*/ 04120000
strcpy( hvObjSchema, /* ..in: save object schema */ 04130000
argv[argc--] ); /* */ 04140000
else /* otherwise it wasn't passed */ 04150000
hvObjSchema[0] = NULLCHAR; /* ..so define it as null */ 04160000
04170000
strcpy( hvObjName,argv[argc] ); /* in: save object name */ 04180000
04190000
04200000
/******************************************************************* 04210000
* Initialize output parms * 04220000
*******************************************************************/ 04230000
message[0] = NULLCHAR; 04240000
strcpy( sqlstate,"00000" ); 04250000
*niResult = 0; 04260000
result[0] = NULLCHAR; 04270000
04280000
/******************************************************************* 04290000
* If no object name provided, return null result * 04300000
*******************************************************************/ 04310000
if( ( *niObjName != 0 ) || ( strlen( hvObjName ) == 0 ) ) 04320000
status = NOT_OK; 04330000
1230 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
/******************************************************************* 04340000
* If no object schema provided, assign default schema * 04350000
*******************************************************************/ 04360000
if( ( *niObjSchema != 0 ) || ( strlen( hvObjSchema ) == 0 ) ) 04370000
EXEC SQL SET :hvObjSchema = CURRENT SQLID; 04380000
/******************************************************************* 04390000
* Concatenate "wildcard" to object location * 04400000
*******************************************************************/ 04410000
strcat( hvObjLocation,"%" ); 04420000
04430000
/******************************************************************* 04440000
* Look for alias with the object name (and schema (and location)) * 04450000
*******************************************************************/ 04460000
if( status == OK ) 04470000
{ 04480000
EXEC SQL SELECT TBNAME, 04490000
TBCREATOR, 04500000
LOCATION 04510000
INTO :hvTBNAME, 04520000
:hvTBCREATOR, 04530000
:hvLOCATION 04540000
FROM SYSIBM.SYSTABLES 04550000
WHERE NAME = :hvObjName 04560000
AND CREATOR = :hvObjSchema 04570000
AND LOCATION LIKE :hvObjLocation 04580000
AND TYPE = 'A'; 04590000
04600000
if( SQLCODE == 0 ) 04610000
/************************************************************* 04620000
* If such an alias was found ... * 04630000
*************************************************************/ 04640000
if( strncmp( specificName,"DSN8DUTIN",9 ) == 0 ) 04650000
/*********************************************************** 04660000
* TABLE_NAME UDF: return true name of table or view * 04670000
***********************************************************/ 04680000
strcpy( result,hvTBNAME ); 04690000
else if( strncmp( specificName,"DSN8DUTIS",9 ) == 0 ) 04700000
/*********************************************************** 04710000
* TABLE_SCHEMA UDF: return true schema of table or view * 04720000
***********************************************************/ 04730000
strcpy( result,hvTBCREATOR ); 04740000
else if( strncmp( specificName,"DSN8DUTIL",9 ) == 0 ) 04750000
/*********************************************************** 04760000
* TABLE_LOCATION UDF: return true loc'n of table or view * 04770000
***********************************************************/ 04780000
strcpy( result,hvLOCATION ); 04790000
else 04800000
/*********************************************************** 04810000
* Unknown UDF: signal error * 04820000
***********************************************************/ 04830000
{ 04840000
status = NOT_OK; 04850000
strcpy( sqlstate,"38601" ); 04860000
sprintf( message, 04870000
"DSN8DUTI Error: Invocation by unexpected UDF ", 04880000
"having specific name %s", 04890000
specificName ); 04900000
} 04910000
04920000
else if( SQLCODE == 100 ) 04930000
/************************************************************* 04940000
* If no such alias was found ... * 04950000
*************************************************************/ 04960000
if( strncmp( specificName,"DSN8DUTIN",9 ) == 0 ) 04970000
/*********************************************************** 04980000
* TABLE_NAME UDF: return starting point * 04990000
***********************************************************/ 05000000
strcpy( result,hvObjName ); 05010000
else if( strncmp( specificName,"DSN8DUTIS",9 ) == 0 ) 05020000
/*********************************************************** 05030000
* TABLE_SCHEMA UDF: return schema of starting point * 05040000
***********************************************************/ 05050000
strcpy( result,hvObjSchema ); 05060000
else if( strncmp( specificName,"DSN8DUTIL",9 ) == 0 ) 05070000
/*********************************************************** 05080000
* TABLE_LOCATION UDF: Remove trailing search wildcard byte * 05090000
* and return location of starting point * 05100000
***********************************************************/ 05110000
{ 05120000
hvObjLocation[strlen(hvObjLocation)-1] = NULLCHAR; 05130000
strcpy( result,hvObjLocation ); 05140000
} 05150000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1231
else 05160000
/*********************************************************** 05170000
* Unknown UDF: signal error * 05180000
***********************************************************/ 05190000
{ 05200000
status = NOT_OK; 05210000
strcpy( sqlstate,"38601" ); 05220000
sprintf( message, 05230000
"DSN8DUTI Error: Invocation by unexpected UDF ", 05240000
"having specific name %s", 05250000
specificName ); 05260000
} 05270000
05280000
else 05290000
/************************************************************* 05300000
* If unexpected SQLCODE, issue message * 05310000
*************************************************************/ 05320000
{ 05330000
status = NOT_OK; 05340000
strcpy( sqlstate,"38602" ); 05350000
sprintf( message, 05360000
"DSN8DUTI Error: Unexpected SQLCODE, %d, " 05370000
"from SQL SELECT", 05380000
SQLCODE ); 05390000
} 05400000
} /* end if( status == OK ) */ 05410000
05420000
/******************************************************************* 05430000
* If null starting point or unexpected SQLCODE, return null result * 05440000
*******************************************************************/ 05450000
if( status == NOT_OK ) 05460000
{ 05470000
result[0] = NULLCHAR; 05480000
*niResult = -1; 05490000
} 05500000
else 05510000
{ 05520000
*niResult = 0; 05530000
strcpy( sqlstate,"00000" ); 05540000
} 05560000
05570000
} /* end DSN8DUTI */ 05620000
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSN8DUWC
Invokes the sample UDF table function WEATHER to demon- strate how a UDF and UDF table handling
using static SQL.
/*********************************************************************
* Module name = DSN8DUWC (DB2 sample program) *
* *
* DESCRIPTIVE NAME = Client for sample UDF table function WEATHER *
* *
* *
* LICENSED MATERIALS - PROPERTY OF IBM *
* 5645-DB2 *
* (C) COPYRIGHT 1998 IBM CORP. ALL RIGHTS RESERVED. *
* *
* STATUS = VERSION 6 *
* *
* Function: Invokes the sample UDF table function WEATHER to demon- *
* strate how a UDF and UDF table handling using static SQL.*
* *
* Notes: *
* Dependencies: Requires IBM C/C++ for OS/390 V1R3 or higher *
* *
* Restrictions: *
* *
* Module type: C program *
* Processor: IBM C/C++ for OS/390 V1R3 or higher *
* Module size: See linkedit output *
* Attributes: Re-entrant and re-usable *
* *
* Entry Point: DSN8DUWC *
1232 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* Purpose: See Function *
* Linkage: DB2SQL *
* Invoked via SQL UDF call *
* *
* *
* Parameters: DSN8DUWC uses the C "main" argument convention of *
* argv (argument vector) and argc (argument count). *
* *
* - ARGV[0] = (input) pointer to a char[9], null- *
* terminated string having the name of *
* this program (DSN8DUWC) *
* - ARGV[1] = (input) pointer to a char[45], null- *
* terminated string having the name of the *
* source data for the weather reports. *
* *
* Normal Exit: Return Code: 0000 *
* - Message: none *
* *
* Error Exit: Return Code: 0008 *
* - Message: DSN8DUWC failed: Invalid parameter count *
* *
* - Message: <formatted SQL text from DSNTIAR> *
* *
* *
* External References: *
* - Routines/Services: DSNTIAR: DB2 msg text formatter *
* - Data areas : None *
* - Control blocks : None *
* *
* Pseudocode: *
* DSN8DUWC: *
* - Verify that 2 input parameters (program name and weather data *
* set name) were passed. *
* - if not, issue diagnostic message and end with code 0008 *
* - Open WEATHER_CURSOR, the client cursor for the WEATHER UDF *
* table function, passing the weather data set name as a host *
* variable *
* - if unsuccessful, call sql_error to issue a diagnostic mes- *
* sage, then end with code 0008. *
* - Do while not end of cursor *
* - Read the cursor *
* - If successful, print the result *
* - else if not end of cursor, call sql_error to issue a diag- *
* nostic message, then end with code 0008. *
* - Close the cursor *
* - if unsuccessful, call sql_error to issue a diagnostic mes- *
* sage, then end with code 0008. *
* End DSN8DUWC *
* *
* sql_error: *
* - call DSNTIAR to format the unexpected SQLCODE. *
* End sql_error *
* *
*********************************************************************/
/********************** C library definitions ***********************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1233
short int niTemp_in_f = 0; /* indic var for temperature */
if( status == OK )
{
EXEC SQL OPEN WEATHER_CURSOR;
if( SQLCODE != 0 )
sql_error( " *** Open weather cursor" );
1234 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
}
if( status == OK )
{
EXEC SQL CLOSE WEATHER_CURSOR;
if( SQLCODE != 0 )
sql_error( " *** Close weather cursor" );
}
if( status != OK )
completion_code = 8;
return( completion_code );
} /* end main */
/*********************************************************************
**********************************************************************
** SQL error handler **
**********************************************************************
*********************************************************************/
void sql_error( char locmsg[] ) /*proc*/
{
/*******************************************************************
* set status to prevent further processing *
*******************************************************************/
status = NOT_OK;
/*******************************************************************
* print the locator message *
*******************************************************************/
printf( " %.80s\n", locmsg );
/*******************************************************************
* format and print the SQL message *
*******************************************************************/
rc = dsntiar( &sqlca, &error_message, &lrecl );
if( rc == 0 )
for( j=0; j<DATA_DIM; j++ )
{
for( k=0; k<OUTLEN; k++ )
putchar(error_message.error_text[j][k] );
putchar('\n');
}
else
{
printf( " *** ERROR: DSNTIAR could not format the message\n" );
printf( " *** SQLCODE is %d\n",SQLCODE );
printf( " *** SQLERRM is \n" );
for( j=0; j<sqlca.sqlerrml; j++ )
printf( "%c", sqlca.sqlerrmc[j] );
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1235
printf( "\n" );
}
} /* end of sql_error */
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSN8DUWF
Returns weather information for various cities, as read from the data set passed as the argument to input
para- meter 'weatherDSN'.
/********************************************************************* 00000100
* Module name = DSN8DUWF (DB2 sample program) * 00000200
* * 00000300
* DESCRIPTIVE NAME = Weather (DB2 user-defined table function) * 00000400
* * 00000500
* 5675-DB2 * 00000600
* (C) COPYRIGHT 1998, 2000 IBM CORP. * 00000700
* * 00000800
* STATUS = VERSION 7 * 00000900
* * 00001000
* Function: Returns weather information for various cities, as read * 00001100
* from the data set passed as the argument to input para- * 00001200
* meter 'weatherDSN'. The data includes the name of a * 00001300
* city followed by its weather information: Temperature in * 00001400
* fahrenheit, percent humidity, wind direction, wind velo- * 00001500
* city, barometric pressure, and the forecast. See the * 00001600
* structure 'weatherRec' for the record format. * 00001700
* * 00001800
* File pointer information is retained between calls in * 00001900
* the UDF scratchpad area. * 00002000
* * 00002100
* Data read from the input data set is returned by this * 00002200
* function as a DB2 table with the following structure: * 00002300
* with this structure: * 00002400
* * 00002500
* CITY VARCHAR(30), * 00002600
* TEMP_IN_F INTEGER, * 00002700
* HUMIDITY INTEGER, * 00002800
* WIND VARCHAR(5), * 00002900
* WIND_VELOCITY INTEGER, * 00003000
* BAROMETER FLOAT, * 00003100
* FORECAST VARCHAR(25) * 00003200
* * 00003300
* Clients invoking this function can use standard SQL * 00003400
* syntax to create a desired result set. * 00003500
* * 00003600
* Example invocation: * 00003700
* * 00003800
* EXEC SQL DECLARE WEATHER_CURSOR * 00003900
* CURSOR FOR * 00004000
* SELECT CITY, * 00004100
* FORECAST * 00004200
* FROM TABLE( DSN8.WEATHER(:hvWeatherDSN) ) * 00004300
* AS W * 00004400
* WHERE CITY = 'Juneau, AK'; * 00004500
* * 00004600
* Notes: * 00004700
* Dependencies: Requires IBM C/C++ for OS/390 V1R3 or higher * 00004800
* * 00004900
* Restrictions: * 00005000
* * 00005100
* Module type: C program * 00005200
* Processor: IBM C/C++ for OS/390 V1R3 or higher * 00005300
* Module size: See linkedit output * 00005400
* Attributes: Re-entrant and re-usable * 00005500
* * 00005600
* Entry Point: DSN8DUWF * 00005700
* Purpose: See Function * 00005800
* Linkage: DB2SQL * 00005900
* Invoked via SQL UDF call * 00006000
* * 00006100
* * 00006200
* Input: Parameters explicitly passed to this function: * 00006300
* - *weatherDSN : pointer to a char[45], null-termi- * 00006400
1236 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* nated string having the name of the * 00006500
* source data for the weather reports. * 00006600
* - *niWeatherDSN: pointer to a short integer having * 00006700
* the null indicator variable for * 00006800
* *weatherDSN. * 00006900
* - *fnName : pointer to a char[138], null-termi- * 00007000
* nated string having the UDF family * 00007100
* name of this function. * 00007200
* - *specificName: pointer to a char[129], null-termi- * 00007300
* nated string having the UDF specific * 00007400
* name of this function. * 00007500
* * 00007600
* * 00007700
* Output: Parameters explicitly passed by this function: * 00007800
* - *city : pointer to a char[31], null-termi- * 00007900
* nated string to receive the name of * 00008000
* the city. * 00008100
* - *temp_in_f : pointer to a long integer to receive * 00008200
* the temperature in fahrenheit for * 00008300
* the city. * 00008400
* - *humidity : pointer to a long integer to receive * 00008500
* the percent humidity for the city. * 00008600
* - *wind : pointer to a char[6], null-termi- * 00008700
* nated string to receive the wind di- * 00008800
* rection for the city. * 00008900
* - *wind_velocity: pointer to a long integer to receive* 00009000
* the wind velocity for city. * 00009100
* - *barometer : pointer to a double word to receive * 00009200
* the barometric pressure for the city.* 00009300
* - *forecast : pointer to a char[26], null-termi- * 00009400
* nated string to receive the forecast * 00009500
* for the city. * 00009600
* - *niCity : pointer to a short integer to re- * 00009700
* ceive the null indicator variable * 00009800
* for *city. * 00009900
* - *niTemp_in_f : pointer to a short integer to re- * 00010000
* ceive the null indicator variable * 00010100
* for *temp_in_f. * 00010200
* - *niHumidity : pointer to a short integer to re- * 00010300
* ceive the null indicator variable * 00010400
* for *humidity. * 00010500
* - *niWind : pointer to a short integer to re- * 00010600
* ceive the null indicator variable * 00010700
* for *wind. * 00010800
* - *niWind_velocity: pointer to a short integer to re- * 00010900
* ceive the null indicator variable * 00011000
* for *wind_velocity. * 00011100
* - *niBarometer : pointer to a short integer to re- * 00011200
* ceive the null indicator variable * 00011300
* for *barometer. * 00011400
* - *niForecast : pointer to a short integer to re- * 00011500
* ceive the null indicator variable * 00011600
* for *forecast. * 00011700
* - *sqlstate : pointer to a char[06], null-termi- * 00011800
* nated string to receive the SQLSTATE.* 00011900
* - *message : pointer to a char[70], null-termi- * 00012000
* nated string to receive a diagnostic * 00012100
* message if one is generated by this * 00012200
* function. * 00012300
* * 00012400
* Normal Exit: Return Code: SQLSTATE = 00000 * 00012500
* - Message: none * 00012600
* * 00012700
* Return Code: SQLSTATE = 02000 (end of input) * 00012800
* - Message: none * 00012900
* * 00013000
* Error Exit: Return Code: SQLSTATE = 38601 * 00013100
* - Message: DSN8DUWF Error: Unable to allocate DD * 00013200
* <ddname>: Error code=<x>, * 00013300
* info code=<y> * 00013400
* * 00013500
* Return Code: SQLSTATE = 38602 * 00013600
* - Message: DSN8DUWF Error: Error opening weather data * 00013700
* set * 00013800
* * 00013900
* Return Code: SQLSTATE = 38603 * 00014000
* - Message: DSN8DUWF Error: Error reading weather data * 00014100
* set * 00014200
* * 00014300
* Return Code: SQLSTATE = 38604 * 00014400
* - Message: DSN8DUWF Error: Error closing weather data * 00014500
* set * 00014600
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1237
* * 00014700
* Return Code: SQLSTATE = 38605 * 00014800
* - Message: DSN8DUWF Error: FREE failed for DDNAME <x>.* 00014900
* Error code=<y>, info code= * 00015000
* <z> * 00015100
* * 00015200
* External References: * 00015300
* - Routines/Services: dyninit: IBM C/C++, dynit.h * 00015400
* - Initializes control block for * 00015500
* dynamic file allocation * 00015600
* dynalloc: IBM C/C++, dynit.h * 00015700
* - Dynamic file allocation * 00015800
* dynfree: IBM C/C++, dynit.h * 00015900
* - Dynamic file deallocation * 00016000
* - Data areas : None * 00016100
* - Control blocks : __dyn_t: IBM C/C++, dynint.h * 00016200
* - for dynamic file allocation * 00016300
* * 00016400
* Pseudocode: * 00016500
* DSN8DUWF: * 00016600
* - If SQLUDF call type is SQLUDF_TF_FIRST (-2) * 00016700
* - call allocWeatherDSN to allocate the data set name passed as * 00016800
* the argument to the weatherDSN parameter * 00016900
* - Else if SQLUDF call type is SQLUDF_TF_OPEN (-1) * 00017000
* - call openWeatherDS to open the weather data set * 00017100
* - Else if SQLUDF call type is SQLUDF_TF_FETCH (0) * 00017200
* - call readWeatherDS to read the next record from the weather * 00017300
* data set * 00017400
* - if EOF, set sqlstate to 02000 to signal end of cursor to * 00017500
* client * 00017600
* - else call buildReturnRow to populate the UDF table function * 00017700
* output parameters with data from the input record * 00017800
* - Else if SQLUDF call type is SQLUDF_TF_CLOSE (1) * 00017900
* - call closeWeatherDS to close the weather data set * 00018000
* - Else (SQLUDF call type is SQLUDF_TF_FINAL (2) ) * 00018100
* - call freeWeatherDS to deallocate the weather data set * 00018200
* End DSN8DUWF * 00018300
* * 00018400
* allocWeatherDS: * 00018500
* - if the data set name passed in as the argument to the input * 00018600
* parameter weatherDSN is for a partitioned data set, extract * 00018700
* the member name * 00018800
* - use dynalloc to dynamically allocate the data set (and member, * 00018900
* if applicable) * 00019000
* - if allocation error occurs, issue sqlstate 38601 and a diag- * 00019100
* nostic message * 00019200
* End allocWeatherDS * 00019300
* * 00019400
* openWeatherDS: * 00019500
* - open the weather data set * 00019600
* - if the data cannot be opened, issue sqlstate 38602 and a diag- * 00019700
* nostic message * 00019800
* End openWeatherDS * 00019900
* * 00020000
* readWeatherDS: * 00020100
* - read the next record from the data set * 00020200
* - this implicitly updates the file pointer variable, which is * 00020300
* maintained in the UDF scratchpad area * 00020400
* - if the data set cannot be read, issue sqlstate 38603 and a * 00020500
* diagnostic message * 00020600
* End readWeatherDS * 00020700
* * 00020800
* buildReturnRow: * 00020900
* - extract weather data fields from the weather data set * 00021000
* - perform appropriate data type conversions * 00021100
* - copy the (converted) data to the appropriate output parameters * 00021200
* End buildReturnRow * 00021300
* * 00021400
* closeWeatherDS: * 00021500
* - close the weather data set * 00021600
* - if the data cannot be closed, issue sqlstate 38604 and a diag- * 00021700
* nostic message * 00021800
* End closeWeatherDS * 00021900
* * 00022000
* freeWeatherDS: * 00022100
* - use dynfree to dynamically deallocate the weather data set * 00022200
* - if deallocation error occurs, issue sqlstate 38605 and a diag- * 00022300
* nostic message * 00022400
* End freeWeatherDS * 00022500
* * 00022600
*********************************************************************/ 00022700
00022800
1238 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
#pragma linkage(DSN8DUWF,fetchable) 00022900
00023000
/********************** C library definitions ***********************/ 00023100
#include <dynit.h> 00023200
#include <stdlib.h> 00023300
#include <string.h> 00023400
#include <stdio.h> 00023500
00023600
/***************************** Equates ******************************/ 00023700
#define NO 0 /* Negative */ 00023800
#define YES 1 /* Affirmative */ 00023900
00024000
#define NULLCHAR '\0' /* Null character */ 00024100
00024200
#define SQLUDF_TF_FIRST -2 /* First call */ 00024300
#define SQLUDF_TF_OPEN -1 /* Open table call */ 00024400
#define SQLUDF_TF_FETCH 0 /* Fetch next row call */ 00024500
#define SQLUDF_TF_CLOSE 1 /* Close table call */ 00024600
#define SQLUDF_TF_FINAL 2 /* Final call */ 00024700
00024800
/************************ Weather Data Set **************************/ 00024900
struct scr /* Struct for scratchpad area */ 00025000
{ 00025100
long len; /* Length of scratchpad data */ 00025200
FILE *WEATHRin; /* ptr to weather data set */ 00025300
char not_used[100]; /* filler */ 00025400
}; 00025500
00025600
char WEATHRinBuffer[8188]; /* Input buffer for weather ds*/ 00025700
short int moreWeatherRecs = YES;/* EOF indicator, weather ds */ 00025800
00025900
typedef struct /* Weather record structure */ 00026000
{ 00026100
char cityField[30]; /* name of city 01-30 */ 00026200
char filler1[1]; /* 31-31 */ 00026300
char temp_in_fField[3]; /* temp in fahrenheit 32-34 */ 00026400
char filler2[1]; /* 35-35 */ 00026500
char humidityField[3]; /* percent humidity 36-38 */ 00026600
char filler3[1]; /* 39-39 */ 00026700
char windField[5]; /* wind direction 40-44 */ 00026800
char filler4[1]; /* 45-45 */ 00026900
char windVelocityField[3]; /* wind velocity 46-48 */ 00027000
char filler5[1]; /* 49-49 */ 00027100
char barometerField[5]; /* baromtric pressure 50-54 */ 00027200
char filler6[1]; /* 55-55 */ 00027300
char forecastField[25]; /* forecast 56-80 */ 00027400
} weatherRec; 00027500
00027600
weatherRec *pweatherRec = (weatherRec *)&WEATHRinBuffer; 00027700
00027800
00027900
/*************************** Functions ******************************/ 00028000
void *DSN8DUWF /* Weather function */ 00028100
( char *weatherDSN, /* in: input ds, weather data */ 00028200
char *city, /* out: name of city */ 00028300
long int *temp_in_f, /* out: temp in fahrenheit */ 00028400
long int *humidity, /* out: relative humidity */ 00028500
char *wind, /* out: wind direction */ 00028600
long int *wind_velocity, /* out: wind velocity */ 00028700
double *barometer, /* out: barometric pressure */ 00028800
char *forecast, /* out: forecast */ 00028900
short int *niWeatherDSN, /* in: indic var, weather dsn */ 00029000
short int *niCity, /* out: indic var, city name */ 00029100
short int *niTemp_in_f, /* out: indic var, temperature*/ 00029200
short int *niHumidity, /* out: indic var, humidity */ 00029300
short int *niWind, /* out: indic var, wind dir */ 00029400
short int *niWind_velocity, /* out: indic var, wind veloc */ 00029500
short int *niBarometer, /* out: indic var, baro press */ 00029600
short int *niForecast, /* out: indic var, forecast */ 00029700
char *sqlstate, /* out: SQLSTATE */ 00029800
char *fnName, /* in: family name of function*/ 00029900
char *specificName, /* in: specific name of func */ 00030000
char *msgtext, /* out: diagnostic message */ 00030100
struct scr *scratchptr, /* i/o: scratchpad area */ 00030200
long *callType /* i/o: call type parameter */ 00030300
); 00030400
00030500
void allocWeatherDS /* Dynam allocates weather ds */ 00030600
( char *weatherDSN, /* in: name of weather ds */ 00030700
char *sqlstate, /* out: sqlstate */ 00030800
char *msgtext /* out: diag message text */ 00030900
); 00031000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1239
00031100
void openWeatherDS /* Opens weather data set */ 00031200
( struct scr *scratchptr, /* in: ptr to scratch pad */ 00031300
char *sqlstate, /* out: sqlstate */ 00031400
char *msgtext /* out: diag message text */ 00031500
); 00031600
00031700
void readWeatherDS /* Reads from weather data set*/ 00031800
( struct scr *scratchptr, /* in: ptr to scratch pad */ 00031900
char *sqlstate, /* out: sqlstate */ 00032000
char *msgtext /* out: diag message text */ 00032100
); 00032200
00032300
void buildReturnRow /* Builds function return row */ 00032400
( char *city, /* out: name of city */ 00032500
long int *temp_in_f, /* out: temp in fahrenheit */ 00032600
long int *humidity, /* out: relative humidity */ 00032700
char *wind, /* out: wind direction */ 00032800
long int *wind_velocity, /* out: wind velocity */ 00032900
double *barometer, /* out: barometric pressure */ 00033000
char *forecast, /* out: forecast */ 00033100
short int *niCity, /* out: indic var, city name */ 00033200
short int *niTemp_in_f, /* out: indic var, temperature*/ 00033300
short int *niHumidity, /* out: indic var, humidity */ 00033400
short int *niWind, /* out: indic var, wind dir */ 00033500
short int *niWind_velocity, /* out: indic var, wind veloc */ 00033600
short int *niBarometer, /* out: indic var, baro press */ 00033700
short int *niForecast /* out: indic var, forecast */ 00033800
); 00033900
00034000
void closeWeatherDS /* Closes weather data set */ 00034100
( struct scr *scratchptr, /* in: ptr to scratch pad */ 00034200
char *sqlstate, /* out: sqlstate */ 00034300
char *msgtext /* out: diag message text */ 00034400
); 00034500
00034600
void freeWeatherDS /* Dynam frees the weather ds */ 00034700
( char *sqlstate, /* out: sqlstate */ 00034800
char *msgtext /* out: diag message text */ 00034900
); 00035000
00035100
00035200
void *DSN8DUWF 00035300
( char *weatherDSN, /* in: input ds, weather data */ 00035400
char *city, /* out: name of city */ 00035500
long int *temp_in_f, /* out: temp in fahrenheit */ 00035600
long int *humidity, /* out: relative humidity */ 00035700
char *wind, /* out: wind direction */ 00035800
long int *wind_velocity, /* out: wind velocity */ 00035900
double *barometer, /* out: barometric pressure */ 00036000
char *forecast, /* out: forecast */ 00036100
short int *niWeatherDSN, /* in: indic var, weather dsn */ 00036200
short int *niCity, /* out: indic var, city name */ 00036300
short int *niTemp_in_f, /* out: indic var, temperature*/ 00036400
short int *niHumidity, /* out: indic var, humidity */ 00036500
short int *niWind, /* out: indic var, wind dir */ 00036600
short int *niWind_velocity, /* out: indic var, wind veloc */ 00036700
short int *niBarometer, /* out: indic var, baro press */ 00036800
short int *niForecast, /* out: indic var, forecast */ 00036900
char *sqlstate, /* out: SQLSTATE */ 00037000
char *fnName, /* in: family name of function*/ 00037100
char *specificName, /* in: specific name of func */ 00037200
char *msgtext, /* out: diagnostic message */ 00037300
struct scr *scratchptr, /* i/o: scratchpad area */ 00037400
long *callType /* i/o: call type parameter */ 00037500
) 00037600
/********************************************************************* 00037700
* Main routine for Weather table function * 00037800
*********************************************************************/ 00037900
{ 00038000
/******************************************************************* 00038100
* First call: Dynamically allocate the weather data set * 00038200
*******************************************************************/ 00038300
if( *callType == SQLUDF_TF_FIRST ) 00038400
{ 00038500
strcpy( sqlstate,"00000" ); /* Init sqlstate return var */ 00038600
*msgtext = NULLCHAR; /* Init message text rtrn var */ 00038700
allocWeatherDS( weatherDSN, sqlstate, msgtext ); 00038800
} 00038900
/******************************************************************* 00039000
* Second call: Open the weather data set * 00039100
*******************************************************************/ 00039200
1240 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
else if( *callType == SQLUDF_TF_OPEN ) 00039300
{ 00039400
strcpy( sqlstate,"00000" ); /* Init sqlstate return var */ 00039500
*msgtext = NULLCHAR; /* Init message text rtrn var */ 00039600
moreWeatherRecs = YES; /* EOF indicator, weather ds */ 00039700
openWeatherDS( scratchptr, sqlstate, msgtext ); 00039800
} 00039900
/******************************************************************* 00040000
* Subsequent calls: Read a record from the weather data set * 00040100
*******************************************************************/ 00040200
else if( *callType == SQLUDF_TF_FETCH ) 00040300
{ 00040400
readWeatherDS( scratchptr, sqlstate, msgtext ); 00040500
if( moreWeatherRecs == NO ) /* If no more weather data */ 00040600
strcpy( sqlstate,"02000" ); /* ..signal for FINAL CALL */ 00040700
else 00040800
{ 00040900
buildReturnRow( city, 00041000
temp_in_f, 00041100
humidity, 00041200
wind, 00041300
wind_velocity, 00041400
barometer, 00041500
forecast, 00041600
niCity, 00041700
niTemp_in_f, 00041800
niHumidity, 00041900
niWind, 00042000
niWind_velocity, 00042100
niBarometer, 00042200
niForecast ); 00042300
} 00042400
} 00042500
/******************************************************************* 00042600
* End of file: Close weather data set * 00042700
*******************************************************************/ 00042800
else if( *callType == SQLUDF_TF_CLOSE ) 00042900
{ 00043000
closeWeatherDS( scratchptr, sqlstate, msgtext ); 00043100
} 00043200
/******************************************************************* 00043300
* Final call: De-allocate weather data set * 00043400
*******************************************************************/ 00043500
else /* *callType == SQLUDF_TF_FINAL */ 00043600
{ 00043700
freeWeatherDS( sqlstate, msgtext ); 00043800
} 00043900
return; 00044000
} 00044100
00044200
00044300
void allocWeatherDS 00044400
( char *weatherDSN, /* in: name of weather ds */ 00044500
char *sqlstate, /* out: sqlstate */ 00044600
char *msgtext /* out: diag message text */ 00044700
) 00044800
/********************************************************************* 00044900
* Dynamically allocates weatherDSN to the WEATHRIN DD. If the value * 00045000
* in weatherDSN contains parentheses, it is assumed to specify a * 00045100
* partitioned data set; otherwise it is assumed to specify a * 00045200
* physical sequential data set. * 00045300
*********************************************************************/ 00045400
{ 00045500
__dyn_t ip; /* pointer to control block */ 00045600
char DSname[45]; /* recv's copy of weather dsn */ 00045700
char *tokPtr; /* string ptr for token parser*/ 00045800
00045900
dyninit( &ip ); /* Initialize control block */ 00046000
ip.__ddname = "WEATHRIN"; /* Specify DDNAME of WEATHRIN */ 00046100
/******************************************************************* 00046200
* Use the strtok func to separate the PDS member name, if any, * 00046300
* from the data set name * 00046400
*******************************************************************/ 00046500
strcpy( DSname,weatherDSN ); /* Get workcopy of weather dsn*/ 00046600
tokPtr = strtok( DSname,"(" ); /* Parse for open parenthesis */ 00046700
if( tokPtr == NULL ) /* If none found then */ 00046800
ip.__dsname = DSname; /* ...data set is not a PDS */ 00046900
else /* Otherwise */ 00047000
{ 00047100
ip.__dsname = tokPtr; /* ...token is name of a PDS */ 00047200
tokPtr = strtok( NULL,")" ); /* ...parse for close paren */ 00047300
ip.__member = tokPtr; /* ...token is name of member */ 00047400
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1241
} 00047500
ip.__status = __DISP_SHR; /* Specify DISP=SHR */ 00047600
00047700
/******************************************************************* 00047800
* If dynamic allocation failed, generate an error message and quit * 00047900
*******************************************************************/ 00048000
if( dynalloc(&ip) != 0 ) 00048100
{ 00048200
sprintf( msgtext,"Unable to allocate DD %s: " 00048300
"Error code=%hX, info code=%hX\n", 00048400
ip.__ddname, 00048500
ip.__errcode, 00048600
ip.__infocode ); 00048700
strcpy( sqlstate,"38601" ); 00048800
} 00048900
} /* end allocWeatherDS */ 00049000
00049100
00049200
void openWeatherDS 00049300
( struct scr *scratchptr, /* in: ptr to scratch pad */ 00049400
char *sqlstate, /* out: sqlstate */ 00049500
char *msgtext /* out: diag message text */ 00049600
) 00049700
/********************************************************************* 00049800
* Opens the weather data set, which has been allocated to the DD * 00049900
* WEATHRIN, for record-type input, and assigns the file pointer to * 00050000
* the scratchpad area indicated by scratchptr. * 00050100
*********************************************************************/ 00050200
{ 00050300
scratchptr->WEATHRin = fopen("DD:WEATHRIN", 00050400
"rb,recfm=vb,lrecl=8188,type=record"); 00050500
00050600
if( scratchptr->WEATHRin == NULL ) /* If unable to open data set */ 00050700
{ /* ..set return msg and state */ 00050800
strcpy( msgtext,"Error opening weather data set" ); 00050900
strcpy( sqlstate,"38602" ); 00051000
} 00051100
} /* end openWeatherDS */ 00051200
00051300
00051400
void readWeatherDS 00051500
( struct scr *scratchptr, /* in: ptr to scratch pad */ 00051600
char *sqlstate, /* out: sqlstate */ 00051700
char *msgtext /* out: diag message text */ 00051800
) 00051900
/********************************************************************* 00052000
* Reads the next record from the weather data set * 00052100
*********************************************************************/ 00052200
{ 00052300
short int recordLength = 0; /* Receives len of current rec*/ 00052400
00052500
recordLength /* */ 00052600
= fread( WEATHRinBuffer, /* Read into WEATHRinBuffer */ 00052700
1, /* ..a record */ 00052800
sizeof( WEATHRinBuffer ),/* ..<= len of WEATHRinBuffer */ 00052900
scratchptr->WEATHRin ); /* ..from the weather data set*/ 00053000
00053100
if( ferror(scratchptr->WEATHRin) ) /* If an error occurs */ 00053200
{ /* ..set return msg and state */ 00053300
strcpy( msgtext,"Error reading weather data set" ); 00053400
strcpy( sqlstate,"38603" ); 00053500
} 00053600
else if( feof(scratchptr->WEATHRin))/* Else if end of file reached*/ 00053700
moreWeatherRecs = NO; /* ..get ready to quit */ 00053800
} /* end readWeatherDS */ 00053900
00054000
00054100
void buildReturnRow /* Builds function return row */ 00054200
( char *city, /* out: name of city */ 00054300
long int *temp_in_f, /* out: temp in fahrenheit */ 00054400
long int *humidity, /* out: relative humidity */ 00054500
char *wind, /* out: wind direction */ 00054600
long int *wind_velocity, /* out: wind velocity */ 00054700
double *barometer, /* out: barometric pressure */ 00054800
char *forecast, /* out: forecast */ 00054900
short int *niCity, /* out: indic var, city name */ 00055000
short int *niTemp_in_f, /* out: indic var, temperature*/ 00055100
short int *niHumidity, /* out: indic var, humidity */ 00055200
short int *niWind, /* out: indic var, wind dir */ 00055300
short int *niWind_velocity, /* out: indic var, wind veloc */ 00055400
short int *niBarometer, /* out: indic var, baro press */ 00055500
short int *niForecast /* out: indic var, forecast */ 00055600
1242 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
) 00055700
/********************************************************************* 00055800
* Build a return row for the current call to the WEATHER table * 00055900
* function. * 00056000
*********************************************************************/ 00056100
{ 00056200
char workBuff[6]; /* for datatype conversions */ 00056300
00056400
/******************************************************************* 00056500
* Move the city name to its table variable * 00056600
*******************************************************************/ 00056700
strncpy( city,pweatherRec->cityField,30 ); 00056800
*niCity = 0; 00056900
00057000
/******************************************************************* 00057100
* Move the temperature to its table var after making it numeric * 00057200
*******************************************************************/ 00057300
memset( workBuff,'\0',6 ); 00057400
strncpy( workBuff,pweatherRec->temp_in_fField,3 ); 00057500
*temp_in_f = atoi( workBuff ); 00057600
*niTemp_in_f = 0; 00057700
00057800
/******************************************************************* 00057900
* Move the humidity factor to its table var after making it numeric* 00058000
*******************************************************************/ 00058100
memset( workBuff,'\0',6 ); 00058200
strncpy( workBuff,pweatherRec->humidityField,3 ); 00058300
*humidity = atoi( workBuff ); 00058400
*niHumidity = 0; 00058500
00058600
/******************************************************************* 00058700
* Move the wind direction to its table variable * 00058800
*******************************************************************/ 00058900
strncpy( wind,pweatherRec->windField,5 ); 00059000
*niWind = 0; 00059100
00059200
/******************************************************************* 00059300
* Move the wind velocity to its table var after making it numeric * 00059400
*******************************************************************/ 00059500
memset( workBuff,'\0',6 ); 00059600
strncpy( workBuff,pweatherRec->windVelocityField,3 ); 00059700
*wind_velocity = atoi( workBuff ); 00059800
*niWind_velocity = 0; 00059900
00060000
/******************************************************************* 00060100
* Move the forecast to its table variable * 00060200
*******************************************************************/ 00060300
memset( workBuff,'\0',6 ); 00060400
strncpy( workBuff,pweatherRec->barometerField,5 ); 00060500
*barometer = atof( workBuff ); 00060600
*niBarometer = 0; 00060700
00060800
/******************************************************************* 00060900
* Move the forecast to its table variable * 00061000
*******************************************************************/ 00061100
strncpy( forecast,pweatherRec->forecastField,25 ); 00061200
*niForecast = 0; 00061300
00061400
} /* end buildReturnRow */ 00061500
00061600
00061700
void closeWeatherDS 00061800
( struct scr *scratchptr, /* in: ptr to scratch pad */ 00061900
char *sqlstate, /* out: sqlstate */ 00062000
char *msgtext /* out: diag message text */ 00062100
) 00062200
/********************************************************************* 00062300
* Closes the weather data set and resets the file pointer in the * 00062400
* scratchpad area. * 00062500
*********************************************************************/ 00062600
{ 00062700
if( fclose(scratchptr->WEATHRin) != 0 ) 00062800
/* If unable to close data set*/ 00062900
{ /* ..set return msg and state */ 00063000
strcpy( msgtext,"Error closing weather data set" ); 00063100
strcpy( sqlstate,"38604" ); 00063200
} 00063300
else 00063400
scratchptr->WEATHRin = NULLCHAR; /* Otherwise, reset file ptr */ 00063500
} /* end closeWeatherDS */ 00063600
00063700
00063800
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1243
void freeWeatherDS 00063900
( char *sqlstate, /* out: sqlstate */ 00064000
char *msgtext /* out: diag message text */ 00064100
) 00064200
/********************************************************************* 00064300
* Dynamically frees the weather data set, which has been allocated * 00064400
* to the WEATHRIN DD. * 00064500
*********************************************************************/ 00064600
{ 00064700
__dyn_t free_ip; /* pointer to control block */ 00064800
00064900
dyninit( &free_ip ); /* Initialize control block */ 00065000
free_ip.__ddname = "WEATHRIN"; /* Set DD name of weather ds */ 00065100
00065200
if( dynfree(&free_ip) != 0 ) 00065300
{ 00065400
sprintf( msgtext,"FREE failed for DDNAME %s. " 00065500
"Error code=%hX, info code=%hX\n", 00065600
free_ip.__errcode, 00065700
free_ip.__errcode, 00065800
free_ip.__infocode ); 00065900
strcpy( sqlstate,"38605" ); 00066000
} 00066100
} /* end freeWeatherDS */ 00066200
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSN8EUDN
Returns the day of the week (Monday through Sunday) on which a given date in ISO format (YYYY-MM-DD)
falls.
/*********************************************************************
* Module name = DSN8EUDN (DB2 sample program) *
* *
* DESCRIPTIVE NAME = Query day of the week (UDF) *
* *
* LICENSED MATERIALS - PROPERTY OF IBM *
* 5675-DB2 *
* (C) COPYRIGHT 2000 IBM CORP. ALL RIGHTS RESERVED. *
* *
* STATUS = VERSION 7 *
* *
* Function: Returns the day of the week (Monday through Sunday) on *
* which a given date in ISO format (YYYY-MM-DD) falls. *
* *
* Example invocation: *
* EXEC SQL SET :dayname = DAYNAME( "2000-01-29" ); *
* ==> dayname = Tuesday *
* Notes: *
* Dependencies: Requires IBM C/C++ for OS/390 V1R3 or higher *
* *
* Restrictions: Assumes the Gregorian calendar was adopted in *
* September, 1752. Code modifications are required *
* to handle a different adoption date. *
* *
* Module type: C++ program *
* Processor: IBM C/C++ for OS/390 V1R3 or higher *
* Module size: See linkedit output *
* Attributes: Re-entrant and re-usable *
* *
* Entry Point: DSN8EUDN *
* Purpose: See Function *
* Linkage: DB2SQL *
* Invoked via SQL UDF call *
* *
* Input: Parameters explicitly passed to this function: *
* - *ISOdateIn : pointer to a char[11], null-termi- *
* nated string having a date in ISO *
* format. *
* - *niISOdateIn : pointer to a short integer having *
* the null indicator variable for *
* *ISOdateIn. *
* - *fnName : pointer to a char[138], null-termi- *
* nated string having the UDF family *
* name of this function. *
1244 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* - *specificName: pointer to a char[129], null-termi- *
* nated string having the UDF specific *
* name of this function. *
* *
* *
* Output: Parameters explicitly passed by this function: *
* - *dayNameOut : pointer to a char[10], null-termi- *
* nated string to receive the dayname *
* for ISOdateIn. *
* - *niDayNameOut: pointer to a short integer to re- *
* ceive the null indicator variable *
* for *dayNameOut. *
* - *sqlstate : pointer to a char[06], null-termi- *
* nated string to receive the SQLSTATE.*
* - *message : pointer to a char[70], null-termi- *
* nated string to receive a diagnostic *
* message if one is generated by this *
* function. *
* *
* Normal Exit: Return Code: SQLSTATE = 00000 *
* - Message: none *
* *
* Error Exit: Return Code: SQLSTATE = 38601 *
* - Message: DSN8EUDN Error: No date entered *
* Return Code: SQLSTATE = 38602 *
* - Message: DSN8EUDN Error: Input date not valid *
* or not in ISO format" *
* *
* External References: *
* - Routines/Services: *
* - strftime: Formatted time conversion routine *
* - from IBM C/C++ for z/OS run-time library *
* - strptime: Date and time conversion routine *
* - from IBM C/C++ for z/OS run-time library *
* - Data areas : None *
* - Control blocks : None *
* *
* *
* Pseudocode: *
* DSN8EUDN: *
* - Verify that a date was passed in: *
* - if *ISOdateIn blank or niISOdateIn is not 0, no date passed: *
* - issue SQLSTATE 38601 and a diagnostic message. *
* - Use strptime to validate the entry *
* - if *ISOdateIn is not a valid ISO date: *
* - issue SQLSTATE 38602 and a diagnostic message *
* - Parse out the year, month, and day *
* - Compute the weekday number (0=Sunday, ..., 6=Saturday) *
* - Use strptime and strftime to convert the day number to the *
* full weekday name of the current locale. *
* End DSN8EUDN *
* *
* Change log: *
* 2004-02-25: Rewritten due to demise of IBM Open Class library *
* *
*********************************************************************/
extern "C" void DSN8EUDN /* Establish linkage */
( char *ISOdateIn, /* in: date to look up */
char *dayNameOut, /* out: ISOdateIn's day name */
short int *niISOdateIn, /* in: indic var, ISOdateIn */
short int *niDayNameOut, /* out: indic var, dayNameOut */
char *sqlstate, /* out: SQLSTATE */
char *fnName, /* in: family name of function*/
char *specificName, /* in: specific name of func */
char *message /* out: diagnostic message */
);
#pragma linkage(DSN8EUDN,fetchable) /* Establish linkage */
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1245
/********************************************************************/
/*************************** main routine ***************************/
/********************************************************************/
void DSN8EUDN /* main routine */
( char *ISOdateIn, /* in: date to look up */
char *dayNameOut, /* out: ISOdateIn's day name */
short int *niISOdateIn, /* in: indic var, ISOdateIn */
short int *niDayNameOut, /* out: indic var, dayNameOut */
char *sqlstate, /* out: SQLSTATE */
char *fnName, /* in: family name of function*/
char *specificName, /* in: specific name of func */
char *message /* out: diagnostic message */
)
/*********************************************************************
* Returns the weekday name of the date in ISOdateIn. *
* *
* Assumptions: *
* - *ISOdateIn points to a char[11], null-terminated string *
* - *dayNameOut points to a char[10], null-terminated string *
* - *niISOdateIn points to a short integer *
* - *niDayNameOut points to a short integer *
* - *sqlstate points to a char[06], null-terminated string *
* - *fnName points to a char[138], null-terminated string *
* - *specificName points to a char[129], null-terminated string *
* - *message points to a char[70], null-terminated string *
*********************************************************************/
{
/*******************************************************************
* Verify that something has been passed in *
*******************************************************************/
if( *niISOdateIn != 0 || ( strlen( ISOdateIn ) == 0 ) )
{
status = NOT_OK;
strcpy( message,
"DSN8EUDN Error: No date entered" );
strcpy( sqlstate, "38601" );
}
/*******************************************************************
* Verify that the input looks like a date *
*******************************************************************/
if( status == OK )
{ rc = strptime( ISOdateIn,isoFormat,&tmbuff );
if( rc == NULL ) /* Unable to convert ISOdateIn*/
{
status = NOT_OK;
strcpy( message,
"DSN8EUDN Error: Input date not valid "
"or not in ISO format" );
strcpy( sqlstate, "38602" );
}
}
/*******************************************************************
1246 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* Parse the 4-digit year, the month no., and day no. from ISOdateIn*
*******************************************************************/
if( status == OK )
{ strcpy( workStr,ISOdateIn );
/*******************************************************************
* Get the weekday name of ISOdateIn *
*******************************************************************/
if( status == OK )
{ /***************************************************************
* Leap year allowance: Shift Jan and Feb to end of prev year *
***************************************************************/
if( monthInt < 3)
{ monthInt += 12;
yearInt--;
}
/***************************************************************
* Calculate weekday no. with Sunday basis *
***************************************************************/
weekDayInt = ( ((13 * monthInt) + 3) / 5 /* xform months */
+ dayInt /* + days */
+ yearInt /* + years */
+ yearInt / 4 /* + leapyear/4 */
- yearInt / 100 /* - leapyear/100 */
+ yearInt / 400 /* + leapyear/400 */
+ 1 /* + Sunday basis */
) % 7; /* % days per wk */
/***************************************************************
* adjust for pre-gregorian calendar (September 1752) *
***************************************************************/
if( (yearInt < 1752) || (yearInt == 1752 && monthInt < 9) )
{ if( weekDayInt > 3 )
weekDayInt = weekDayInt - 4;
else
weekDayInt = weekDayInt + 3;
}
/***************************************************************
* convert day of week from numeric to string *
***************************************************************/
sprintf( weekDayStr,"%02d",weekDayInt );
/***************************************************************
* Convert day of week from numeric string to day name *
***************************************************************/
rc = strptime( weekDayStr,weekDayFormat,&tmbuff );
*rc = strftime( dayNameOut,10,weekDayLongNameFormat,&tmbuff );
/*******************************************************************
* If weekday name was obtained, clear the message buffer and sql- *
* state, and unset the SQL null indicator for dayNameOut. *
*******************************************************************/
if( status == OK )
{
*niDayNameOut = 0;
message[0] = NULLCHAR;
strcpy( sqlstate,"00000" );
}
/*******************************************************************
* If errors occurred, clear the dayNameOut buffer and set the SQL *
* NULL indicator. A diagnostic message and the SQLSTATE have been *
* set where the error was detected. *
*******************************************************************/
else
{
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1247
dayNameOut[0] = NULLCHAR;
*niDayNameOut = -1;
}
return;
} /* end DSN8EUDN */
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSN8EUMN
Returns the calendar name of the month name in which a given date in ISO format (YYYY-MM-DD) falls.
/*********************************************************************
* Module name = DSN8EUMN (DB2 sample program) *
* *
* DESCRIPTIVE NAME = Query calendar month name (UDF) *
* *
* *
* LICENSED MATERIALS - PROPERTY OF IBM *
* 5675-DB2 *
* (C) COPYRIGHT 1998, 2000 IBM CORP. ALL RIGHTS RESERVED. *
* *
* STATUS = VERSION 7 *
* *
* *
* Function: Returns the calendar name of the month name in *
* which a given date in ISO format (YYYY-MM-DD) falls. *
* *
* Example invocation: *
* EXEC SQL SET :monthname = MONTHNAME( "2000-01-29" ); *
* ==> monthname = January *
* Notes: *
* Dependencies: Requires IBM C/C++ for OS/390 V1R3 or higher *
* *
* Restrictions: *
* *
* Module type: C++ program *
* Processor: IBM C/C++ for OS/390 V1R3 or higher *
* Module size: See linkedit output *
* Attributes: Re-entrant and re-usable *
* *
* Entry Point: DSN8EUMN *
* Purpose: See Function *
* Linkage: DB2SQL *
* Invoked via SQL UDF call *
* *
* Input: Parameters explicitly passed to this function: *
* - *ISOdateIn : pointer to a char[11], null-termi- *
* nated string having a date in ISO *
* format. *
* - *niISOdateIn : pointer to a short integer having *
* the null indicator variable for *
* *ISOdateIn. *
* - *fnName : pointer to a char[138], null-termi- *
* nated string having the UDF family *
* name of this function. *
* - *specificName: pointer to a char[129], null-termi- *
* nated string having the UDF specific *
* name of this function. *
* *
* *
* Output: Parameters explicitly passed by this function: *
* - *monthNameOut: pointer to a char[10], null-termi- *
* nated string to receive the month- *
* name for ISOdateIn. *
* - *niMonthNameOut: pointer to a short integer to re- *
* ceive the null indicator variable *
* for *monthNameOut. *
* - *sqlstate : pointer to a char[06], null-termi- *
* nated string to receive the SQLSTATE.*
* - *message : pointer to a char[70], null-termi- *
* nated string to receive a diagnostic *
* message if one is generated by this *
* function. *
* *
1248 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* Normal Exit: Return Code: SQLSTATE = 00000 *
* - Message: none *
* *
* Error Exit: Return Code: SQLSTATE = 38601 *
* - Message: DSN8EUMN Error: No date entered *
* Return Code: SQLSTATE = 38602 *
* - Message: DSN8EUMN Error: Input date not valid *
* or not in ISO format" *
* *
* External References: *
* - Routines/Services: *
* - strftime: Formatted time conversion routine *
* - from IBM C/C++ for z/OS run-time library *
* - strptime: Date and time conversion routine *
* - from IBM C/C++ for z/OS run-time library *
* - Data areas : None *
* - Control blocks : None *
* *
* *
* Pseudocode: *
* DSN8EUMN: *
* - Verify that a date was passed in: *
* - if *ISOdateIn blank or niISOdateIn is not 0, no date passed: *
* - issue SQLSTATE 38601 and a diagnostic message. *
* - Use strptime to validate the entry and convert the date to tm *
* - if *ISOdateIn is not a valid ISO date: *
* - issue SQLSTATE 38602 and a diagnostic message *
* - Use strftime to get the full monthname for the locale *
* End DSN8EUMN *
* *
* Change log: *
* 2004-02-25: Rewritten due to demise of IBM Open Class library *
* *
*********************************************************************/
extern "C" void DSN8EUMN /* Establish linkage */
( char *ISOdateIn, /* in: date to look up */
char *monthNameOut, /* out: ISOdateIn's month name*/
short int *niISOdateIn, /* in: indic var, ISOdateIn */
short int *niMonthNameOut, /* out: indic var,monthNameOut*/
char *sqlstate, /* out: SQLSTATE */
char *fnName, /* in: family name of function*/
char *specificName, /* in: specific name of func */
char *message /* out: diagnostic message */
);
/********************************************************************/
/*************************** main routine ***************************/
/********************************************************************/
void DSN8EUMN /* main routine */
( char *ISOdateIn, /* in: date to look up */
char *monthNameOut, /* out: ISOdateIn's month name*/
short int *niISOdateIn, /* in: indic var, ISOdateIn */
short int *niMonthNameOut, /* out: indic var,monthNameOut*/
char *sqlstate, /* out: SQLSTATE */
char *fnName, /* in: family name of function*/
char *specificName, /* in: specific name of func */
char *message /* out: diagnostic message */
)
/*********************************************************************
* Returns the name of the month for the date in isoDate. *
* *
* Assumptions: *
* - *ISOdateIn points to a char[11], null-terminated string *
* - *monthNameOut points to a char[10], null-terminated string *
* - *niISOdateIn points to a short integer *
* - *niMonthNameOut points to a short integer *
* - *sqlstate points to a char[06], null-terminated string *
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1249
* - *fnName points to a char[138], null-terminated string *
* - *specificName points to a char[129], null-terminated string *
* - *message points to a char[70], null-terminated string *
*********************************************************************/
{
/*******************************************************************
* Verify that something has been passed in *
*******************************************************************/
if( *niISOdateIn != 0 || ( strlen( ISOdateIn ) == 0 ) )
{
status = NOT_OK;
strcpy( message,
"DSN8EUMN Error: No date entered" );
strcpy( sqlstate, "38601" );
}
/*******************************************************************
* Convert ISOdateIn to C tm format *
*******************************************************************/
if( status == OK )
{ rc = strptime( ISOdateIn,isoFormat,&tmbuff );
if( rc == NULL ) /* Unable to convert ISOdateIn*/
{
status = NOT_OK;
strcpy( message,
"DSN8EUMN Error: Input date not valid "
"or not in ISO format" );
strcpy( sqlstate, "38602" );
}
}
/*******************************************************************
* Convert the date from C tm format to the locale's full monthname *
*******************************************************************/
if( status == OK )
{ *rc = strftime( monthNameOut,10,fullMonthName,&tmbuff );
}
/*******************************************************************
* If month name was obtained, clear the message buffer and sql- *
* state, and unset the SQL null indicator for monthNameOut. *
*******************************************************************/
if( status == OK )
{
*niMonthNameOut = 0;
message[0] = NULLCHAR;
strcpy( sqlstate,"00000" );
}
/*******************************************************************
* If errors occurred, clear the monthNameOut buffer and set the SQL*
* NULL indicator. A diagnostic message and the SQLSTATE have been *
* set where the error was detected. *
*******************************************************************/
else
{
monthNameOut[0] = NULLCHAR;
*niMonthNameOut = -1;
}
return;
} /* end DSN8EUMN */
Related reference
“Sample applications in TSO” on page 1025
1250 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
A set of Db2 sample applications run in the TSO environment.
DSN8DLPL
Populates the PSEG_PHOTO (500K BLOB) and BMP_PHOTO (100K BLOB) columns of the
EMP_PHOTO_RESUME sample table with data read from sequential data sets.
/*********************************************************************
* Module name = DSN8DLPL (DB2 sample program) *
* *
* DESCRIPTIVE NAME = Populate LOB columns that exceed 32K with data *
* read from sequential data sets. *
* *
* *
* LICENSED MATERIALS - PROPERTY OF IBM *
* 5655-DB2 *
* (C) COPYRIGHT 1997 IBM CORP. ALL RIGHTS RESERVED. *
* *
* STATUS = VERSION 6 *
* *
* Function: Populates the PSEG_PHOTO (500K BLOB) and BMP_PHOTO (100K *
* BLOB) columns of the EMP_PHOTO_RESUME sample table with *
* data read from sequential data sets. *
* *
* LOB locators are used to avoid having to contain all the *
* data in the application's storage. *
* *
* Notes: *
* Dependencies: Requires IBM C/C++ for OS/390 V1R3 or higher *
* *
* Restrictions: *
* *
* Module type: C program *
* Processor: IBM C/C++ for OS/390 V1R3 or subsequent release *
* Module size: See linkedit output *
* Attributes: Re-entrant and re-usable *
* *
* Entry Point: CEESTART (Language Environment entry point) *
* Purpose: See Function *
* Linkage: Standard MVS program invocation, no parameters *
* *
* Input: Symbolic label/name = PSEGINnn, where 00 <= nn <= 99 *
* Description = PSEG photo image data *
* *
* Symbolic label/name = BMPINnn, where 00 <= nn <= 99 *
* Description = BMP photo image data *
* *
* Output: Symbolic label/name = SYSPRINT *
* Description = Report and messages *
* *
* *
* Normal Exit: Return Code = 0000 *
* - Message: none *
* *
* Error Exit: Return Code = 0008 *
* - Message: *** ERROR: DSN8DLPL DB2 Sample Program *
* Unable to open BMPINnn DD data *
* set. Processing terminated. *
* *
* - Message: *** ERROR: DSN8DLPL DB2 Sample Program *
* Unexpected SQLCODE encountered *
* at location xxx *
* Error detailed below *
* Processing terminated *
* (DSNTIAR-formatted message *
* follows). *
* *
* External References: *
* - Routines/Services: DSNTIAR *
* - Data areas : DSNTIAR error_message *
* - Control blocks : None *
* *
* *
* Pseudocode: *
* DSN8DLPL: *
* - Set DD counter (nn) to 00 *
* - Do while more PSEGINnn DD's to process *
* - Call openPSEGfile to open the data set associated with *
* DD PSEGINnn *
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1251
* - Call getPSEGrec to read the first record of the data set *
* - Extract the employee serial from this record *
* - Call openBMPfile to open the data set associated with *
* DD BMPINnn *
* - Call getBMPrec to read the first record of the data set *
* - Call primeBLOBcols to: *
* (a) UPDATE the PSEG_PHOTO and BMP_PHOTO columns of the *
* employee's row in the EMP_PHOTO_RESUME table with the *
* contents of these first records *
* (b) SELECT the PSEG_PHOTO and BMP_PHOTO columns back into *
* BLOB locators *
* - Call getPSEGrec to read the next record from the PSEGINnn DD *
* - Do while not end of file for the PSEGINnn DD *
* - Call buildPSEGcol to append the current PSEGINnn record to *
* the PSEG BLOB locator *
* - Call getPSEGrec to read the next record from PSEGINnn *
* - Call getBMPrec to read the next record from the BMPINnn DD *
* - Do while not end of file for the BMPINnn DD *
* - Call buildBMPcol to append the current BMPINnn record to *
* the BMP BLOB locator *
* - Call getBMPrec to read the next record from BMPINnn *
* - Call updateBLOBcols to apply the BLOB locators to the *
* PSEG_PHOTO and BMP_PHOTO columns of the employee's row in *
* the EMP_PHOTO_RESUME table *
* - If all went well, call commitWorkUnit to commit the changes *
* - Else call rollbackWorkUnit to roll back the changes *
* - Print a status line *
* - Close the PSEGINnn and BMPINnn DD's *
* - Increment DD counter (nn) by 1. *
* - If an SQL error occurs, invoke the sql_error routine to gener- *
* ate and display message text *
* End DSN8DLPL *
* *
* openPSEGfile: *
* - Open the data set associated with the PSEGINnn DD *
* - If the open fails, set validDD to false *
* End openPSEGfile *
* *
* getPSEGrec: *
* - Read a record from the data set associated with the PSEGINnn DD*
* - If end of file, set morePSEGrecs to false *
* End getPSEGrec *
* *
* openBMPfile: *
* - Open the data set associated with the BMPINnn DD *
* End openBMPfile *
* *
* getBMPrec: *
* - Read a record from the data set associated with the BMPINnn DD *
* - If end of file, set moreBMPrecs to false *
* End getBMPrec *
* *
* primeBLOBcols: *
* - extract the employee serial from bytes 10-15 of the PSEG *
* buffer. *
* - UPDATE the PSEG_PHOTO and BMP_PHOTO columns for the employee's *
* row in the EMP_PHOTO_RESUME table from the PSEG and BMP records*
* - SELECT the PSEG_PHOTO and BMP_PHOTO columns for the employee *
* into LOB locators blPSEG1 and blBMP1
* End primeBLOBcols *
* *
* buildPSEGcol: *
* - append the contents of the PSEG input record to the PSEG BLOB *
* locator blPSEG1 and assign to BLOB locator blPSEG2 *
* - free BLOB locator blPSEG1 *
* - set BLOB locator blPSEG1 from BLOB locator blPSEG2 *
* - free BLOB locator blPSEG2 *
* End buildPSEGcol *
* *
* buildBMPcol: *
* - append the contents of the BMP input record to the BMP BLOB *
* locator blBMP1 and assign to BLOB locator blBMP2 *
* - free BLOB locator blBMP1 *
* - set BLOB locator blBMP1 from BLOB locator blBMP2 *
* - free BLOB locator blBMP2 *
* End buildBMPcol *
* *
* updateBLOBcols: *
* - UPDATE the PSEG_PHOTO and BMP_PHOTO columns for the employee's *
* row in the EMP_PHOTO_RESUME table from the PSEG and BMP BLOB *
* locators BMP blPSEG1 and blBMP1 *
* End updateBLOBcols *
1252 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* *
* commitWorkUnit: *
* - commit the changes *
* End commitWorkUnit *
* *
* rollbackWorkUnit: *
* - roll back the changes *
* End rollbackWorkUnit *
* *
* sql_error: *
* - call DSNTIAR to format the unexpected SQLCODE. *
* End sql_error *
* *
*********************************************************************/
/********************** C library definitions ***********************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1253
SQL TYPE IS BLOB(8K) BMPinRec; /* Area for BMP input record */
short int niBMP_PHOTO = 0; /* Null ind for BMP photo col */
EXEC SQL END DECLARE SECTION;
/********************************************************************/
/*************************** main routine ***************************/
/********************************************************************/
int main( void )
{
/******************************************************************/
/************************* Initialization *************************/
/******************************************************************/
/*******************************************************************
* Write identification header *
*******************************************************************/
printf( "****************************************"
"****************************************\n" );
printf( "* DSN8DLPL DB2 Sample Program\n" );
printf( "****************************************"
"****************************************\n" );
/******************************************************************/
/*************************** Processing ***************************/
/******************************************************************/
/*******************************************************************
* Cycle through PSEGINnn and BMPINnn DD pairs, incrementing the DD *
* counter, until all pairs have been processed. *
*******************************************************************/
for( DDcounter=0; validDD == YES && status == OK; DDcounter++ )
{
/***************************************************************
* Fetch the PSEG data from the current PSEGINnn DD. The first *
* record contains the serial number of the employee associated *
* with the photo. *
***************************************************************/
openPSEGfile();
if( validDD == YES && status == OK )
getPSEGrec();
/***************************************************************
* Fetch the first record from the BMPINnn DD *
***************************************************************/
1254 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
if( validDD == YES && status == OK )
openBMPfile();
if( validDD == YES && status == OK )
getBMPrec();
/***************************************************************
* Init the PSEG and BMP BLOB table columns for the employee *
***************************************************************/
if( validDD == YES && status == OK )
primeBLOBcols();
/***************************************************************
* Read the second records from the PSEG and BMP data sets *
***************************************************************/
if( validDD == YES && status == OK )
getPSEGrec();
if( validDD == YES && status == OK )
getBMPrec();
/***************************************************************
* Append remaining PSEG recs to PSEG photo col using BLOB loc *
***************************************************************/
while( morePSEGrecs == YES && validDD == YES && status == OK )
{
buildPSEGcol();
if( status == OK )
getPSEGrec();
}
/***************************************************************
* Append remaining BMP recs to BMP photo col using BLOB locator*
***************************************************************/
while( moreBMPrecs == YES && validDD == YES && status == OK )
{
buildBMPcol();
if( status == OK )
getBMPrec();
}
/***************************************************************
* Apply the data associated with the PSEG and BMP BLOB locators*
* to the table *
***************************************************************/
if( validDD == YES && status == OK )
updateBLOBcols();
/***************************************************************
* If clear status, commit the work unit; otherwise, rollback *
***************************************************************/
if( validDD == YES )
if( status == OK )
commitWorkUnit();
else
rollbackWorkUnit();
/***************************************************************
* Print report line *
***************************************************************/
if( validDD == YES && status == OK )
{
printf( "* LOB population statistics for employee "
"number %s follow:\n", hvEMPNO );
printf( "* - PSEG photo bytes: %d\n",PSEGcolLen );
printf( "* - BMP photo bytes: %d\n",BMPcolLen );
printf( "****************************************"
"****************************************\n" );
}
/***************************************************************
* Close data sets for current PSEGINnn and BMPINnn DDs *
***************************************************************/
fclose(PSEGin);
fclose(BMPin);
} /* end for( DDcounter=0; validDD == YES && status == OK ... */
/******************************************************************/
/***************************** Cleanup ****************************/
/******************************************************************/
/*******************************************************************
* Set return code *
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1255
*******************************************************************/
if( status == OK )
return( 0 );
else
return( 8 );
} /* end main */
/*******************************************************************
* form the DD name for the next PSEG data set *
*******************************************************************/
strcpy( PSEGinDD,"DD:PSEGIN\0" ); /* init PSEGin DD template */
sprintf( DDnum,"%02d",DDcounter ); /* convert DD cntr to string */
strcat( PSEGinDD,DDnum ); /* form PSEGINnn DD name */
/*******************************************************************
* open the PSEGINnn DD data set *
*******************************************************************/
PSEGin = fopen( PSEGinDD,"rb,recfm=u" );
1256 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
PSEGrecPos = 0;
PSEGinRec.length = 0;
/*******************************************************************
* read the 1st byte of the record *
*******************************************************************/
byteIn = getc(PSEGin);
/*******************************************************************
* get remaining bytes of the record if not EOF *
*******************************************************************/
if( byteIn != EOF )
{
/***************************************************************
* if at end of block, read next BDW *
***************************************************************/
if( PSEGblkPos >= PSEGblkLen && PSEGrecPos >= PSEGrecLen)
{
/***********************************************************
* length of block = (16**2) * BDW[0] *
* ............... + (16**0) * BDW[1] *
* ............... - 4 (length of BDW) *
***********************************************************/
PSEGblkLen = 256 * byteIn;
byteIn = getc(PSEGin);
PSEGblkLen = PSEGblkLen + byteIn - 4;
/***********************************************************
* skip remainder of BDW *
***********************************************************/
byteIn = getc(PSEGin);
byteIn = getc(PSEGin);
PSEGblkPos = 0;
/***********************************************************
* read first byte of RDW *
***********************************************************/
byteIn = getc(PSEGin);
}
/***************************************************************
* process the RDW *
****************************************************************
* length of record = (16**2) * RDW[0] *
* ................ + (16**0) * RDW[1] *
* ................ - 4 (length of RDW) *
***************************************************************/
PSEGrecLen = 256 * byteIn;
byteIn = getc(PSEGin);
PSEGrecLen = PSEGrecLen + byteIn - 4;
/***************************************************************
* skip remainder of RDW *
***************************************************************/
byteIn = getc(PSEGin);
byteIn = getc(PSEGin);
PSEGrecPos = 0;
/***************************************************************
* update position in block *
***************************************************************/
PSEGblkPos = PSEGblkPos + PSEGrecLen + 4;
}
/*******************************************************************
* build the PSEG record according to the record length *
*******************************************************************/
while( PSEGrecPos < PSEGrecLen && byteIn != EOF )
{
byteIn = getc(PSEGin);
PSEGinRec.data[PSEGinRec.length++] = byteIn;
PSEGrecPos++;
}
/*******************************************************************
* signal end of file when applicable *
*******************************************************************/
if( byteIn == EOF )
morePSEGrecs = NO;
} /* end getPSEGrec */
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1257
/*********************************************************************
* Opens the data set associated with the BMPINnn DD, where "nn" is *
* the current setting of the DD counter from the main loop. *
* *
* If the DD cannot be allocated, then an error has occurred because *
* each BMPINnn DD must be paired with a PSEGINnn data set. *
*********************************************************************/
{
/*******************************************************************
* intialize work variables *
*******************************************************************/
moreBMPrecs = YES;
BMPblkPos = 0;
BMPblkLen = 0;
/*******************************************************************
* form the DD name for the next BMP data set *
*******************************************************************/
strcpy( BMPinDD,"DD:BMPIN\0" ); /* init BMPin DD template */
sprintf( DDnum,"%02d",DDcounter ); /* convert DD cntr to string */
strcat( BMPinDD,DDnum ); /* form BMPINnn DD name */
/*******************************************************************
* open the current BMPINnn DD data set *
*******************************************************************/
BMPin = fopen( BMPinDD,"rb,recfm=u" );
1258 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
/*******************************************************************
* read the 1st byte of the record *
*******************************************************************/
byteIn = getc(BMPin);
/*******************************************************************
* get remaining bytes of the record if not EOF *
*******************************************************************/
if( byteIn != EOF )
{
/***************************************************************
* if at end of block, read next BDW *
***************************************************************/
if( BMPblkPos >= BMPblkLen )
{
/***********************************************************
* length of block = (16**2) * BDW[0] *
* ............... + (16**0) * BDW[1] *
* ............... - 4 (length of BDW) *
***********************************************************/
BMPblkLen = 256 * byteIn;
byteIn = getc(BMPin);
BMPblkLen = BMPblkLen + byteIn - 4;
/***********************************************************
* skip remainder of BDW *
***********************************************************/
byteIn = getc(BMPin);
byteIn = getc(BMPin);
BMPblkPos = 0;
/***********************************************************
* read first byte of RDW *
***********************************************************/
byteIn = getc(BMPin);
}
/***************************************************************
* process the RDW *
****************************************************************
* length of record = (16**2) * RDW[0] *
* ................ + (16**0) * RDW[1] *
* ................ - 4 (length of RDW) *
***************************************************************/
BMPrecLen = 256 * byteIn;
byteIn = getc(BMPin);
BMPrecLen = BMPrecLen + byteIn - 4;
/***************************************************************
* skip remainder of RDW *
***************************************************************/
byteIn = getc(BMPin);
byteIn = getc(BMPin);
BMPrecPos = 0;
/***************************************************************
* update position in block *
***************************************************************/
BMPblkPos = BMPblkPos + BMPrecLen + 4;
}
/*******************************************************************
* build the BMP record according to the record length *
*******************************************************************/
while( BMPrecPos < BMPrecLen && byteIn != EOF )
{
byteIn = getc(BMPin);
BMPinRec.data[BMPinRec.length++] = byteIn;
BMPrecPos++;
}
/*******************************************************************
* signal end of file when applicable *
*******************************************************************/
if( byteIn == EOF )
moreBMPrecs = NO;
} /* end getBMPrec */
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1259
* to the PSEG_PHOTO and BMP_PHOTO BLOB columns, respectively, and *
* then fetch those columns using BLOB locators. *
* *
* The PSEG BLOB locator will be used by the buildPSEGcol function *
* to build a BLOB entity of up to 500K bytes from the remaining *
* PSEGin records without consuming application workspace. *
* *
* The BMP BLOB locator will be used by the buildBMPcol function to *
* build a BLOB entity of up to 500K bytes from the remaining BMPin *
* records, again without consuming application workspace. *
* *
* When all PSEG and BMP records have been processed, the data will *
* be applied from the BLOB locators to the EMP_PHOTO_RESUME table by *
* the updateBLOBcols function. *
*********************************************************************/
{
char *empser; /* */
/*******************************************************************
* Extract the employee number from bytes 10-15 of the PSEG record *
*******************************************************************/
empser = &PSEGinRec.data[9];
strncpy( hvEMPNO,empser,6 );
/*******************************************************************
* Initialize the BLOB columns with data from the 1st input records *
*******************************************************************/
EXEC SQL UPDATE EMP_PHOTO_RESUME
SET PSEG_PHOTO = :PSEGinRec,
BMP_PHOTO = :BMPinRec
WHERE EMPNO = :hvEMPNO;
if( SQLCODE != 0 )
{
status = NOT_OK;
sql_error( "primeBLOBcols @ UPDATE" );
}
/*******************************************************************
* Select the initial BLOB data into locators *
*******************************************************************/
if( status == OK )
{
EXEC SQL SELECT PSEG_PHOTO, BMP_PHOTO
INTO :blPSEG1 :niPSEG_PHOTO,
:blBMP1 :niBMP_PHOTO
FROM EMP_PHOTO_RESUME
WHERE EMPNO = :hvEMPNO;
if( SQLCODE != 0 )
{
status = NOT_OK;
sql_error( "primeBLOBcols @ SELECT" );
}
/*******************************************************************
* Set initial lengths of PSEG_PHOTO anf BMP_PHOTO columns *
*******************************************************************/
PSEGcolLen = PSEGinRec.length;
BMPcolLen = BMPinRec.length;
} /* end primeBLOBcols */
1260 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* record appended to the current PSEG_PHOTO locator *
*******************************************************************/
EXEC SQL SET :blPSEG2 = SUBSTR( :blPSEG1,1,LENGTH(:blPSEG1) )
|| :PSEGinRec;
if( SQLCODE != 0 )
{
status = NOT_OK;
sql_error( "buildPSEGcol @ SET LOCATOR #2" );
}
/*******************************************************************
* Regenerate the PSEG_PHOTO locator from the updated locator *
*******************************************************************/
if( status == OK )
{
EXEC SQL FREE LOCATOR :blPSEG1;
if( SQLCODE != 0 )
{
status = NOT_OK;
sql_error( "buildPSEGcol @ FREE LOCATOR #1" );
}
}
if( status == OK )
{
EXEC SQL SET :blPSEG1 = :blPSEG2;
if( SQLCODE != 0 )
{
status = NOT_OK;
sql_error( "buildPSEGcol @ SET LOCATOR #1" );
}
}
if( status == OK )
{
EXEC SQL FREE LOCATOR :blPSEG2;
if( SQLCODE != 0 )
{
status = NOT_OK;
sql_error( "buildPSEGcol @ FREE LOCATOR #2" );
}
}
/*******************************************************************
* Update length of PSEG_PHOTO column *
*******************************************************************/
if( status == OK )
PSEGcolLen = PSEGcolLen + PSEGinRec.length;
} /* end buildPSEGcol */
if( SQLCODE != 0 )
{
status = NOT_OK;
sql_error( "buildBMPcol @ SET LOCATOR #2" );
}
/*******************************************************************
* Regenerate the BMP_PHOTO locator from the updated locator *
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1261
*******************************************************************/
if( status == OK )
{
EXEC SQL FREE LOCATOR :blBMP1;
if( SQLCODE != 0 )
{
status = NOT_OK;
sql_error( "buildBMPcol @ FREE LOCATOR #1" );
}
}
if( status == OK )
{
EXEC SQL SET :blBMP1 = :blBMP2;
if( SQLCODE != 0 )
{
status = NOT_OK;
sql_error( "buildBMPcol @ SET LOCATOR #1" );
}
}
if( status == OK )
{
EXEC SQL FREE LOCATOR :blBMP2;
if( SQLCODE != 0 )
{
status = NOT_OK;
sql_error( "buildBMPcol @ FREE LOCATOR #2" );
}
}
/*******************************************************************
* Update length of BMP_PHOTO column *
*******************************************************************/
if( status == OK )
BMPcolLen = BMPcolLen + BMPinRec.length;
} /* end buildBMPcol */
if( SQLCODE != 0 )
{
status = NOT_OK;
sql_error( "updateBLOBcols @ UPDATE" );
}
} /* end updateBLOBcols */
if( SQLCODE != 0 )
{
status = NOT_OK;
sql_error( "commitWorkUnit @ COMMIT" );
}
} /* end commitWorkUnit */
1262 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* which is composed of a fully-built PSEG entry and a fully-built *
* BMP entry for the current employee. *
*********************************************************************/
{
EXEC SQL ROLLBACK;
if( SQLCODE != 0 )
{
status = NOT_OK;
sql_error( "rollbackWorkUnit @ ROLLBACK" );
}
} /* end rollbackWorkUnit */
/*******************************************************************
* print the location message *
*******************************************************************/
printf( "*****************************************************\n" );
printf( "*** ERROR: DSN8DLPL DB2 Sample Program\n" );
printf( "*** Unexpected SQLCODE encountered at location\n" );
printf( "*** %.68s\n", locmsg );
printf( "*** Error detailed below\n" );
printf( "*** Processing terminated\n" );
printf( "*****************************************************\n" );
/*******************************************************************
* format and print the SQL message *
*******************************************************************/
rc = dsntiar( &sqlca, &error_message, &lrecl );
if( rc == 0 )
for( j=0; j<TIAR_DIM; j++ )
{
for( k=0; k<TIAR_LEN; k++ )
putchar(error_message.error_text[j][k] );
putchar('\n');
}
else
{
printf( " *** ERROR: DSNTIAR could not format the message\n" );
printf( " *** SQLCODE is %d\n",SQLCODE );
printf( " *** SQLERRM is \n" );
for( j=0; j<sqlca.sqlerrml; j++ )
printf( "%c", sqlca.sqlerrmc[j] );
printf( "\n" );
}
} /* end sql_error */
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSN8DLRV
Prompts the user to choose an employee, then retrieves the resume data for that employee from
the RESUME (CLOB) column of the EMP_PHOTO_RESUME table into a CLOB locator, uses LOB locator-
handling functions to locate and break out data elements, and puts them in fields for display by ISPF.
/*********************************************************************
* Module name = DSN8DLRV (DB2 sample program) *
* *
* DESCRIPTIVE NAME = Display the resume of a specified employee *
* *
* *
* LICENSED MATERIALS - PROPERTY OF IBM *
* 5675-DB2 *
* (C) COPYRIGHT 1982, 2000 IBM CORP. ALL RIGHTS RESERVED. *
* *
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1263
* STATUS = VERSION 7 *
* *
* Function: Prompts the user to choose an employee, then retrieves *
* the resume data for that employee from the RESUME (CLOB) *
* column of the EMP_PHOTO_RESUME table into a CLOB locator,*
* uses LOB locator-handling functions to locate and break *
* out data elements, and puts them in fields for display *
* by ISPF. *
* *
* Notes: *
* Dependencies: Requires IBM C/C++ for OS/390 V1R3 or higher *
* *
* Restrictions: *
* *
* Module type: C program *
* Processor: IBM C/C++ for OS/390 V1R3 or subsequent release *
* Module size: See linkedit output *
* Attributes: Re-entrant and re-usable *
* *
* Entry Point: CEESTART (Language Environment entry point) *
* Purpose: See Function *
* Linkage: Standard MVS program invocation, no parameters *
* *
* Normal Exit: Return Code = 0000 *
* - Message: none *
* *
* Error Exit: Return Code = 0008 *
* - Message: *** ERROR: DSN8DLRV DB2 Sample Program *
* Unexpected SQLCODE encountered *
* at location xxx *
* Error detailed below *
* Processing terminated *
* (DSNTIAR-formatted message here)*
* *
* - Message: *** ERROR: DSN8DLRV DB2 Sample Program *
* No entry in the Employee Photo/ *
* Resume table for employee with *
* empno = xxxxxx *
* Processing terminated *
* *
* - Message: *** ERROR: DSN8DLRV DB2 Sample Program *
* No resume data exists in *
* the Employee Photo/Resume table *
* for the employee with empno = *
* xxxxxx. *
* Processing terminated *
* *
* *
* External References: *
* - Routines/Services: DSNTIAR, ISPF *
* - Data areas : DSNTIAR error_message *
* - Control blocks : None *
* *
* *
* Pseudocode: *
* DSN8DLRV: *
* - Call initISPFvars to establish ISPF variable sharing *
* - Do until the user indicates termination *
* - Call clearISPFvars to reset the ISPF shared variables *
* - Call getEmplNum to request an employee id *
* - Call getEmplResume to retrieve the resume *
* - Call formatEmplResume to populate the ISPF display panel *
* - Call showEmplResume to display the resume *
* - Call freeISPFvars to terminate ISPF variable sharing *
* End DSN8DLRV *
* *
* initISPFvars: *
* - Establish ISPF variable sharing *
* End initISPFvars *
* *
* clearISPFvars: *
* - Set ISPF vars to blank if character type or 0 if numeric *
* End clearISPFvars *
* *
* getEmplNum: *
* - prompt user to select an employee whose resume is to be viewed *
* End getEmplNum *
* *
* getEmplResume: *
* - Fetch the specified employee's resume from DB2 using a CLOB *
* locator *
* End getEmplResume *
1264 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* *
* formatEmplResume: *
* - call getPersonalData to extract personal data from the resume *
* - call getDepartmentData to extract department data *
* - call getEducationData to extract education data *
* - call getWorkHistoryData to extract work history data *
* End formatEmplResume *
* *
* showEmplResume: *
* - Display the ISPF panel with the specified employee's resume *
* End showEmplResume *
* *
* freeISPFvars: *
* - Terminate variable sharing with ISPF *
* End freeISPFvars *
* *
* getPersonalData: *
* - Parse the employee's name, address, home telephone no., *
* birthdate, sex, marital status, height, and weight into ISPF *
* display variables *
* End getPersonalData *
* *
* getDepartmentData: *
* - Parse the employee's department number, manager, job position, *
* work telephone no., and hire date into ISPF display variables. *
* End getDepartmentData *
* *
* getEducationData: *
* - Parse the employee's degree dates, descriptions, and schools *
* into ISPF display variables. *
* End getEducationData *
* *
* getWorkHistoryData: *
* - Parse the employee's job dates, titles, and descriptions into *
* ISPF display variables. *
* End getWorkHistoryData *
* *
* sql_error: *
* - call DSNTIAR to format an unexpected SQLCODE. *
* End sql_error *
* *
**********************************************************************
* Assumptions: *
* (1) Each employee has exactly 2 entries under "Education" *
* (2) Each employee has exactly 3 entries under "Work History" *
* (3) Each job description consists of a single sentence and that *
* sentence ends with a period and that period is the only *
* period in the sentence. *
*********************************************************************/
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1265
} error_message = {TIAR_DIM * (TIAR_LEN)};
1266 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
/************************* Global Functions *************************/
int main( void ); /* main logic */
void initISPFvars( void ); /* establish ISPF vars */
void clearISPFvars( void ); /* blank/zero ISPF disp vars */
void getEmplNum( void ); /* prompt for employee ser no */
void getEmplResume( void ); /* get resume from database */
void formatEmplResume( void ); /* build display panel */
void getPersonalData( void ); /* get personal data from res */
void getDepartmentData( void ); /* get dept data from resume */
void getEducationData( void ); /* get educ data from resume */
void getWorkHistoryData( void ); /* get job hist from resume */
void showEmplResume( void ); /* display the ISPF panel */
void freeISPFvars( void ); /* drop ISPF vars */
void sql_error( char *locmsg ); /* generate SQL messages */
/*********************************************************************
**************************** main routine ****************************
*********************************************************************/
int main( void )
{
/*******************************************************************
* Establish variable sharing with ISPF *
*******************************************************************/
initISPFvars();
/*******************************************************************
* Display employee resumes until user indicates completion *
*******************************************************************/
keepViewing = YES;
while( keepViewing == YES )
{
clearISPFvars();
/***************************************************************
* prompt user to select employee whose resume is to be viewed *
***************************************************************/
getEmplNum();
/*******************************************************************
* Terminate variable sharing with ISPF *
*******************************************************************/
freeISPFvars();
} /* end main */
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1267
ISPFrc = isplink( VDEFINE, "D8EMADR2", D8EMADR2, CHAR, 24 );
ISPFrc = isplink( VDEFINE, "D8MGRNAM", D8MGRNAM, CHAR, 21 );
ISPFrc = isplink( VDEFINE, "D8EMADR3", D8EMADR3, CHAR, 14 );
ISPFrc = isplink( VDEFINE, "D8EMPOSN", D8EMPOSN, CHAR, 21 );
ISPFrc = isplink( VDEFINE, "D8EMBORN", D8EMBORN, CHAR, 18 );
ISPFrc = isplink( VDEFINE, "D8EMPHON", D8EMPHON, CHAR, 14 );
ISPFrc = isplink( VDEFINE, "D8EMSEX ", D8EMSEX , CHAR, 6 );
ISPFrc = isplink( VDEFINE, "D8EMHIRE", D8EMHIRE, CHAR, 10 );
ISPFrc = isplink( VDEFINE, "D8EMHGT ", D8EMHGT , CHAR, 5 );
ISPFrc = isplink( VDEFINE, "D8EMWGT ", D8EMWGT , CHAR, 8 );
ISPFrc = isplink( VDEFINE, "D8EMPMST", D8EMPMST, CHAR, 8 );
ISPFrc = isplink( VDEFINE, "D8EMEDY1", D8EMEDY1, CHAR, 4 );
ISPFrc = isplink( VDEFINE, "D8EMEDD1", D8EMEDD1, CHAR, 34 );
ISPFrc = isplink( VDEFINE, "D8EMEDY2", D8EMEDY2, CHAR, 4 );
ISPFrc = isplink( VDEFINE, "D8EMEDD2", D8EMEDD2, CHAR, 34 );
ISPFrc = isplink( VDEFINE, "D8EMEDI1", D8EMEDI1, CHAR, 34 );
ISPFrc = isplink( VDEFINE, "D8EMEDI2", D8EMEDI2, CHAR, 34 );
ISPFrc = isplink( VDEFINE, "D8EMWHD1", D8EMWHD1, CHAR, 16 );
ISPFrc = isplink( VDEFINE, "D8EMWHJ1", D8EMWHJ1, CHAR, 62 );
ISPFrc = isplink( VDEFINE, "D8EMWHT1", D8EMWHT1, CHAR, 62 );
ISPFrc = isplink( VDEFINE, "D8EMWHD2", D8EMWHD2, CHAR, 16 );
ISPFrc = isplink( VDEFINE, "D8EMWHJ2", D8EMWHJ2, CHAR, 62 );
ISPFrc = isplink( VDEFINE, "D8EMWHT2", D8EMWHT2, CHAR, 62 );
ISPFrc = isplink( VDEFINE, "D8EMWHD3", D8EMWHD3, CHAR, 16 );
ISPFrc = isplink( VDEFINE, "D8EMWHJ3", D8EMWHJ3, CHAR, 62 );
ISPFrc = isplink( VDEFINE, "D8EMWHT3", D8EMWHT3, CHAR, 62 );
} /* end initISPFvars */
/*******************************************************************
* Save off the value of the ISPF shared variable *
1268 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
*******************************************************************/
strcpy( hvEMPNO,D8EMNUMB );
} /* end getEmplNum */
} /* end getEmplResume */
/*******************************************************************
* Get the employee's department no., manager, and other dept data *
*******************************************************************/
if( status == OK )
getDepartmentData();
/*******************************************************************
* Get the employee's education data *
*******************************************************************/
if( status == OK )
getEducationData();
/*******************************************************************
* Get the employee's employment history *
*******************************************************************/
if( status == OK )
getWorkHistoryData();
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1269
/*******************************************************************
* Free the CLOB locator for the resume *
*******************************************************************/
if( status == OK )
{
EXEC SQL FREE LOCATOR :clRESUME;
if( SQLCODE != 0 )
{
status = NOT_OK;
sql_error( "formatEmplResume @ FREE LOCATOR" );
}
}
} /* end formatEmplResume */
1270 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
endField - begField );
}
/*******************************************************************
* Get the employee's city, state, and zipcode *
*******************************************************************/
if( status == OK )
{
begField = endField + 22; /* set loc to city/st/zip dat */
endField /* find end of ciy/st/zip */
= strstr( phvRESUME," Phone: " );
strncpy( D8EMADR2, /* get data from in between */
begField,
endField - begField );
}
/*******************************************************************
* Get the employee's home telephone number *
*******************************************************************/
if( status == OK )
{
begField = endField + 22; /* set loc to home phone data */
endField /* find end of home phone no. */
= strstr( phvRESUME," Birthdate: " );
strncpy( D8EMADR3, /* get phone# from in between */
begField,
endField - begField );
}
/*******************************************************************
* Get the employee's birthdate *
*******************************************************************/
if( status == OK )
{
begField = endField + 22; /* set loc to birthdate data */
endField /* find end of birthdate data */
= strstr( phvRESUME," Sex: " );
strncpy( D8EMBORN, /* get birthdate from in betw */
begField,
endField - begField );
}
/*******************************************************************
* Get the employee's sex *
*******************************************************************/
if( status == OK )
{
begField = endField + 22; /* set loc to sex data */
endField /* find end of sex data */
= strstr( phvRESUME," Marital Status: " );
strncpy( D8EMSEX, /* get sex data from in betw */
begField,
endField - begField );
}
/*******************************************************************
* Get the employee's marital status *
*******************************************************************/
if( status == OK )
{
begField = endField + 22; /* set loc to marital status */
endField /* find end of marital stat. */
= strstr( phvRESUME," Height: " );
strncpy( D8EMPMST, /* get mar stat from in betw */
begField,
endField - begField );
}
/*******************************************************************
* Get the employee's height *
*******************************************************************/
if( status == OK )
{
begField = endField + 22; /* set loc to height data */
endField /* find end of height data */
= strstr( phvRESUME," Weight: " );
strncpy( D8EMHGT, /* get height from in between */
begField,
endField - begField );
}
/*******************************************************************
* Get the employee's weight *
*******************************************************************/
if( status == OK )
{
begField = endField + 22; /* set loc to weight data */
strcpy( D8EMWGT, /* weight is at end of string */
begField );
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1271
}
} /* end getPersonalData */
1272 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
strncpy( D8EMPHON, /* get work ph# from in betw */
begField,
endField - begField );
}
/*******************************************************************
* Get the employee's hire date *
*******************************************************************/
if( status == OK )
{
begField = endField + 22; /* set loc to hire date data */
strcpy( D8EMHIRE, /* hire data is at end of str */
begField );
}
} /* end getDepartmentData */
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1273
*******************************************************************/
if( status == OK )
{
begField = endField + 3; /* set loc to grad year data */
endField /* find end of grad year data */
= strstr( phvRESUME," " );
strncpy( D8EMEDY2, /* get hire data from in betw */
begField,
endField - begField );
begField = endField + 16; /* set loc to degree descript */
endField /* find end of deg descr data */
= strstr( phvRESUME," " );
strncpy( D8EMEDD2, /* get deg descr from in betw */
begField,
endField - begField );
}
/*******************************************************************
* Get institution that granted employee's previous degree *
*******************************************************************/
if( status == OK )
{
begField = endField + 22; /* set loc to inst name data */
phvRESUME = begField; /* reset starting point */
strcpy( D8EMEDI2, /* inst name is at end of str */
begField );
}
} /* end getEducationData */
1274 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
if( status == OK )
{
begField = endField + 22; /* set loc to job 1 descr. */
phvRESUME = begField; /* reset starting point */
endField /* find end of job 1 descr. */
= strstr( phvRESUME,". " );
if( endField - begField < 62 ) /* job 1 descr has 1 part */
strncpy( D8EMWHJ1, /* get job 1 descr from betw */
begField,
endField - begField );
else /* job 1 descr has 2 parts */
{
endField /* find 1st part of job descr */
= strstr( phvRESUME," " );
strncpy( D8EMWHJ1, /* get job 1 descr from betw */
begField,
endField - begField );
begField = endField + 22; /* set loc to 2nd part job des*/
endField /* find end of job 1 descr. */
= strstr( phvRESUME,". " );
strncat( D8EMWHJ1, /* get rest of job 1 descr. */
begField-1,
endField - (begField-1) );
}
}
/*******************************************************************
* Get dates and title of employee's previous job *
*******************************************************************/
if( status == OK )
{
begField = endField + 4; /* set loc to job 2 dates */
phvRESUME = begField; /* reset starting point */
strncpy( D8EMWHD2, /* job 2 dates, next 15 bytes */
begField,
15 );
begField = begField + 20; /* set loc to job 2 title */
endField /* find end of job 2 title */
= strstr( phvRESUME," " );
strncpy( D8EMWHT2, /* get job 2 title from betw */
begField,
endField - begField );
}
/*******************************************************************
* Get description of employee's previous job *
*******************************************************************/
if( status == OK )
{
begField = endField + 22; /* set loc to job 2 descr. */
phvRESUME = begField; /* reset starting point */
endField /* find end of job 2 descr. */
= strstr( phvRESUME,". " );
if( endField - begField < 62 ) /* job 2 descr has 1 part */
strncpy( D8EMWHJ2, /* get job 2 title from betw */
begField,
endField - begField );
else /* job 2 descr has 2 parts */
{
endField /* find 1st part of job descr */
= strstr( phvRESUME," " );
strncpy( D8EMWHJ2, /* get job 2 descr from betw */
begField,
endField - begField );
begField = endField + 22; /* set loc to 2nd part job des*/
endField /* find end of job 2 descr. */
= strstr( phvRESUME,". " );
strncat( D8EMWHJ2, /* get rest of job 2 descr. */
begField-1,
endField - (begField-1) );
}
}
/*******************************************************************
* Get dates and title of employee's other previous job *
*******************************************************************/
if( status == OK )
{
begField = endField + 4; /* set loc to job 3 dates */
phvRESUME = begField; /* reset starting point */
strncpy( D8EMWHD3, /* job 3 dates, next 15 bytes */
begField,
15 );
begField = begField + 20; /* set loc to job 3 title */
endField /* find end of job 3 title */
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1275
= strstr( phvRESUME," " );
strncpy( D8EMWHT3, /* get job 3 title from betw */
begField,
endField - begField );
}
/*******************************************************************
* Get description of employee's other previous job *
*******************************************************************/
if( status == OK )
{
begField = endField + 22; /* set loc to job 3 descr. */
phvRESUME = begField; /* reset starting point */
begField = phvRESUME; /* reset starting point */
endField /* find end of job 3 descr. */
= strstr( phvRESUME,"." );
if( endField - begField < 62 ) /* job 3 descr has 1 part */
strncpy( D8EMWHJ3, /* get job 3 title from betw */
begField,
endField - begField );
else /* job 3 descr has 2 parts */
{
endField /* find 1st part of job descr */
= strstr( phvRESUME," " );
strncpy( D8EMWHJ3, /* get job 3 descr from betw */
begField,
endField - begField );
begField = endField + 22; /* set loc to 2nd part job des*/
endField /* find end of job 3 descr. */
= strstr( phvRESUME,". " );
strncat( D8EMWHJ3, /* get rest of job 3 descr. */
begField-1,
endField - (begField-1) );
}
}
} /* end getWorkHistoryData */
} /* end showEmplResume */
} /* end freeISPFvars */
/*******************************************************************
* print the location message *
*******************************************************************/
printf( "*****************************************************\n" );
printf( "*** ERROR: DSN8DLRV DB2 Sample Program\n" );
printf( "*** Unexpected SQLCODE encountered at location\n" );
printf( "*** %.68s\n", locmsg );
printf( "*** Error detailed below\n" );
printf( "*** Processing terminated\n" );
printf( "*****************************************************\n" );
/*******************************************************************
1276 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* format and print the SQL message *
*******************************************************************/
rc = dsntiar( &sqlca, &error_message, &lrecl );
if( rc == 0 )
for( j=0; j<TIAR_DIM; j++ )
{
for( k=0; k<TIAR_LEN; k++ )
putchar(error_message.error_text[j][k] );
putchar('\n');
}
else
{
printf( " *** ERROR: DSNTIAR could not format the message\n" );
printf( " *** SQLCODE is %d\n",SQLCODE );
printf( " *** SQLERRM is \n" );
for( j=0; j<sqlca.sqlerrml; j++ )
printf( "%c", sqlca.sqlerrmc[j] );
printf( "\n" );
}
} /* end sql_error */
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSN8DLPV
Prompts the user to choose an employee, then retrieves the PSEG photo image for that employee from
the PSEG_- PHOTO column of the EMP_PHOTO_RESUME table and passes it to GDDM for formatting and
display.
/*********************************************************************
* Module name = DSN8DLPV (DB2 sample program) *
* *
* DESCRIPTIVE NAME = Display PSEG photo image of a specified employee*
* *
* *
* LICENSED MATERIALS - PROPERTY OF IBM *
* 5655-DB2 *
* (C) COPYRIGHT 1997 IBM CORP. ALL RIGHTS RESERVED. *
* *
* STATUS = VERSION 6 *
* *
* Function: Prompts the user to choose an employee, then retrieves *
* the PSEG photo image for that employee from the PSEG_- *
* PHOTO column of the EMP_PHOTO_RESUME table and passes it *
* to GDDM for formatting and display. *
* *
* Notes: *
* Dependencies: Requires IBM C/C++ for OS/390 V1R3 or higher *
* Requires IBM Graphical Data Display Manager (GDDM) *
* V3R1 or higher *
* *
* Restrictions: *
* *
* Module type: C program *
* Processor: IBM C/C++ for OS/390 V1R3 or subsequent release *
* Module size: See linkedit output *
* Attributes: Re-entrant and re-usable *
* *
* Entry Point: CEESTART (Language Environment entry point) *
* Purpose: See Function *
* Linkage: Standard MVS program invocation, no parameters *
* *
* Normal Exit: Return Code = 0000 *
* - Message: none *
* *
* Error Exit: Return Code = 0008 *
* - Message: *** ERROR: DSN8DLPV DB2 Sample Program *
* Unexpected SQLCODE encountered *
* at location xxx *
* Error detailed below *
* Processing terminated *
* (DSNTIAR-formatted message here)*
* *
* - Message: *** ERROR: DSN8DLPV DB2 Sample Program *
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1277
* No entry in the Employee Photo/ *
* Resume table for employee with *
* empno = xxxxxx *
* Processing terminated *
* *
* - Message: *** ERROR: DSN8DLPV DB2 Sample Program *
* No PSEG photo image exists in *
* the Employee Photo/Resume table *
* for the employee with empno = *
* xxxxxx. *
* Processing terminated *
* *
* External References: *
* - Routines/Services: DSNTIAR, GDDM, ISPF *
* - Data areas : DSNTIAR error_message *
* - Control blocks : None *
* *
* *
* Pseudocode: *
* DSN8DLPV: *
* - Do until the user indicates termination *
* - Call getEmplNum to request an employee id *
* - Call getEmplPhoto to retrieve the PSEG photo image *
* - Call showEmplPhoto to display the photo *
* End DSN8DLRV *
* *
* getEmplNum: *
* - prompt user to select an employee whose photo is to be viewed *
* *
* getEmplPhoto: *
* - Fetch the specified employee's PSEG photo image from DB2 *
* - call sql_error for unexpected SQLCODEs *
* End getEmplPhoto: *
* *
* showEmplPhoto: *
* - Use GDDM calls to format and display the PSEG photo image *
* *
* sql_error: *
* - call DSNTIAR to format the unexpected SQLCODE. *
* *
*********************************************************************/
1278 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
} error_message = {TIAR_DIM * (TIAR_LEN)};
/********************************************************************/
/*************************** main routine ***************************/
/********************************************************************/
int main( void )
{
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1279
/*******************************************************************
* Display employee photos until user indicates completion *
*******************************************************************/
keepViewing = YES;
while( keepViewing == YES )
{
/***************************************************************
* prompt user to select an employee whose photo is to be viewed*
***************************************************************/
getEmplNum();
} /* end main */
/*******************************************************************
* Display the prompt panel *
*******************************************************************/
ISPFrc = isplink( DISPLAY,"DSN8SSE " );
if( ISPFrc != 0 )
keepViewing = NO;
/*******************************************************************
* Save off the value of the ISPF shared variable *
*******************************************************************/
strcpy( hvEMPNO,D8EMNUMB );
/*******************************************************************
* And release it *
*******************************************************************/
ISPFrc = isplink( VRESET );
} /* end getEmplNum */
if( SQLCODE == 0 )
hvPSEG_PHOTO.data[hvPSEG_PHOTO.length] = '\n';
else if( SQLCODE == 100 )
{
1280 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
status = NOT_OK;
printf( "*************************************************\n" );
printf( "*** ERROR: DSN8DLPV DB2 Sample Program\n" );
printf( "*** No entry in the Employee Photo/Resume\n" );
printf( "*** table for employee with empno = %s\n",
hvEMPNO );
printf( "*** Processing terminated\n" );
printf( "*************************************************\n" );
}
else if( SQLCODE == -305 )
{
status = NOT_OK;
printf( "*************************************************\n" );
printf( "*** ERROR: DSN8DLPV DB2 Sample Program\n" );
printf( "*** No PSEG photo image exists in the\n" );
printf( "*** Employee Photo/Resume table for the\n" );
printf( "*** employee with empno = %s\n",
hvEMPNO );
printf( "*** Processing terminated\n" );
printf( "*************************************************\n" );
}
else
{
status = NOT_OK;
sql_error( "getEmplPhoto @1" );
}
} /* end getEmplPhoto */
/*******************************************************************
* Initialize GDDM *
*******************************************************************/
fsinit( AAB.AABstr ); /* GDDM anchor block */
/*******************************************************************
* Obtain a GDDM application image id *
*******************************************************************/
imagid( AAB.AABstr, /* GDDM anchor block */
&appl_id ); /* application id for image */
/*******************************************************************
* Create a GDDM application image to receive the employee photo *
*******************************************************************/
imacrt( AAB.AABstr, /* GDDM anchor block */
appl_id, /* target: application image */
ih_pixels, /* horiz size in # of pixels */
iv_pixels, /* vert size in # of pixels */
iim_type, /* pixel type (1=bi-level) */
ires_type, /* defined resolution indic. */
ires_unit, /* resolut'n units (0=inches) */
ih_res, /* horizontal resolution */
iv_res ); /* vertical resolution */
/*******************************************************************
* Set up conversion of photo from PSEG format to GDDM format *
*******************************************************************/
imapts( AAB.AABstr, /* GDDM anchor block */
appl_id, /* target: application image */
0, /* GDDM proj. id (0=identity) */
PSEGformat, /* source format (PSEG) */
PSEGcompression ); /* source compression (3800) */
/*******************************************************************
* Perform conversion *
*******************************************************************/
imapt( AAB.AABstr, /* GDDM anchor block */
appl_id, /* target: application image */
hvPSEG_PHOTO.length, /* source length */
hvPSEG_PHOTO.data ); /* source: employee PSEG photo*/
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1281
/*******************************************************************
* Terminate conversion *
*******************************************************************/
imapte( AAB.AABstr, /* GDDM anchor block */
appl_id ); /* target: application image */
/*******************************************************************
* Transfer the GDDM application image to the display *
*******************************************************************/
imxfer( AAB.AABstr, /* GDDM anchor block */
appl_id, /* source: application image */
0, /* target: 0=display */
0 ); /* GDDM proj. id (0=identity) */
/*******************************************************************
* Disable user updates to the image on the display *
*******************************************************************/
fsenab( AAB.AABstr, /* GDDM anchor block */
1, /* type of input (1=alphanum) */
0 ); /* type of control (0=disable)*/
/*******************************************************************
* Display the image until attn or interrupt key depressed *
*******************************************************************/
asread( AAB.AABstr, /* GDDM anchor block */
&attype, /* type of attn/interrupt key */
&attval, /* value of attn/interrupt key*/
&count ); /* number of fields modified */
/*******************************************************************
* Delete the GDDM application image *
*******************************************************************/
imadel( AAB.AABstr, /* GDDM anchor block */
appl_id ); /* target: application image */
/*******************************************************************
* Terminate GDDM *
*******************************************************************/
fsterm( AAB.AABstr ); /* GDDM anchor block */
} /* end showEmplPhoto */
/*******************************************************************
* print the location message *
*******************************************************************/
printf( "*****************************************************\n" );
printf( "*** ERROR: DSN8DLPV DB2 Sample Program\n" );
printf( "*** Unexpected SQLCODE encountered at location\n" );
printf( "*** %.68s\n", locmsg );
printf( "*** Error detailed below\n" );
printf( "*** Processing terminated\n" );
printf( "*****************************************************\n" );
/*******************************************************************
* format and print the SQL message *
*******************************************************************/
rc = dsntiar( &sqlca, &error_message, &lrecl );
if( rc == 0 )
for( j=0; j<TIAR_DIM; j++ )
{
for( k=0; k<TIAR_LEN; k++ )
putchar(error_message.error_text[j][k] );
putchar('\n');
1282 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
}
else
{
printf( " *** ERROR: DSNTIAR could not format the message\n" );
printf( " *** SQLCODE is %d\n",SQLCODE );
printf( " *** SQLERRM is \n" );
for( j=0; j<sqlca.sqlerrml; j++ )
printf( "%c", sqlca.sqlerrmc[j] );
printf( "\n" );
}
} /* end sql_error */
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSNTEJ2C
THIS JCL PERFORMS THE PHASE 2 COBOL SETUP FOR THE SAMPLE APPLICATIONS.
//*********************************************************************
//* NAME = DSNTEJ2C
//*
//* DESCRIPTIVE NAME = DB2 SAMPLE APPLICATION
//* PHASE 2
//* COBOL
//*
//* LICENSED MATERIALS - PROPERTY OF IBM
//* 5650-DB2
//* (C) COPYRIGHT 1982, 2016 IBM CORP. ALL RIGHTS RESERVED.
//*
//* STATUS = VERSION 12
//*
//* FUNCTION = THIS JCL PERFORMS THE PHASE 2 COBOL SETUP FOR THE
//* SAMPLE APPLICATIONS. IT PREPARES AND EXECUTES
//* COBOL BATCH PROGRAMS.
//*
//* THIS JOB IS RUN AFTER PHASE 1.
//*
//*
//* CHANGE ACTIVITY =
//* 08/18/2014 Single-phase migration s21938_inst1 s21938
//*
//*********************************************************************
//*
//JOBLIB DD DISP=SHR,DSN=DSN!!0.SDSNEXIT
// DD DISP=SHR,DSN=DSN!!0.SDSNLOAD
// DD DISP=SHR,DSN=CEE.V!R!M!.SCEERUN
//*
//* STEP 1: CREATE COPY FILE TABLE DESCRIPTIONS (DCLGEN)
//PH02CS01 EXEC PGM=IKJEFT01,DYNAMNBR=20
//SYSTSPRT DD SYSOUT=*,DCB=(RECFM=F,LRECL=200,BLKSIZE=200)
//SYSUDUMP DD SYSOUT=*
//SYSTSIN DD *
DELETE 'DSN!!0.SRCLIB.DATA(DSN8MCDP)'
DELETE 'DSN!!0.SRCLIB.DATA(DSN8MCEM)'
DELETE 'DSN!!0.SRCLIB.DATA(DSN8MCDM)'
DELETE 'DSN!!0.SRCLIB.DATA(DSN8MCAD)'
DELETE 'DSN!!0.SRCLIB.DATA(DSN8MCA2)'
DELETE 'DSN!!0.SRCLIB.DATA(DSN8MCCS)'
DELETE 'DSN!!0.SRCLIB.DATA(DSN8MCOV)'
DELETE 'DSN!!0.SRCLIB.DATA(DSN8MCDT)'
DELETE 'DSN!!0.SRCLIB.DATA(DSN8MCED)'
DSN SYSTEM(DSN)
DCLGEN TABLE(VDEPT) +
OWNER(DSN8!!0) +
LIBRARY('DSN!!0.SRCLIB.DATA(DSN8MCDP)') +
ACTION(ADD) APOST +
LANGUAGE(IBMCOB) +
STRUCTURE(PDEPT)
DCLGEN TABLE(VEMP) +
OWNER(DSN8!!0) +
LIBRARY('DSN!!0.SRCLIB.DATA(DSN8MCEM)') +
ACTION(ADD) APOST +
LANGUAGE(IBMCOB) +
STRUCTURE(PEMP)
DCLGEN TABLE(VDEPMG1) +
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1283
OWNER(DSN8!!0) +
LIBRARY('DSN!!0.SRCLIB.DATA(DSN8MCDM)') +
ACTION(ADD) APOST +
LANGUAGE(IBMCOB) +
STRUCTURE(PDEPMGR)
DCLGEN TABLE(VASTRDE1) +
OWNER(DSN8!!0) +
LIBRARY('DSN!!0.SRCLIB.DATA(DSN8MCAD)') +
ACTION(ADD) APOST +
LANGUAGE(IBMCOB) +
STRUCTURE(PASTRDET)
DCLGEN TABLE(VASTRDE2) +
OWNER(DSN8!!0) +
LIBRARY('DSN!!0.SRCLIB.DATA(DSN8MCA2)') +
ACTION(ADD) APOST +
LANGUAGE(IBMCOB) +
NAMES(ADE2) +
STRUCTURE(PASTRDE2)
DCLGEN TABLE(VCONA) +
OWNER(DSN8!!0) +
LIBRARY('DSN!!0.SRCLIB.DATA(DSN8MCCS)') +
ACTION(ADD) APOST +
LANGUAGE(IBMCOB) +
STRUCTURE(PCONA)
DCLGEN TABLE(VOPTVAL) +
OWNER(DSN8!!0) +
LIBRARY('DSN!!0.SRCLIB.DATA(DSN8MCOV)') +
ACTION(ADD) APOST +
LANGUAGE(IBMCOB) +
STRUCTURE(POPTVAL)
DCLGEN TABLE(VDSPTXT) +
OWNER(DSN8!!0) +
LIBRARY('DSN!!0.SRCLIB.DATA(DSN8MCDT)') +
ACTION(ADD) APOST +
LANGUAGE(IBMCOB) +
STRUCTURE(PDSPTXT)
DCLGEN TABLE(VEMPDPT1) +
OWNER(DSN8!!0) +
LIBRARY('DSN!!0.SRCLIB.DATA(DSN8MCED)') +
ACTION(ADD) APOST +
LANGUAGE(IBMCOB) +
STRUCTURE(PEMPDPT1)
END
//*
//* STEP 2: PREPARE ERROR MESSAGE ROUTINE
//PH02CS02 EXEC DSNHICOB,MEM=DSN8MCG,
// COND=(4,LT),
// PARM.PC=('HOST(IBMCOB)',APOST,APOSTSQL,SOURCE,
// NOXREF,'SQL(DB2)','DEC(31)'),
// PARM.COB=(NOSEQUENCE,QUOTE,RENT,'PGMNAME(LONGUPPER)'),
// PARM.LKED='LIST,XREF,MAP,RENT'
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8MCG),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8MCG),
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8MCG),
// DISP=SHR
//*
//* STEP 3: PREPARE COBOL PHONE PROGRAM
//PH02CS03 EXEC DSNHICOB,MEM=DSN8BC3,
// COND=(4,LT),
// PARM.PC=('HOST(IBMCOB)',APOST,APOSTSQL,SOURCE,
// NOXREF,'SQL(DB2)','DEC(31)'),
// PARM.COB=(NOSEQUENCE,QUOTE,RENT,'PGMNAME(LONGUPPER)')
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8BC3),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8BC3),
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8BC3),
// DISP=SHR
//LKED.RUNLIB DD DSN=DSN!!0.RUNLIB.LOAD,
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNELI)
INCLUDE RUNLIB(DSN8MCG)
//*
//* STEP 4: BIND AND RUN PROGRAMS
//PH02CS04 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
1284 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
//DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA,DISP=SHR
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//REPORT DD SYSOUT=*
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
GRANT BIND, EXECUTE ON PLAN DSN8BH!!
TO PUBLIC;
//SYSTSIN DD *
DSN SYSTEM(DSN)
BIND PACKAGE(DSN8BH!!) MEMBER(DSN8BC3) APPLCOMPAT(V!!R1) +
ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
BIND PLAN(DSN8BH!!) PKLIST(DSN8BH!!.*) +
ACTION(REPLACE) RETAIN +
ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
RUN PROGRAM(DSNTIAD) PLAN(DSNTIA!!) -
LIB('DSN!!0.RUNLIB.LOAD')
RUN PROGRAM(DSN8BC3) PLAN(DSN8BH!!) -
LIB('DSN!!0.RUNLIB.LOAD')
END
//CARDIN DD *
L*
LJO%
L%SON
LSMITH
LBROWN ALAN
LBROWN DAVID
U 0002304265
//*
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSNTEJ2D
THIS JCL PERFORMS THE PHASE 2 C LANGUAGE SETUP FOR THE SAMPLE APPLICATIONS.
//*********************************************************************
//* NAME = DSNTEJ2D
//*
//* DESCRIPTIVE NAME = DB2 SAMPLE APPLICATION
//* PHASE 2
//* C
//*
//* LICENSED MATERIALS - PROPERTY OF IBM
//* 5650-DB2
//* (C) COPYRIGHT 1982, 2016 IBM CORP. ALL RIGHTS RESERVED.
//*
//* STATUS = VERSION 12
//*
//* FUNCTION = THIS JCL PERFORMS THE PHASE 2 C LANGUAGE SETUP FOR
//* THE SAMPLE APPLICATIONS. IT PREPARES AND EXECUTES
//* C BATCH PROGRAMS.
//*
//* NOTES = ENSURE THAT LINE NUMBER SEQUENCING IS SET 'ON' IF
//* THIS JOB IS SUBMITTED FROM AN ISPF EDIT SESSION
//*
//* THIS JOB IS RUN AFTER PHASE 1.
//*
//* CHANGE ACTIVITY =
//* 08/18/2014 Single-phase migration s21938_inst1 s21938
//*
//*********************************************************************
//*
//JOBLIB DD DSN=DSN!!0.SDSNLOAD,DISP=SHR
// DD DSN=CEE.V!R!M!.SCEERUN,DISP=SHR
//*
//* STEP 1 : PREPARE ERROR MESSAGE ROUTINE
//PH02DS01 EXEC DSNHC,MEM=DSN8MDG,
// PARM.PC=('HOST(C),CCSID(1047),MARGINS(1,72),STDSQL(NO)',
// SOURCE,XREF),
// PARM.C='SOURCE XREF MARGINS(1,72) OPTFILE(DD:CCOPTS)',
// PARM.LKED='NCAL,MAP,AMODE=31,RMODE=ANY'
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8MDG),
// DISP=SHR
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1285
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8MDG),
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8MDG),
// DISP=SHR
//*
//* STEP 2 : PREPARE C PHONE PROGRAM
//PH02DS02 EXEC DSNHC,MEM=DSN8BD3,
// COND=(4,LT),
// PARM.PC=('HOST(C),CCSID(1047),MARGINS(1,72),STDSQL(NO)',
// SOURCE,XREF),
// PARM.C='SOURCE LIST MARGINS(1,72) OPTFILE(DD:CCOPTS)',
// PARM.LKED='AMODE=31,RMODE=ANY,MAP'
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8BD3),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8BD3),
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8BD3),
// DISP=SHR
//LKED.RUNLIB DD DSN=DSN!!0.RUNLIB.LOAD,
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNELI)
INCLUDE RUNLIB(DSN8MDG)
//*
//* STEP 3 : BIND AND RUN PROGRAMS
//PH02DS03 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//DBRMLIB DD DISP=SHR,DSN=DSN!!0.DBRMLIB.DATA
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//CEEDUMP DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//REPORT DD SYSOUT=*
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
GRANT BIND, EXECUTE ON PLAN DSN8BD!!
TO PUBLIC;
//SYSTSIN DD *
DSN SYSTEM(DSN)
BIND PACKAGE(DSN8BD!!) MEMBER(DSN8BD3) APPLCOMPAT(V!!R1) +
ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
BIND PLAN(DSN8BD!!) PKLIST(DSN8BD!!.*) +
ACTION(REPLACE) RETAIN +
ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
RUN PROGRAM(DSNTIAD) PLAN(DSNTIA!!) -
LIB('DSN!!0.RUNLIB.LOAD')
RUN PROGRAM(DSN8BD3) PLAN(DSN8BD!!) -
LIB('DSN!!0.RUNLIB.LOAD')
END
//CARDIN DD *
L*
LJO%
L%SON
LSMITH
LBROWN ALAN
LBROWN DAVID
U 0002304265
//*
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSNTEJ2E
THIS JCL PERFORMS THE PHASE 2 C++ LANGUAGE SETUP FOR THE SAMPLE APPLICATIONS.
//*********************************************************************
//* NAME = DSNTEJ2E
//*
//* DESCRIPTIVE NAME = DB2 SAMPLE APPLICATION
//* PHASE 2
//* C++
//*
1286 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
//* Licensed Materials - Property of IBM
//* 5650-DB2
//* (C) COPYRIGHT 1982, 2016 IBM Corp. All Rights Reserved.
//*
//* STATUS = Version 12
//*
//* FUNCTION = THIS JCL PERFORMS THE PHASE 2 C++ LANGUAGE SETUP FOR
//* THE SAMPLE APPLICATIONS. IT PREPARES AND EXECUTES
//* C++ BATCH PROGRAMS.
//*
//* NOTES = ENSURE THAT LINE NUMBER SEQUENCING IS SET 'ON' IF
//* THIS JOB IS SUBMITTED FROM AN ISPF EDIT SESSION
//*
//* THIS JOB IS RUN AFTER PHASE 1.
//*
//* CHANGE ACTIVITY =
//* 10/16/2013 Don't use prelinker by default PI13612 DM1812
//* 08/18/2014 Single-phase migration s21938_inst1 s21938
//*
//*********************************************************************
//*
//JOBLIB DD DSN=DSN!!0.SDSNLOAD,DISP=SHR
// DD DSN=CEE.V!R!M!.SCEERUN,DISP=SHR
//*
//* STEP 1 : PREPARE ERROR MESSAGE ROUTINE
//PH02ES01 EXEC DSNHC,MEM=DSN8MDG,
// PARM.PC=('HOST(C),CCSID(1047),MARGINS(1,72),STDSQL(NO)',
// SOURCE,XREF),
// PARM.C='SOURCE XREF MARGINS(1,72) OPTFILE(DD:CCOPTS)',
// PARM.LKED='NCAL,MAP,AMODE=31,RMODE=ANY'
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8MDG),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8MDG),
// DISP=SHR
//C.SYSLIN DD DSN=&&LOADSET2,
// DISP=(MOD,PASS),
// UNIT=SYSDA,SPACE=(32000,(30,30)),
// DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200)
//LKED.SYSLIN DD DSN=&&LOADSET2,DISP=(OLD,PASS)
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8MDG),
// DISP=SHR
//*
//* STEP 2 : PREPARE CLASSES USED BY C++ PHONE PROGRAM
//PH02ES02 EXEC DSNHCPP,MEM=DSN8BECL,COND=(4,LT),
// PARM.PC=('HOST(CPP),CCSID(1047),MARGINS(1,72),STDSQL(NO)',
// SOURCE,XREF),
// PARM.CP=('/CXX SOURCE XREF OPTFILE(DD:CCOPTS)',
// 'LANGLVL(EXTENDED)'),
// PARM.LKED='NCAL,MAP,AMODE=31,RMODE=ANY'
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8BE3),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8BECL),
// DISP=SHR
//CP.USERLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//CP.SYSLIN DD DSN=&&LOADSET1,
// DISP=(MOD,PASS),
// UNIT=SYSDA,SPACE=(32000,(30,30)),
// DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200)
//LKED.SYSLIN DD DSN=&&LOADSET1,DISP=(OLD,PASS)
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8BECL),
// DISP=SHR
//LKED.RUNLIB DD DSN=DSN!!0.RUNLIB.LOAD,
// DISP=SHR
//*
//* STEP 3 : PREPARE C++ PHONE PROGRAM
//PH02ES03 EXEC DSNHCPP,MEM=DSN8BE3,
// COND=(4,LT),
// PARM.PC=('HOST(CPP),CCSID(1047),MARGINS(1,72),STDSQL(NO)',
// SOURCE,XREF),
// PARM.CP=('/CXX SOURCE XREF OPTFILE(DD:CCOPTS)',
// 'LANGLVL(EXTENDED)'),
// PARM.LKED='AMODE=31,RMODE=ANY,MAP,UPCASE'
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DUMMY),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8BE3),
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1287
// DISP=SHR
//CP.USERLIB DD DSN=DSN!!0.SDSNSAMP,
// DISP=SHR
//LKED.SYSLIN DD DSN=&&LOADSET,DISP=(OLD,DELETE)
// DD DSN=&&LOADSET1,DISP=(OLD,DELETE)
// DD DSN=&&LOADSET2,DISP=(OLD,DELETE)
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8BE3),
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNELI)
INCLUDE SYSLMOD(DSN8MDG)
NAME DSN8BE3(R)
//*
//* STEP 4 : BIND AND RUN PROGRAMS
//PH02ES04 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//DBRMLIB DD DISP=SHR,DSN=DSN!!0.DBRMLIB.DATA
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//CEEDUMP DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//REPORT DD SYSOUT=*
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
GRANT BIND, EXECUTE ON PLAN DSN8BE!!
TO PUBLIC;
//SYSTSIN DD *
DSN SYSTEM(DSN)
BIND PACKAGE(DSN8BE!!) MEMBER(DSN8BE3) APPLCOMPAT(V!!R1) +
ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
BIND PLAN(DSN8BE!!) PKLIST(DSN8BE!!.*) +
ACTION(REPLACE) RETAIN +
ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
RUN PROGRAM(DSNTIAD) PLAN(DSNTIA!!) -
LIB('DSN!!0.RUNLIB.LOAD')
RUN PROGRAM(DSN8BE3) PLAN(DSN8BE!!) -
LIB('DSN!!0.RUNLIB.LOAD')
END
//CARDIN DD *
L*
LJO%
L%SON
LSMITH
LBROWN ALAN
LBROWN DAVID
U 0002304265
//*
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSNTEJ2P
THIS JCL PERFORMS THE PHASE 2 SETUP FOR THE SAMPLE APPLICATIONS AT SITES WITH PL/I.
//*********************************************************************
//* NAME = DSNTEJ2P
//*
//* DESCRIPTIVE NAME = DB2 SAMPLE APPLICATION
//* PHASE 2
//* PL/I
//*
//* LICENSED MATERIALS - PROPERTY OF IBM
//* 5650-DB2
//* (C) COPYRIGHT 1982, 2016 IBM CORP. ALL RIGHTS RESERVED.
//*
//* STATUS = VERSION 12
//*
//* FUNCTION = THIS JCL PERFORMS THE PHASE 2 SETUP FOR THE SAMPLE
//* APPLICATIONS AT SITES WITH PL/I. IT PREPARES AND
//* EXECUTES THE PL/I BATCH PROGRAM.
//*
//* THIS JOB IS RUN AFTER PHASE 1.
//*
//* CHANGE ACTIVITY =
//* 08/18/2014 Single-phase migration s21938_inst1 s21938
//*
1288 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
//*********************************************************************
//*
//JOBLIB DD DISP=SHR,DSN=DSN!!0.SDSNEXIT
// DD DISP=SHR,DSN=DSN!!0.SDSNLOAD
// DD DISP=SHR,DSN=CEE.V!R!M!.SCEERUN
//* STEP 1: CREATE COPY FILE TABLE DESCRIPTIONS ( DCLGEN )
//PH02PS01 EXEC PGM=IKJEFT01,DYNAMNBR=20
//SYSTSPRT DD SYSOUT=*,DCB=(RECFM=F,LRECL=200,BLKSIZE=200)
//SYSUDUMP DD SYSOUT=*
//SYSTSIN DD *
DELETE 'DSN!!0.SRCLIB.DATA(DSN8MPAC)'
DELETE 'DSN!!0.SRCLIB.DATA(DSN8MPDP)'
DELETE 'DSN!!0.SRCLIB.DATA(DSN8MPEM)'
DELETE 'DSN!!0.SRCLIB.DATA(DSN8MPPJ)'
DELETE 'DSN!!0.SRCLIB.DATA(DSN8MPPA)'
DELETE 'DSN!!0.SRCLIB.DATA(DSN8MPEP)'
DELETE 'DSN!!0.SRCLIB.DATA(DSN8MPDM)'
DELETE 'DSN!!0.SRCLIB.DATA(DSN8MPAD)'
DELETE 'DSN!!0.SRCLIB.DATA(DSN8MPA2)'
DELETE 'DSN!!0.SRCLIB.DATA(DSN8MPPR)'
DELETE 'DSN!!0.SRCLIB.DATA(DSN8MPPD)'
DELETE 'DSN!!0.SRCLIB.DATA(DSN8MPP2)'
DELETE 'DSN!!0.SRCLIB.DATA(DSN8MPSA)'
DELETE 'DSN!!0.SRCLIB.DATA(DSN8MPS2)'
DELETE 'DSN!!0.SRCLIB.DATA(DSN8MPCS)'
DELETE 'DSN!!0.SRCLIB.DATA(DSN8MPOV)'
DELETE 'DSN!!0.SRCLIB.DATA(DSN8MPDT)'
DELETE 'DSN!!0.SRCLIB.DATA(DSN8MPED)'
DELETE 'DSN!!0.SRCLIB.DATA(DSN8MPFP)'
DSN SYSTEM(DSN)
DCLGEN TABLE(VACT) +
OWNER(DSN8!!0) +
LIBRARY('DSN!!0.SRCLIB.DATA(DSN8MPAC)') +
ACTION(ADD) +
LANGUAGE(PLI) +
STRUCTURE(PACT)
DCLGEN TABLE(VDEPT) +
OWNER(DSN8!!0) +
LIBRARY('DSN!!0.SRCLIB.DATA(DSN8MPDP)') +
ACTION(ADD) +
LANGUAGE(PLI) +
STRUCTURE(PDEPT)
DCLGEN TABLE(VEMP) +
OWNER(DSN8!!0) +
LIBRARY('DSN!!0.SRCLIB.DATA(DSN8MPEM)') +
ACTION(ADD) +
LANGUAGE(PLI) +
STRUCTURE(PEMP)
DCLGEN TABLE(VPROJ) +
OWNER(DSN8!!0) +
LIBRARY('DSN!!0.SRCLIB.DATA(DSN8MPPJ)') +
ACTION(ADD) +
LANGUAGE(PLI) +
STRUCTURE(PPROJ)
DCLGEN TABLE(VPROJACT) +
OWNER(DSN8!!0) +
LIBRARY('DSN!!0.SRCLIB.DATA(DSN8MPPA)') +
ACTION(ADD) +
LANGUAGE(PLI) +
STRUCTURE(PPROJACT)
DCLGEN TABLE(VEMPPROJACT) +
OWNER(DSN8!!0) +
LIBRARY('DSN!!0.SRCLIB.DATA(DSN8MPEP)') +
ACTION(ADD) +
LANGUAGE(PLI) +
STRUCTURE(PEMPPROJACT)
DCLGEN TABLE(VDEPMG1) +
OWNER(DSN8!!0) +
LIBRARY('DSN!!0.SRCLIB.DATA(DSN8MPDM)') +
ACTION(ADD) +
LANGUAGE(PLI) +
STRUCTURE(PDEPMGR)
DCLGEN TABLE(VASTRDE1) +
OWNER(DSN8!!0) +
LIBRARY('DSN!!0.SRCLIB.DATA(DSN8MPAD)') +
ACTION(ADD) +
LANGUAGE(PLI) +
STRUCTURE(PASTRDET)
DCLGEN TABLE(VASTRDE2) +
OWNER(DSN8!!0) +
LIBRARY('DSN!!0.SRCLIB.DATA(DSN8MPA2)') +
ACTION(ADD) +
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1289
LANGUAGE(PLI) +
NAMES(ASTD) +
STRUCTURE(PASTRDE2)
DCLGEN TABLE(VPROJRE1) +
OWNER(DSN8!!0) +
LIBRARY('DSN!!0.SRCLIB.DATA(DSN8MPPR)') +
ACTION(ADD) +
LANGUAGE(PLI) +
STRUCTURE(PPROJRES)
DCLGEN TABLE(VPSTRDE1) +
OWNER(DSN8!!0) +
LIBRARY('DSN!!0.SRCLIB.DATA(DSN8MPPD)') +
ACTION(ADD) +
LANGUAGE(PLI) +
STRUCTURE(PPSTRDET)
DCLGEN TABLE(VPSTRDE2) +
OWNER(DSN8!!0) +
LIBRARY('DSN!!0.SRCLIB.DATA(DSN8MPP2)') +
ACTION(ADD) +
LANGUAGE(PLI) +
NAMES(PSTD) +
STRUCTURE(PPSTRDE2)
DCLGEN TABLE(VSTAFAC1) +
OWNER(DSN8!!0) +
LIBRARY('DSN!!0.SRCLIB.DATA(DSN8MPSA)') +
ACTION(ADD) +
LANGUAGE(PLI) +
NAMES(STAF) +
STRUCTURE(PSTAFAC1)
DCLGEN TABLE(VSTAFAC2) +
OWNER(DSN8!!0) +
LIBRARY('DSN!!0.SRCLIB.DATA(DSN8MPS2)') +
ACTION(ADD) +
LANGUAGE(PLI) +
STRUCTURE(PSTAFACT)
DCLGEN TABLE(VCONA) +
OWNER(DSN8!!0) +
LIBRARY('DSN!!0.SRCLIB.DATA(DSN8MPCS)') +
ACTION(ADD) +
LANGUAGE(PLI) +
STRUCTURE(PCONA)
DCLGEN TABLE(VOPTVAL) +
OWNER(DSN8!!0) +
LIBRARY('DSN!!0.SRCLIB.DATA(DSN8MPOV)') +
ACTION(ADD) +
LANGUAGE(PLI) +
STRUCTURE(POPTVAL)
DCLGEN TABLE(VDSPTXT) +
OWNER(DSN8!!0) +
LIBRARY('DSN!!0.SRCLIB.DATA(DSN8MPDT)') +
ACTION(ADD) +
LANGUAGE(PLI) +
STRUCTURE(PDSPTXT)
DCLGEN TABLE(VEMPDPT1) +
OWNER(DSN8!!0) +
LIBRARY('DSN!!0.SRCLIB.DATA(DSN8MPED)') +
ACTION(ADD) +
LANGUAGE(PLI) +
STRUCTURE(PEMPDPT1)
DCLGEN TABLE(VFORPLA) +
OWNER(DSN8!!0) +
LIBRARY('DSN!!0.SRCLIB.DATA(DSN8MPFP)') +
ACTION(ADD) +
LANGUAGE(PLI) +
STRUCTURE(PFORPLA)
END
//*
//* STEP 2: PREPARE PLI MESSAGE ROUTINE
//PH02PS02 EXEC DSNHPLI,MEM=DSN8MPG,
// COND=(4,LT),
// PARM.PC='HOST(PLI),CCSID(37),SOURCE,XREF,STDSQL(NO)',
// PARM.PLI=('NOPT,SOURCE,OBJECT,MARGINS(2,72,0),NORENT',
// 'LIMITS(EXTNAME(7)),OPTIONS'),
// PARM.LKED='NCAL,LIST,XREF'
//PPLI.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8MPG),
// DISP=SHR
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8MPG),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8MPG),
// DISP=SHR
1290 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
//*
//* STEP 3: PREPARE TELEPHONE PROGRAM
//PH02PS03 EXEC DSNHPLI,MEM=DSN8BP3,
// COND=(4,LT),
// PARM.PC='HOST(PLI),CCSID(37),SOURCE,XREF,STDSQL(NO)',
// PARM.PLI=('NOPT,SOURCE,OBJECT,MARGINS(2,72,0)',
// 'LIMITS(EXTNAME(7)),OPTIONS')
//PPLI.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8BP3),
// DISP=SHR
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8BP3),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8BP3),
// DISP=SHR
//LKED.RUNLIB DD DSN=DSN!!0.RUNLIB.LOAD,
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNELI)
INCLUDE RUNLIB(DSN8MPG)
//*
//* STEP 4: BIND PROGRAMS
//PH02PS04 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA,
// DISP=SHR
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
GRANT BIND, EXECUTE ON PLAN DSN8BP!!
TO PUBLIC;
//SYSTSIN DD *
DSN SYSTEM(DSN)
BIND PACKAGE(DSN8BP!!) MEMBER(DSN8BP3) APPLCOMPAT(V!!R1) +
ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
BIND PLAN(DSN8BP!!) PKLIST(DSN8BP!!.*) +
ACTION(REPLACE) RETAIN +
ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
RUN PROGRAM(DSNTIAD) PLAN(DSNTIA!!) -
LIB('DSN!!0.RUNLIB.LOAD')
END
//*
//* STEP 5: RUN PROGRAMS
//PH02PS05 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//REPORT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//CARDIN DD *
L*
LJO%
L%SON
LSMITH
LBROWN ALAN
LBROWN DAVID
U 0002304265
//SYSTSIN DD *
DSN SYSTEM(DSN)
RUN PROGRAM(DSN8BP3) PLAN(DSN8BP!!) -
LIB('DSN!!0.RUNLIB.LOAD')
END
//*
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSNTEJ2F
THIS JCL PERFORMS THE PHASE 2 SETUP FOR THE SAMPLE APPLICATIONS AT SITES WITH FORTRAN.
//*********************************************************************
//* NAME = DSNTEJ2F
//*
//* DESCRIPTIVE NAME = DB2 SAMPLE APPLICATION
//* PHASE 2
//* FORTRAN
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1291
//*
//* LICENSED MATERIALS - PROPERTY OF IBM
//* 5650-DB2
//* (C) COPYRIGHT 1982, 2016 IBM CORP. ALL RIGHTS RESERVED.
//*
//* STATUS = VERSION 12
//*
//* FUNCTION = THIS JCL PERFORMS THE PHASE 2 SETUP FOR THE SAMPLE
//* APPLICATIONS AT SITES WITH FORTRAN. IT PREPARES
//* AND EXECUTES THE FORTRAN BATCH PROGRAM.
//*
//* THIS JOB IS RUN AFTER PHASE 1.
//*
//* CHANGE ACTIVITY =
//* 08/18/2014 Single-phase migration s21938_inst1 s21938
//*
//*********************************************************************
//*
//JOBLIB DD DSN=DSN!!0.SDSNLOAD,DISP=SHR
// DD DSN=SYS1.VSF2FORT,DISP=SHR
//* STEP 1: PREPARE DSNTIR ROUTINE
//PH02FS01 EXEC DSNHASM,MEM=DSNTIR,
// PARM.PC='HOST(ASM),STDSQL(NO)',
// PARM.ASM='RENT,OBJECT,NODECK',
// PARM.LKED='XREF,NCAL'
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSNTIR),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
// DD DSN=DSN!!0.SDSNSAMP,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSNTIR),
// DISP=SHR
//ASM.SYSLIB DD DSN=DSN!!0.SDSNSAMP,
// DISP=SHR
// DD DSN=SYS1.MACLIB,DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSNTIR),
// DISP=SHR
//LKED.SYSIN DD *
ENTRY DSNTIR
NAME DSNTIR(R)
//*
//* STEP 2: PREPARE TELEPHONE PROGRAM
//PH02FS02 EXEC DSNHFOR,MEM=DSN8BF3,
// COND=(4,LT),
// PARM.PC='HOST(FORTRAN),SOURCE,XREF,STDSQL(NO)',
// PARM.FORT='MAP,GOSTMT,SOURCE,XREF'
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8BF3),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8BF3),
// DISP=SHR
//LKED.SYSLIB DD
// DD
// DD DSN=DSN!!0.RUNLIB.LOAD,
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8BF3),
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNHFT)
//*
//* STEP 3: BIND AND RUN PROGRAM
//PH02FS03 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA,DISP=SHR
//SYSTSPRT DD SYSOUT=*
//FT06F001 DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
GRANT BIND, EXECUTE ON PLAN DSN8BF!!
TO PUBLIC;
//SYSTSIN DD *
DSN SYSTEM(DSN)
BIND PACKAGE(DSN8BF!!) MEMBER(DSN8BF3) APPLCOMPAT(V!!R1) +
ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
BIND PLAN(DSN8BF!!) PKLIST(DSN8BF!!.*) +
ACTION(REPLACE) RETAIN +
ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
RUN PROGRAM(DSN8BF3) PLAN(DSN8BF!!) -
LIB('DSN!!0.RUNLIB.LOAD')
1292 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
RUN PROGRAM(DSNTIAD) PLAN(DSNTIA!!) -
LIB('DSN!!0.RUNLIB.LOAD')
END
//FT05F001 DD *
L*
LJO%
L%SON
LSMITH
LBROWN ALAN
LBROWN DAVID
U 0002304265
//*
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSNTEJ3C
THIS JCL PERFORMS THE PHASE 3 SETUP FOR THE SAMPLE APPLICATIONS AT SITES WITH COBOL.
//*********************************************************************
//* NAME = DSNTEJ3C
//*
//* DESCRIPTIVE NAME = DB2 SAMPLE APPLICATION
//* PHASE 3
//* COBOL, ISPF, CAF
//*
//* LICENSED MATERIALS - PROPERTY OF IBM
//* 5650-DB2
//* (C) COPYRIGHT 1982, 2016 IBM Corp. All Rights Reserved.
//*
//* STATUS = Version 12
//*
//* FUNCTION = THIS JCL PERFORMS THE PHASE 3 SETUP FOR THE SAMPLE
//* APPLICATIONS AT SITES WITH COBOL. IT PREPARES THE
//* COBOL ISPF CAF TELEPHONE APPLICATION AND THE REMOTE
//* COBOL ORGANIZATION APPLICATION.
//*
//* NOTE: DDF MUST BE UP FOR STEP PH03CS06 TO EXECUTE
//*
//* RUN THIS JOB ANYTIME AFTER PHASE 2.
//*
//*
//*
//* CHANGE ACTIVITY =
//* 08/18/2014 Single-phase migration s21938_inst1 s21938
//*
//*********************************************************************
//*
//JOBLIB DD DSN=DSN!!0.SDSNLOAD,DISP=SHR
//*
//*
//* STEP 1: PREPARE THE COBOL CAF INTERFACE
//*
//PH03CS01 EXEC DSNHICOB,MEM=DSN8CC,
// COND=(4,LT),
// PARM.PC=('HOST(IBMCOB)',APOST,APOSTSQL,SOURCE,
// NOXREF,'SQL(DB2)','DEC(31)'),
// PARM.COB=(NOSEQUENCE,QUOTE,RENT,'PGMNAME(LONGUPPER)')
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8CC),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8CC),
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8CC),
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNALI)
//*
//* STEP 2: PREPARE THE CONNECTION MANAGER
//*
//PH03CS02 EXEC DSNHICOB,MEM=DSN8SCM,
// COND=(4,LT),
// PARM.PC=('HOST(IBMCOB)',APOST,APOSTSQL,SOURCE,
// NOXREF,'SQL(DB2)','DEC(31)'),
// PARM.COB=(NOSEQUENCE,QUOTE,RENT,'PGMNAME(LONGUPPER)')
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1293
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8SCM),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8SCM),
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8SCM),
// DISP=SHR
//*
//* STEP 3: PREPARE THE TELEPHONE APPLICATION
//*
//PH03CS03 EXEC DSNHICOB,MEM=DSN8SC3,
// COND=(4,LT),
// PARM.PC=('HOST(IBMCOB)',APOST,APOSTSQL,SOURCE,
// NOXREF,'SQL(DB2)','DEC(31)'),
// PARM.COB=(NOSEQUENCE,QUOTE,RENT,'PGMNAME(LONGUPPER)')
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8SC3),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8SC3),
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8SC3),
// DISP=SHR
//LKED.RUNLIB DD DSN=DSN!!0.RUNLIB.LOAD,
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNALI)
INCLUDE RUNLIB(DSN8MCG)
//*
//* STEP 4: PREPARE THE REMOTE ORGANIZATION APPLICATION
//*
//PH03CS04 EXEC DSNHICOB,MEM=DSN8HC3,
// COND=(4,LT),
// PARM.PC=('HOST(IBMCOB)',APOST,APOSTSQL,SOURCE,
// NOXREF,'SQL(DB2)','DEC(31)'),
// PARM.COB=(NOSEQUENCE,QUOTE,RENT,'PGMNAME(LONGUPPER)')
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8HC3),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8HC3),
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8HC3),
// DISP=SHR
//LKED.RUNLIB DD DSN=DSN!!0.RUNLIB.LOAD,
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNALI)
INCLUDE RUNLIB(DSN8MCG)
//*
//* STEP 5: BIND THE TELEPHONE APPLICATION PROGRAM
//*
//PH03CS05 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA,DISP=SHR
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
GRANT BIND, EXECUTE ON PLAN DSN8SC!!
TO PUBLIC;
//SYSTSIN DD *
DSN SYSTEM(DSN)
BIND PACKAGE(DSN8SC!!) MEMBER(DSN8SC3) APPLCOMPAT(V!!R1) +
ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
BIND PLAN(DSN8SC!!) PKLIST(DSN8SC!!.*) +
ACTION(REPLACE) RETAIN +
ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
RUN PROGRAM(DSNTIAD) PLAN(DSNTIA!!) -
LIB('DSN!!0.RUNLIB.LOAD')
//*
//* STEP 6: BIND THE REMOTE ORGANIZATION APPLICATION
//*
//PH03CS06 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA,DISP=SHR
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//SYSIN DD *
1294 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
SET CURRENT SQLID = 'SYSADM';
GRANT BIND, EXECUTE ON PLAN DSN8HC!!
TO PUBLIC;
//SYSTSIN DD *
DSN SYSTEM(DSN)
BIND PACKAGE(DSN8HC!!) MEMBER (DSN8HC3) APPLCOMPAT(V!!R1) +
ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
BIND PACKAGE(SAMPLOC.DSN8HC!!) MEMBER(DSN8HC3) +
APPLCOMPAT(V!!R1) +
ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
BIND PLAN(DSN8HC!!) -
PKLIST(DSN8HC!!.*,SAMPLOC.DSN8HC!!.*) -
ACTION(REPLACE) RETAIN +
ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
RUN PROGRAM(DSNTIAD) PLAN(DSNTIA!!) -
LIB('DSN!!0.RUNLIB.LOAD')
END
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSNTEJ6
RUN THIS JOB AT THE REMOTE LOCATION TO UPDATE THE SAMPLE LOCATION IN DEPARTMENT TABLE
RUN THIS JOB ANYTIME AFTER PHASE 3.
//********************************************************************* 00010000
//* NAME = DSNTEJ6 00020000
//* 00030000
//* DESCRIPTIVE NAME = DB2 REMOTE UNIT OF WORK SAMPLE APPLICATION 00040000
//* PHASE 6 00050000
//* 00060000
//* LICENSED MATERIALS - PROPERTY OF IBM 00070000
//* 5615-DB2 00080001
//* (C) COPYRIGHT 1982, 2013 IBM CORP. ALL RIGHTS RESERVED. 00090001
//* 00100000
//* STATUS = VERSION 11 00110001
//* 00120000
//* FUNCTION = RUN THIS JOB AT THE REMOTE LOCATION TO UPDATE THE 00130000
//* SAMPLE LOCATION IN DEPARTMENT TABLE 00140000
//* 00150000
//* RUN THIS JOB ANYTIME AFTER PHASE 3. 00160000
//* 00170000
//* CHANGE ACTIVITY = 00180000
//* 11/07/2012 ADD SET CURRENT SQLID DN1651_INST1 / DN1651 00180100
//* 05/17/2013 FIX COPYRIGHT STATEMENT 49779_077_724 00180201
//* 00181000
//********************************************************************* 00190000
//* 00200000
//JOBLIB DD DSN=DSN!!0.SDSNLOAD,DISP=SHR 00210000
//* 00220000
//* STEP 1: UPDATE SAMPLE LOCATIONS IN DEPARTMENT TABLE 00230000
//* 00240000
//PH06S01 EXEC PGM=IKJEFT01,DYNAMNBR=20 00250000
//SYSTSPRT DD SYSOUT=* 00260000
//SYSPRINT DD SYSOUT=* 00270000
//SYSUDUMP DD SYSOUT=* 00280000
//SYSOUT DD SYSOUT=* 00290000
//SYSTSIN DD * 00300000
DSN SYSTEM(DSN) 00310000
RUN PROGRAM(DSNTIAD) PLAN(DSNTIA!!) - 00320000
LIB('DSN!!0.RUNLIB.LOAD') 00330000
//SYSIN DD * 00340000
SET CURRENT SQLID = 'SYSADM'; 00341000
UPDATE DEPT SET LOCATION = 'SAMPLOC' WHERE DEPTNO = 'F22'; 00350000
UPDATE DEPT SET LOCATION = 'THISLOCN' WHERE LOCATION = ' '; 00360000
//* 00370000
Related reference
“Sample applications in TSO” on page 1025
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1295
A set of Db2 sample applications run in the TSO environment.
DSNTEJ3P
THIS JCL PERFORMS THE PHASE 3 SETUP FOR THE SAMPLE APPLICATIONS AT SITES WITH PL/I.
//*********************************************************************
//* NAME = DSNTEJ3P
//*
//* DESCRIPTIVE NAME = DB2 SAMPLE APPLICATION
//* PHASE 3
//* PL/I, ISPF, CAF
//*
//* LICENSED MATERIALS - PROPERTY OF IBM
//* 5650-DB2
//* (C) COPYRIGHT 1982, 2016 IBM CORP. ALL RIGHTS RESERVED.
//*
//* STATUS = VERSION 12
//*
//* FUNCTION = THIS JCL PERFORMS THE PHASE 3 SETUP FOR THE SAMPLE
//* APPLICATIONS AT SITES WITH PL/I. IT PREPARES THE
//* PL/I ISPF CAF TELEPHONE PROGRAM.
//*
//* RUN THIS JOB ANYTIME AFTER PHASE 2.
//*
//* CHANGE ACTIVITY =
//* 08/18/2014 Single-phase migration s21938_inst1 s21938
//*
//*********************************************************************
//*
//JOBLIB DD DISP=SHR,DSN=DSN!!0.SDSNLOAD
// DD DISP=SHR,DSN=CEE.V!R!M!.SCEERUN
//*
//* STEP 1: PREPARE THE ISPF CAF CONNECTION MANAGER
//*
//PH03PS01 EXEC DSNHPLI,MEM=DSN8SPM,
// COND=(4,LT),
// PARM.PC='HOST(PLI),CCSID(37),SOURCE,XREF,STDSQL(NO)',
// PARM.PLI=('NOPT,SOURCE,OBJECT,MARGINS(2,72,0)',
// 'LIMITS(EXTNAME(7)),OPTIONS')
//PPLI.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8SPM),
// DISP=SHR
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8SPM),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8SPM),
// DISP=SHR
//LKED.SYSIN DD *
ENTRY CEESTART
//*
//* STEP 2: PREPARE THE ISPF CAF TELEPHONE APPLICATION
//*
//PH03PS02 EXEC DSNHPLI,MEM=DSN8SP3,
// COND=(4,LT),
// PARM.PC='HOST(PLI),CCSID(37),SOURCE,XREF,STDSQL(NO)',
// PARM.PLI=('NOPT,SOURCE,OBJECT,MARGINS(2,72,0)',
// 'LIMITS(EXTNAME(7)),OPTIONS')
//PPLI.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8SP3),
// DISP=SHR
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8SP3),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8SP3),
// DISP=SHR
//LKED.RUNLIB DD DSN=DSN!!0.RUNLIB.LOAD,
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNALI)
INCLUDE RUNLIB(DSN8MPG)
//*
//* STEP 3: BIND THE ISPF CAF TELEPHONE APPLICATION
//*
//PH03PS03 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//DBRMLIB DD DISP=SHR,DSN=DSN!!0.DBRMLIB.DATA
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
1296 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
GRANT BIND, EXECUTE ON PLAN DSN8SP!!
TO PUBLIC;
//SYSTSIN DD *
DSN SYSTEM(DSN)
BIND PACKAGE(DSN8SP!!) MEMBER(DSN8SP3) APPLCOMPAT(V!!R1) +
ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
BIND PLAN(DSN8SP!!) PKLIST(DSN8SP!!.*) +
ACTION(REPLACE) RETAIN +
ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
RUN PROGRAM(DSNTIAD) PLAN(DSNTIA!!) -
LIB('DSN!!0.RUNLIB.LOAD')
END
//*
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSNTEJ2A
THIS JCL PERFORMS THE PHASE 2 SETUP FOR THE SAMPLE APPLICATIONS.
//*********************************************************************
//* NAME = DSNTEJ2A
//*
//* DESCRIPTIVE NAME = DB2 SAMPLE APPLICATION
//* PHASE 2
//* ASSEMBLER
//*
//* Licensed Materials - Property of IBM
//* 5650-DB2
//* (C) COPYRIGHT 1982, 2016 IBM Corp. All Rights Reserved.
//*
//* STATUS = Version 12
//*
//* FUNCTION = THIS JCL PERFORMS THE PHASE 2 SETUP FOR THE SAMPLE
//* APPLICATIONS. IT PREPARES AND RUNS THE SAMPLE
//* ASSEMBLER BATCH TABLE UNLOAD PROGRAM
//*
//* THIS JOB IS RUN AFTER PHASE 1.
//*
//* NOTICE =
//* THIS SAMPLE JOB USES DB2 UTILITIES. SOME UTILITY FUNCTIONS ARE
//* ELEMENTS OF SEPARATELY ORDERABLE PRODUCTS. SUCCESSFUL USE OF
//* A PARTICULAR SAMPLE JOB MAY BE DEPENDENT UPON THE OPTIONAL
//* PRODUCT BEING LICENSED AND INSTALLED IN YOUR ENVIRONMENT.
//*
//* CHANGE ACTIVITY =
//* 08/18/2014 Single-phase migration s21938_inst1 s21938
//*
//*********************************************************************
//*
//JOBLIB DD DSN=DSN!!0.SDSNLOAD,DISP=SHR
//*
//* PRECOMPILE, ASSEMBLE, AND LINK EDIT THE UNLOAD PROGRAM
//*
//PREPUNL EXEC DSNHASM,MEM=DSNTIAUL,
// PARM.PC='HOST(ASM),STDSQL(NO),VERSION(AUTO)',
// PARM.ASM='RENT,OBJECT,NODECK',
// PARM.LKED='RENT,XREF,AMODE=ANY,RMODE=24'
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSNTIAUL),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SDSNSAMP,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSNTIAUL),
// DISP=SHR
//ASM.SYSLIB DD
// DD DSN=DSN!!0.SDSNMACS,
// DISP=SHR
// DD DSN=DSN!!0.SDSNSAMP,
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSNTIAUL),
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNELI)
NAME DSNTIAUL(R)
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1297
//*
//* BIND THE UNLOAD PROGRAM AND GRANT EXECUTE AUTHORITY
//*
//BINDUNL EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA,
// DISP=SHR
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
BIND PACKAGE(DSNTIB!!) MEM(DSNTIAUL) APPLCOMPAT(V!!R1) +
CURRENTDATA(NO) ACT(REP) ISO(CS) ENCODING(EBCDIC) +
LIB('DSN!!0.DBRMLIB.DATA')
BIND PLAN(DSNTIB!!) PKLIST(DSNTIB!!.*) +
ACTION(REPLACE) RETAIN +
CURRENTDATA(NO) ISO(CS) ENCODING(EBCDIC)
RUN PROGRAM(DSNTIAD) PLAN(DSNTIA!!) +
LIB('DSN!!0.RUNLIB.LOAD')
END
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
GRANT EXECUTE ON PLAN DSNTIB!!
TO PUBLIC;
//*
//* DELETE DATA SETS, DROP TABLES TO ALLOW RERUNS
//*
//DELETE EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//SYSTSPRT DD SYSOUT=*
//SYSTSIN DD *
DELETE 'DSN!!0.DSN8UNLD.SYSREC00'
DELETE 'DSN!!0.DSN8UNLD.SYSREC01'
DELETE 'DSN!!0.DSN8UNLD.SYSPUNCH'
DSN SYSTEM(DSN)
RUN PROGRAM(DSNTIAD) PLAN(DSNTIA!!) PARM('RC0') -
LIB('DSN!!0.RUNLIB.LOAD')
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
DROP TABLE DSN8!!0.NEWDEPT ;
DROP TABLE DSN8!!0.NEWPHONE ;
DROP DATABASE DSN8D!!U ;
DROP STOGROUP DSN8G!!U ;
COMMIT;
//*
//* CREATE NEW TABLES
//*
//CREATE EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//SYSTSPRT DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
RUN PROGRAM(DSNTIAD) PLAN(DSNTIA!!) -
LIB('DSN!!0.RUNLIB.LOAD')
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
CREATE STOGROUP DSN8G!!U
VOLUMES (DSNV01)
VCAT DSNC!!0;
1298 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
DEPTNAME VARCHAR(36) NOT NULL )
IN DATABASE DSN8D!!U
CCSID EBCDIC;
//*
//* RUN UNLOAD PROGRAM
//*
//UNLOAD EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//SYSTSPRT DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
RUN PROGRAM(DSNTIAUL) PLAN(DSNTIB!!) PARMS('SQL') -
LIB('DSN!!0.RUNLIB.LOAD')
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSREC00 DD DSN=DSN!!0.DSN8UNLD.SYSREC00,
// DISP=(,CATLG),
// UNIT=SYSDA,
// SPACE=(1024,(10,10))
//SYSREC01 DD DSN=DSN!!0.DSN8UNLD.SYSREC01,
// DISP=(,CATLG),
// UNIT=SYSDA,
// SPACE=(1024,(10,10))
//SYSPUNCH DD DSN=DSN!!0.DSN8UNLD.SYSPUNCH,
// DISP=(,CATLG),
// UNIT=SYSDA,
// SPACE=(800,(15,15))
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
LOCK TABLE DSN8!!0.DEPT IN SHARE MODE;
SELECT * FROM DSN8!!0.DEPT;
SELECT * FROM DSN8!!0.VPHONE;
//*
//* EDIT THE OUTPUT FROM THE PROGRAM
//*
//EDIT EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=((4,LT),(4,LE,UNLOAD))
//SYSTSPRT DD SYSOUT=*
//SYSTSIN DD *
EDIT 'DSN!!0.DSN8UNLD.SYSPUNCH' DATA NONUM
CHANGE * 30 /DSN8!!0.DEPT/DSN8!!0.NEWDEPT/
CHANGE * 30 /DSN8!!0.VPHONE/DSN8!!0.NEWPHONE/
TOP
LIST * 999
END SAVE
//*
//* RUN LOAD UTILITY TO LOAD TABLES
//*
//LOAD EXEC DSNUPROC,PARM='DSN,DSNTEX',
// COND=((4,LT),(4,LE,UNLOAD))
//DSNTRACE DD SYSOUT=*
//SORTLIB DD DSN=SYS1.SORTLIB,DISP=SHR
//SORTWK01 DD UNIT=SYSDA,SPACE=(4000,(20,20),,,ROUND)
//SORTWK02 DD UNIT=SYSDA,SPACE=(4000,(20,20),,,ROUND)
//SORTWK03 DD UNIT=SYSDA,SPACE=(4000,(20,20),,,ROUND)
//SORTWK04 DD UNIT=SYSDA,SPACE=(4000,(20,20),,,ROUND)
//SYSREC00 DD DSN=DSN!!0.DSN8UNLD.SYSREC00,
// DISP=(OLD,KEEP)
//SYSREC01 DD DSN=DSN!!0.DSN8UNLD.SYSREC01,
// DISP=(OLD,KEEP)
//SYSUT1 DD UNIT=SYSDA,SPACE=(4000,(20,20),,,ROUND)
//SYSIN DD DSN=DSN!!0.DSN8UNLD.SYSPUNCH,
// DISP=(OLD,KEEP)
//*
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSNTEJ1P
THIS JCL PERFORMS THE PHASE 1 SETUP FOR SAMPLE APPLICATIONS AT SITES WITH PL/I.
//*********************************************************************
//* NAME = DSNTEJ1P
//*
//* DESCRIPTIVE NAME = DB2 SAMPLE APPLICATION
//* PHASE 1
//* PL/I
//*
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1299
//* Licensed Materials - Property of IBM
//* 5650-DB2
//* (C) COPYRIGHT 1982, 2016 IBM Corp. All Rights Reserved.
//*
//* STATUS = Version 12
//*
//* FUNCTION = THIS JCL PERFORMS THE PHASE 1 SETUP FOR SAMPLE
//* APPLICATIONS AT SITES WITH PL/I.
//*
//* THIS JOB IS RUN AFTER DSNTEJ1.
//*
//* CHANGE ACTIVITY =
//* 08/18/2014 Single-phase migration s21938_inst1 s21938
//*
//*********************************************************************
//JOBLIB DD DISP=SHR,DSN=DSN!!0.SDSNLOAD
// DD DISP=SHR,DSN=CEE.V!R!M!.SCEERUN
//*
//* STEP 1 : PREPARE DSNTEP2 FOR EXECUTION
//PH01PS01 EXEC DSNHPLI,MEM=DSNTEP2,
// PARM.PC=('HOST(PLI),CCSID(37),STDSQL(NO),CONNECT(2)',
// TWOPASS,'VERSION(AUTO)'),
// PARM.PLI=(NOPT,'MAR(2,72,0)',GS,OBJ,S,
// 'LIMITS(FIXEDBIN(31,63))','LANGLVL(SPROG)',OFFSET)
//PPLI.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSNTEP2),
// DISP=SHR
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSNTEP2),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSNTEP2),
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNELI)
//*
//* STEP 2 : BIND AND RUN PROGRAM DSNTEP2, TO
//* PRINT THE TABLES
//PH01PS02 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA,
// DISP=SHR
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
BIND PACKAGE (DSNTEP2) MEMBER(DSNTEP2) APPLCOMPAT(V!!R1) +
CURRENTDATA(NO) ACT(REP) ISO(CS) ENCODING(EBCDIC)
BIND PLAN(DSNTEP!!) PKLIST(DSNTEP2.*) +
ACTION(REPLACE) RETAIN +
CURRENTDATA(NO) ISO(CS) ENCODING(EBCDIC) SQLRULES(DB2)
RUN PROGRAM(DSNTEP2) PLAN(DSNTEP!!) +
LIB('DSN!!0.RUNLIB.LOAD') +
PARMS('/ALIGN(MID)')
END
//*
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
GRANT EXECUTE, BIND ON PLAN DSNTEP!!
TO PUBLIC;
SELECT EMPNO, FIRSTNME, MIDINIT, LASTNAME,
WORKDEPT, PHONENO, HIREDATE, JOB, EDLEVEL,
SEX, BIRTHDATE, SALARY, BONUS, COMM,
SALARY+BONUS+COMM AS TOTAL_SALARY
FROM EMP
ORDER BY TOTAL_SALARY;
SELECT * FROM DEPT;
SELECT * FROM ACT;
SELECT * FROM EMPPROJACT;
SELECT * FROM PROJ;
SELECT * FROM PROJACT;
//*
//*
//* STEP 3 : PREPARE DSNTEP4 FOR EXECUTION
//PH01PS03 EXEC DSNHPLI,MEM=DSNTEP4,COND=(4,LT),
// PARM.PC=('HOST(PLI),CCSID(37),STDSQL(NO),CONNECT(2)',
// TWOPASS,'VERSION(AUTO)'),
// PARM.PLI=(NOPT,'MAR(2,72,0)',GS,OBJ,S,
// 'LIMITS(FIXEDBIN(31,63))','LANGLVL(SPROG)',OFFSET)
//PPLI.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSNTEP4),
// DISP=SHR
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSNTEP4),
// DISP=SHR
1300 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSNTEP4),
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNELI)
//*
//* STEP 4 : BIND AND RUN PROGRAM DSNTEP4, TO
//* PRINT THE TABLES
//PH01PS04 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA,
// DISP=SHR
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
BIND PACKAGE (DSNTEP4) MEMBER(DSNTEP4) APPLCOMPAT(V!!R1) +
CURRENTDATA(NO) ACT(REP) ISO(CS) ENCODING(EBCDIC)
BIND PLAN(DSNTP4!!) PKLIST(DSNTEP4.*) +
ACTION(REPLACE) RETAIN +
CURRENTDATA(NO) ISO(CS) ENCODING(EBCDIC) SQLRULES(DB2)
RUN PROGRAM(DSNTEP4) PLAN(DSNTP4!!) +
LIB('DSN!!0.RUNLIB.LOAD') +
PARMS('/ALIGN(MID)')
END
//*
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
GRANT EXECUTE, BIND ON PLAN DSNTP4!!
TO PUBLIC;
SELECT EMPNO, FIRSTNME, MIDINIT, LASTNAME,
WORKDEPT, PHONENO, HIREDATE, JOB, EDLEVEL,
SEX, BIRTHDATE, SALARY, BONUS, COMM,
SALARY+BONUS+COMM AS TOTAL_SALARY
FROM EMP
ORDER BY TOTAL_SALARY;
SELECT * FROM DEPT;
SELECT * FROM ACT;
SELECT * FROM EMPPROJACT;
SELECT * FROM PROJ;
SELECT * FROM PROJACT;
//*
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSNTEJ1L
THIS JCL CREATES THE DSNTEP2 LOAD MODULE FROM THE SHIPPED OBJECT DECK, DSNTEP2L, AND
LINKS THE PACKAGE AND PLAN FOR THIS VERSION OF DSNTEP2.
//*********************************************************************
//* NAME = DSNTEJ1L
//*
//* DESCRIPTIVE NAME = DB2 SAMPLE APPLICATION
//* PHASE 1
//* L/E
//*
//* Licensed Materials - Property of IBM
//* 5650-DB2
//* (C) COPYRIGHT 1982, 2016 IBM Corp. All Rights Reserved.
//*
//* STATUS = Version 12
//*
//* FUNCTION = THIS JCL CREATES THE DSNTEP2 LOAD MODULE FROM THE
//* SHIPPED OBJECT DECK, DSNTEP2L, AND LINKS THE
//* PACKAGE AND PLAN FOR THIS VERSION OF DSNTEP2.
//*
//* = THIS JCL ALSO CREATES THE DSNTEP4 LOAD MODULE FROM
//* THE SHIPPED OBJECT DECK, DSNTEP4L, AND LINKS THE
//* PACKAGE AND PLAN FOR THIS VERSION OF DSNTEP4.
//*
//* THIS JOB IS RUN AFTER DSNTEJ1.
//*
//* NOTE: IF YOU RUN THIS JOB, YOU DO NOT NEED TO RUN THE SAMPLE
//* JOB DSNTEJ1P EXCEPT TO PREPARE CUSTOMIZED VERSIONS OF
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1301
//* THE DSNTEP2 AND DSNTEP4 SOURCE CODE (YOU NEED A PL/I
//* COMPILER TO RUN DSNTEJ1P SUCCESSFULLY).
//*
//* CHANGE ACTIVITY =
//* 08/18/2014 Single-phase migration s21938_inst1 s21938
//*
//*********************************************************************
//JOBLIB DD DISP=SHR,DSN=DSN!!0.SDSNLOAD
// DD DISP=SHR,DSN=CEE.V!R!M!.SCEERUN
//*
//* STEP 1 : CREATE DSNTEP2 LOADMOD FROM DSNTEP2L OBJECT DECK
//*
//PH01LS01 EXEC PGM=IEWL,PARM='XREF'
//SYSLIB DD DISP=SHR,DSN=CEE.V!R!M!.SCEELKED
// DD DISP=SHR,DSN=DSN!!0.SDSNLOAD
//SDSNSAMP DD DISP=SHR,DSN=DSN!!0.SDSNSAMP(DSNTEP2L)
//SYSLMOD DD DISP=SHR,DSN=DSN!!0.RUNLIB.LOAD(DSNTEP2)
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSUT1 DD UNIT=SYSDA,SPACE=(1024,(50,50))
//SYSLIN DD *
INCLUDE SDSNSAMP(DSNTEP2L)
INCLUDE SYSLIB(DSNELI)
NAME DSNTEP2(R)
//*
//* STEP 2 : BIND AND RUN PROGRAM DSNTEP2, TO
//* PRINT THE TABLES
//*
//PH01LS02 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//DBRMLIB DD DISP=SHR,DSN=DSN!!0.SDSNSAMP
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
BIND PACKAGE (DSNTEP2) MEMBER(DSN@EP2L) APPLCOMPAT(V!!R1) +
CURRENTDATA(NO) ACT(REP) ISO(CS) ENCODING(EBCDIC)
BIND PLAN(DSNTEP!!) PKLIST(DSNTEP2.*) +
ACTION(REPLACE) RETAIN +
CURRENTDATA(NO) ISO(CS) ENCODING(EBCDIC) SQLRULES(DB2)
RUN PROGRAM(DSNTEP2) PLAN(DSNTEP!!) +
LIB('DSN!!0.RUNLIB.LOAD') +
PARMS('/ALIGN(MID)')
END
//*
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
GRANT EXECUTE, BIND ON PLAN DSNTEP!!
TO PUBLIC;
SELECT EMPNO, FIRSTNME, MIDINIT, LASTNAME,
WORKDEPT, PHONENO, HIREDATE, JOB, EDLEVEL,
SEX, BIRTHDATE, SALARY, BONUS, COMM,
SALARY+BONUS+COMM AS TOTAL_SALARY
FROM EMP
ORDER BY TOTAL_SALARY;
SELECT * FROM DEPT;
SELECT * FROM ACT;
SELECT * FROM EMPPROJACT;
SELECT * FROM PROJ;
SELECT * FROM PROJACT;
//*
//* STEP 3 : CREATE DSNTEP4 LOADMOD FROM DSNTEP4L OBJECT DECK
//*
//PH01LS03 EXEC PGM=IEWL,COND=(4,LT),PARM='XREF'
//SYSLIB DD DISP=SHR,DSN=CEE.V!R!M!.SCEELKED
// DD DISP=SHR,DSN=DSN!!0.SDSNLOAD
//SDSNSAMP DD DISP=SHR,DSN=DSN!!0.SDSNSAMP(DSNTEP4L)
//SYSLMOD DD DISP=SHR,DSN=DSN!!0.RUNLIB.LOAD(DSNTEP4)
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSUT1 DD UNIT=SYSDA,SPACE=(1024,(50,50))
//SYSLIN DD *
INCLUDE SDSNSAMP(DSNTEP4L)
INCLUDE SYSLIB(DSNELI)
NAME DSNTEP4(R)
//*
//* STEP 4 : BIND AND RUN PROGRAM DSNTEP4, TO
//* PRINT THE TABLES
//*
//PH01LS04 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//DBRMLIB DD DISP=SHR,DSN=DSN!!0.SDSNSAMP
//SYSTSPRT DD SYSOUT=*
1302 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
BIND PACKAGE (DSNTEP4) MEMBER(DSN@EP4L) APPLCOMPAT(V!!R1) +
CURRENTDATA(NO) ACT(REP) ISO(CS) ENCODING(EBCDIC)
BIND PLAN(DSNTP4!!) PKLIST(DSNTEP4.*) +
ACTION(REPLACE) RETAIN +
CURRENTDATA(NO) ISO(CS) ENCODING(EBCDIC) SQLRULES(DB2)
RUN PROGRAM(DSNTEP4) PLAN(DSNTP4!!) +
LIB('DSN!!0.RUNLIB.LOAD') +
PARMS('/ALIGN(MID)')
END
//*
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
GRANT EXECUTE, BIND ON PLAN DSNTP4!!
TO PUBLIC;
SELECT EMPNO, FIRSTNME, MIDINIT, LASTNAME,
WORKDEPT, PHONENO, HIREDATE, JOB, EDLEVEL,
SEX, BIRTHDATE, SALARY, BONUS, COMM,
SALARY+BONUS+COMM AS TOTAL_SALARY
FROM EMP
ORDER BY TOTAL_SALARY;
SELECT * FROM DEPT;
SELECT * FROM ACT;
SELECT * FROM EMPPROJACT;
SELECT * FROM PROJ;
SELECT * FROM PROJACT;
//*
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSNTEJ6P
THIS JCL EXECUTES THE PHASE 6 STORED PROCEDURE SAMPLE APPLICATION.
//********************************************************************
//* NAME = DSNTEJ6P
//*
//* DESCRIPTIVE NAME = DB2 SAMPLE APPLICATION
//*
//* PHASE 6
//*
//* LICENSED MATERIALS - PROPERTY OF IBM
//* 5650-DB2
//* (C) COPYRIGHT 1982, 2016 IBM CORP. ALL RIGHTS RESERVED.
//*
//* STATUS = VERSION 12
//*
//* FUNCTION = THIS JCL EXECUTES THE PHASE 6 STORED PROCEDURE
//* SAMPLE APPLICATION.
//*
//* DEPENDENCIES:
//* (1) RUN SAMPLE JOB DSNTEJ6S AT THE SERVER SITE BEFORE RUNNING THIS
//* JOB; DSNTEJ6S PREPARES THE SAMPLE STORED PROC W/O RESULT SET
//* (2) RUN THIS JOB AT THE CLIENT SITE
//*
//* CHANGE ACTIVITY =
//* 08/18/2014 Single-phase migration s21938_inst1 s21938
//*
//********************************************************************
//JOBLIB DD DISP=SHR,DSN=DSN!!0.SDSNEXIT
// DD DISP=SHR,DSN=DSN!!0.SDSNLOAD
// DD DISP=SHR,DSN=CEE.V!R!M!.SCEERUN
// DD DISP=SHR,DSN=DSN!!0.RUNLIB.LOAD
//*
//********************************************************************
//* STEP 1: PRE-COMPILE, COMPILE, AND LINK-EDIT THE CALLING PROGRAM
//********************************************************************
//PH06PS01 EXEC DSNHPLI,MEM=DSN8EP1,
// PARM.PC='HOST(PLI),CCSID(37),STDSQL(NO),CONNECT(2)'
//PPLI.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8EP1),
// DISP=SHR
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8EP1),
// DISP=SHR
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1303
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8EP1),
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNELI)
INCLUDE SYSLIB(DSNTIAR)
//********************************************************************
//* STEP 2: BIND THE CALLING PROGRAM PACKAGE
//********************************************************************
//PH06PS02 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA,
// DISP=SHR
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
GRANT BIND, EXECUTE ON PLAN DSN8EP1
TO PUBLIC;
//SYSTSIN DD *
DSN SYSTEM(DSN)
BIND PACKAGE(DSN8EP!!) MEMBER(DSN8EP1) APPLCOMPAT(V!!R1) +
ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
BIND PACKAGE(SAMPLOC.DSN8EP!!) APPLCOMPAT(V!!R1) +
MEMBER(DSN8EP1) ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
BIND PLAN(DSN8EP1) -
PKLIST(DSN8EP!!.DSN8EP1, SAMPLOC.DSN8EP!!.DSN8EP1) -
ACTION(REPLACE) RETAIN +
ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
RUN PROGRAM(DSNTIAD) PLAN(DSNTIA!!) -
LIB('DSN!!0.RUNLIB.LOAD')
//********************************************************************
//* STEP 3: EXECUTE THE STORED PROCEDURE
//********************************************************************
//PH06PS03 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
RUN PROGRAM(DSN8EP1) PLAN(DSN8EP1) PARMS('/SAMPLOC')
END
//SYSIN DD *
-DISPLAY ARCHIVE;
-DISPLAY THREAD(*) DETAIL;
//*
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSNTEJ6S
THIS JCL PREPARES THE SAMPLE STORED PROCEDURE.
//********************************************************************
//* NAME = DSNTEJ6S
//*
//* DESCRIPTIVE NAME = DB2 SAMPLE APPLICATION
//*
//* PHASE 6
//*
//* LICENSED MATERIALS - PROPERTY OF IBM
//* 5650-DB2
//* (C) COPYRIGHT 1982, 2016 IBM CORP. ALL RIGHTS RESERVED.
//*
//* STATUS = VERSION 12
//*
//* FUNCTION = THIS JCL PREPARES THE SAMPLE STORED PROCEDURE.
//*
//* DEPENDENCIES:
//* (1) RUN THIS JOB AT THE SERVER SITE BEFORE RUNNING SAMPLE JOB
//* DSNTEJ6P AT THE CLIENT SITE
//*
//* CHANGE ACTIVITY =
//* 08/18/2014 Single-phase migration s21938_inst1 s21938
//*
1304 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
//********************************************************************
//JOBLIB DD DISP=SHR,DSN=DSN!!0.SDSNEXIT
// DD DISP=SHR,DSN=DSN!!0.SDSNLOAD
//*
//********************************************************************
//* STEP 1: DROP ANY EXISTING STORED PROCEDURE CALLED DSN.DSN8EP2
//********************************************************************
//PH06SS01 EXEC PGM=IKJEFT01,DYNAMNBR=20
//SYSTSPRT DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
RUN PROGRAM(DSNTIAD) PLAN(DSNTIA!!) -
LIB('DSN!!0.RUNLIB.LOAD') -
PARM('RC0')
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
//*
//********************************************************************
//* STEP 2: CREATE SAMPLE STORED PROCEDURE DSN8.DSN8EP2
//********************************************************************
//PH06SS02 EXEC PGM=IKJEFT01,DYNAMNBR=20
//SYSTSPRT DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
RUN PROGRAM(DSNTIAD) PLAN(DSNTIA!!) -
LIB('DSN!!0.RUNLIB.LOAD')
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
CREATE PROCEDURE
DSN8.DSN8EP2(
IN VARCHAR(4096) CCSID EBCDIC,
OUT INTEGER,
OUT INTEGER,
OUT INTEGER,
OUT VARCHAR(8320) CCSID EBCDIC )
LANGUAGE PLI
DETERMINISTIC
NO SQL
EXTERNAL NAME DSN8EP2
PARAMETER STYLE GENERAL WITH NULLS
COLLID DSN8EP!!
WLM ENVIRONMENT WLMENV
ASUTIME LIMIT 5
STAY RESIDENT NO
PROGRAM TYPE MAIN
SECURITY DB2
NO DBINFO
RESULT SET 0
COMMIT ON RETURN NO;
//*
//********************************************************************
//* STEP 3: PRE-COMPILE, COMPILE, AND LINK-EDIT THE STORED PROCEDURE
//********************************************************************
//PH06SS03 EXEC DSNHPLI,MEM=DSN8EP2,COND=(4,LT),
// PARM.PC='HOST(PLI),CCSID(37),STDSQL(NO),CONNECT(2)'
//PPLI.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8EP2),
// DISP=SHR
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8EP2),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8EP2),
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNRLI)
INCLUDE SYSLIB(DSNTIAR)
//*
//********************************************************************
//* STEP 4: BIND THE STORED PROCEDURE PACKAGE
//* NOTE: THIS STEP IS COMMENTED OUT FOR THE STORED
//* PROCEDURE SAMPLE APPLICATION BECAUSE IT CONTAINS
//* NO SQL STATEMENTS. IF YOUR STORED PROCEDURE
//* CONTAINS SQL STATEMENTS, YOU MUST BIND IT AS
//* A PACKAGE.
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1305
//********************************************************************
//*PH06SS04 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//*DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA,
//* DISP=SHR
//*SYSTSPRT DD SYSOUT=*
//*SYSTSIN DD *
//* DSN SYSTEM(DSN)
//* BIND PACKAGE(DSN8EP!!) MEMBER(DSN8EP2) APPLCOMPAT(V!!R1) +
//* ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
//*
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSNTEJ6D
THIS JCL PREPARES AND EXECUTES A SAMPLE APPLICATION PROGRAM, DSN8ED1, THAT
DEMONSTRATES HOW TO CALL A Db2 STORED PROCEDURE THAT RETURNS A RESULT SET.
//********************************************************************
//* NAME = DSNTEJ6D
//*
//* DESCRIPTIVE NAME = DB2 SAMPLE APPLICATION
//* PHASE 6
//* SAMPLE CALLER: STORED PROCEDURE WITH RESULT SET
//* C LANGUAGE
//*
//*
//* LICENSED MATERIALS - PROPERTY OF IBM
//* 5650-DB2
//* (C) COPYRIGHT 1982, 2016 IBM CORP. ALL RIGHTS RESERVED.
//*
//* STATUS = VERSION 12
//*
//* FUNCTION = THIS JCL PREPARES AND EXECUTES A SAMPLE APPLICATION
//* PROGRAM, DSN8ED1, THAT DEMONSTRATES HOW TO CALL A DB2
//* STORED PROCEDURE THAT RETURNS A RESULT SET.
//*
//* DSN8ED1 ACCEPTS A DB2 COMMAND FROM STANDARD INPUT
//* (SYSIN) AND PASSES IT AS A PARAMETER TO THE STORED
//* PROCEDURE WHICH RUNS ON A REMOTE DB2 SUBSYSTEM (SEE
//* DSNTEJ6T FOR DETAILS). THE STORED PROCEDURE PLACES THE
//* RESPONSES IN A RESULT SET AND DSN8ED1 EXTRACTS THEM AND
//* PRINTS THEM TO STANDARD OUTPUT (SYSPRINT).
//*
//* DEPENDENCIES:
//* (1) RUN SAMPLE JOB DSNTEJ6T AT THE SERVER SITE BEFORE RUNNING THIS
//* JOB; DSNTEJ6T PREPARES THE SAMPLE STORED PROC W/ RESULT SET
//* (2) RUN THIS JOB AT THE CLIENT SITE
//*
//*
//* CHANGE ACTIVITY =
//* 08/18/2014 Single-phase migration s21938_inst1 s21938
//*
//********************************************************************
//JOBLIB DD DSN=DSN!!0.SDSNEXIT,DISP=SHR
// DD DSN=DSN!!0.SDSNLOAD,DISP=SHR
// DD DSN=CEE.V!R!M!.SCEERUN,DISP=SHR
// DD DSN=DSN!!0.RUNLIB.LOAD,DISP=SHR
//*
//********************************************************************
//* STEP 1: PRE-COMPILE, COMPILE, AND LINK-EDIT THE CALLING PROGRAM
//********************************************************************
//PH06DS01 EXEC DSNHC,MEM=DSN8ED1,
// PARM.PC=('HOST(C),CCSID(1047),MARGINS(1,72),STDSQL(NO)',
// SOURCE,XREF),
// PARM.C='SOURCE LIST MAR(1,72) NORENT OPTFILE(DD:CCOPTS)',
// PARM.LKED='AMODE=31,RMODE=ANY,MAP,NORENT'
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8ED1),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8ED1),
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8ED1),
// DISP=SHR
//LKED.SYSIN DD *
1306 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
INCLUDE SYSLIB(DSNELI)
INCLUDE SYSLIB(DSNTIAR)
//*
//********************************************************************
//* STEP 2: BIND THE CALLING PROGRAM PACKAGE
//********************************************************************
//PH06DS02 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA,
// DISP=SHR
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
GRANT BIND, EXECUTE ON PLAN DSN8ED1
TO PUBLIC;
//SYSTSIN DD *
DSN SYSTEM(DSN)
BIND PACKAGE(DSN8ED!!) MEMBER(DSN8ED1) APPLCOMPAT(V!!R1) +
ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
BIND PACKAGE(SAMPLOC.DSN8ED!!) -
APPLCOMPAT(V!!R1) +
MEMBER(DSN8ED1) ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
BIND PLAN(DSN8ED1) -
PKLIST(DSN8ED!!.DSN8ED1, -
SAMPLOC.DSN8ED!!.DSN8ED1 -
SAMPLOC.DSN8ED!!.DSN8ED2) -
ACTION(REPLACE) RETAIN +
ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
RUN PROGRAM(DSNTIAD) PLAN(DSNTIA!!) -
LIB('DSN!!0.RUNLIB.LOAD')
//*
//********************************************************************
//* STEP 3: EXECUTE THE STORED PROCEDURE
//********************************************************************
//PH06DS03 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
RUN PROGRAM(DSN8ED1) PLAN(DSN8ED1) PARMS('/SAMPLOC')
END
//SYSIN DD *
-DISPLAY ARCHIVE;
-DISPLAY THREAD(*) DETAIL;
//*
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSNTEJ6T
THIS JCL PREPARES AND EXECUTES A SAMPLE APPLICATION PROGRAM, DSN8ED2, THAT
DEMONSTRATES A Db2 STORED PROCEDURE THAT RETURNS A RESULT SET.
//********************************************************************
//* DESCRIPTIVE NAME = DB2 SAMPLE APPLICATION
//* PHASE 6
//* SAMPLE STORED PROCEDURE WITH RESULT SET
//* C LANGUAGE
//*
//*
//* LICENSED MATERIALS - PROPERTY OF IBM
//* 5650-DB2
//* (C) COPYRIGHT 1982, 2016 IBM CORP. ALL RIGHTS RESERVED.
//*
//* STATUS = VERSION 12
//*
//* FUNCTION = THIS JCL PREPARES AND EXECUTES A SAMPLE APPLICATION
//* PROGRAM, DSN8ED2, THAT DEMONSTRATES A DB2 STORED
//* PROCEDURE THAT RETURNS A RESULT SET.
//*
//* DSN8ED2 ACCEPTS A DB2 COMMAND PASSED AS AN INPUT
//* PARAMETER FROM A CLIENT PROGRAM ON A REMOTE DB2
//* SUBSYSTEM. IT CALLS THE IFI UTILITY TO PROCESS THE
//* COMMAND AND PLACES THE RESPONSES IN A TEMPORARY DB2
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1307
//* TABLE SO THEY CAN BE RETURNED AS A RESULT SET TO THE
//* CLIENT.
//*
//* DEPENDENCIES:
//* (1) RUN THIS JOB AT THE SERVER SITE BEFORE RUNNING SAMPLE JOB
//* DSNTEJ6D AT THE CLIENT SITE
//*
//* CHANGE ACTIVITY =
//* 08/18/2014 Single-phase migration s21938_inst1 s21938
//*
//********************************************************************
//JOBLIB DD DSN=DSN!!0.SDSNEXIT,DISP=SHR
// DD DSN=DSN!!0.SDSNLOAD,DISP=SHR
// DD DSN=CEE.V!R!M!.SCEERUN,DISP=SHR
// DD DSN=DSN!!0.RUNLIB.LOAD,DISP=SHR
//*
//********************************************************************
//* STEP 1: DROP OBJECTS CREATED BY ANY PREVIOUS RUN OF DSNTEJ6T:
//* - SAMPLE STORED PROCEDURE DSN8.DSN8ED2
//* - GLOBAL TEMPORARY TABLE DSN8.DSN8ED2_RS_TBL
//********************************************************************
//PH06TS01 EXEC PGM=IKJEFT01,DYNAMNBR=20
//SYSTSPRT DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
RUN PROGRAM(DSNTIAD) PLAN(DSNTIA!!) -
LIB('DSN!!0.RUNLIB.LOAD') -
PARM('RC0')
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
//*
//********************************************************************
//* STEP 2: CREATE SAMPLE STORED PROCEDURE DSN8.DSN8ED2
//* AND GLOBAL TEMPORARY TABLE DSN8.DSN8ED2_RS_TBL
//********************************************************************
//PH06TS02 EXEC PGM=IKJEFT01,DYNAMNBR=20,
// COND=(4,LT)
//SYSTSPRT DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
RUN PROGRAM(DSNTIAD) PLAN(DSNTIA!!) -
LIB('DSN!!0.RUNLIB.LOAD')
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
CREATE PROCEDURE
DSN8.DSN8ED2(
IN VARCHAR(4096) CCSID EBCDIC,
OUT INTEGER,
OUT INTEGER,
OUT INTEGER,
OUT VARCHAR(880) CCSID EBCDIC )
LANGUAGE C
DETERMINISTIC
MODIFIES SQL DATA
EXTERNAL NAME DSN8ED2
PARAMETER STYLE GENERAL WITH NULLS
COLLID DSN8ED!!
WLM ENVIRONMENT WLMENV
ASUTIME LIMIT 50
STAY RESIDENT NO
PROGRAM TYPE MAIN
SECURITY DB2
NO DBINFO
RESULT SET 1
COMMIT ON RETURN NO;
1308 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
//*
//********************************************************************
//* STEP 3: PRE-COMPILE, COMPILE, AND LINK-EDIT THE STORED PROCEDURE
//********************************************************************
//PH06TS03 EXEC DSNHC,MEM=DSN8ED2,
// COND=(4,LT),
// PARM.PC=('HOST(C),CCSID(1047),MARGINS(1,72),STDSQL(NO)',
// SOURCE,XREF),
// PARM.C='SOURCE LIST MARGINS(1,72),RENT OPTFILE(DD:CCOPTS)',
// PARM.LKED='AMODE=31,RMODE=ANY,MAP,RENT'
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8ED2),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8ED2),
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8ED2),
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNRLI)
INCLUDE SYSLIB(DSNTIAR)
//*
//********************************************************************
//* STEP 4: BIND THE STORED PROCEDURE PACKAGE
//********************************************************************
//PH06TS04 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA,
// DISP=SHR
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
BIND PACKAGE(DSN8ED!!) APPLCOMPAT(V!!R1) +
MEMBER(DSN8ED2) ACT(REP) -
ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
//*
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSNTEJ61
This JCL creates a sample application, DSN8EC1, that demonstrates a Db2 stored procedure for IMS
ODBA.
//********************************************************************
//* Name = DSNTEJ61
//*
//* Descriptive Name = DB2 Sample Application
//* Phase 6
//* Sample Stored Procedure for IMS ODBA
//* Cobol Language
//*
//*
//* LICENSED MATERIALS - PROPERTY OF IBM
//* 5650-DB2
//* (C) COPYRIGHT 1982, 2016 IBM Corp. All Rights Reserved.
//*
//* STATUS = Version 12
//*
//* Function = This JCL creates a sample application, DSN8EC1, that
//* demonstrates a DB2 stored procedure for IMS ODBA.
//*
//* DSN8EC1 can be used to insert, retrieve, update,
//* and delete rows in the IMS IVP telephone directory
//* database, DFSIVD1.
//*
//* DSN8EC1 has one input-only parm, five input/output
//* parms, and three output-only parms.
//* - Input only:
//* (1) TDBCTLID : ID of IMS subsystem where data resides
//* - Input/Output:
//* (2) COMMAND : Action to be taken, or action taken
//* - ADD: Add an entry
//* - DEL: Delete an entry
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1309
//* - DIS: Retrieve an entry
//* - UPD: Update an entry
//* (3) LAST_NAME : Operand for, or result of, COMMAND
//* (4) FIRST_NAME: " " " " " "
//* (5) EXTENSION : " " " " " "
//* (6) ZIP-CODE : " " " " " "
//* - Output only:
//* (7) AIBRETRN : Return code from IMS AIB
//* (8) AIBREASN : Reason code from IMS AIB
//* (9) ERROR-CALL: DL/I command executed
//*
//*
//* Dependencies:
//* (1) Run this job at the server site before running sample job
//* DSNTEJ62 at the client site
//* (2) The server site must have an IMS subsystem running IMS/ESA V6
//* or a subsequent release
//* (3) This IMS subsystem must have the following IMS IVP parts
//* available
//* (A) DFSIVD1, the IMS IVP telephone directory database
//* (B) DFSIVP64, the IMS IVP Cobol PSB for BMP access to DFSIVD1
//* (4) Specify the id for this IMS subsystem in DB2 sample job
//* DSNTEJ62, step PH062S03
//* (5) The server site must also have a WLM environment started by
//* a proc that references the IMS reslib in both the STEPLIB DD
//* and the DFSRESLB DD. See the DB2 Installation Guide for more
//* information.
//* (6) Before running this job, verify that this WLM environment is
//* the one specified in the CREATE PROCEDURE statement in step
//* PH061S01.
//*
//* Change Activity =
//* 08/18/2014 Single-phase migration s21938_inst1 s21938
//*
//********************************************************************
//JOBLIB DD DSN=DSN!!0.SDSNEXIT,DISP=SHR
// DD DSN=DSN!!0.SDSNLOAD,DISP=SHR
// DD DSN=CEE.V!R!M!.SCEERUN,DISP=SHR
// DD DSN=DSN!!0.RUNLIB.LOAD,DISP=SHR
//*
//********************************************************************
//* STEP 1: Drop the sample ODBA stored procedure, DSN8.DSN8EC1
//********************************************************************
//PH061S01 EXEC PGM=IKJEFT01,DYNAMNBR=20
//SYSTSPRT DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
RUN PROGRAM(DSNTIAD) PLAN(DSNTIA!!) -
LIB('DSN!!0.RUNLIB.LOAD') -
PARM('RC0')
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
//*
//********************************************************************
//* STEP 2: Create the sample ODBA stored procedure, DSN8.DSN8EC1
//********************************************************************
//PH061S02 EXEC PGM=IKJEFT01,DYNAMNBR=20
//SYSTSPRT DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
RUN PROGRAM(DSNTIAD) PLAN(DSNTIA!!) -
LIB('DSN!!0.RUNLIB.LOAD')
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
CREATE PROCEDURE
DSN8.DSN8EC1(
IN CHAR(8) CCSID EBCDIC,
INOUT CHAR(8) CCSID EBCDIC,
INOUT CHAR(10) CCSID EBCDIC,
INOUT CHAR(10) CCSID EBCDIC,
INOUT CHAR(10) CCSID EBCDIC,
INOUT CHAR(7) CCSID EBCDIC,
OUT INT,
OUT INT,
1310 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
OUT CHAR(4) CCSID EBCDIC )
FENCED
RESULT SETS 0
EXTERNAL NAME DSN8EC1
LANGUAGE COBOL
PARAMETER STYLE GENERAL
NOT DETERMINISTIC
NO SQL
NO DBINFO
NO COLLID
WLM ENVIRONMENT WLMENV
ASUTIME LIMIT 50
STAY RESIDENT NO
PROGRAM TYPE MAIN
SECURITY DB2
RUN OPTIONS 'TRAP(OFF),RPTOPTS(OFF),TERMTHDAC((QUIET),NONOVR)'
COMMIT ON RETURN NO;
//*
//********************************************************************
//* Step 3: Pre-compile, compile, and link-edit the stored procedure
//********************************************************************
//PH061S03 EXEC DSNHICOB,MEM=DSN8EC1,
// COND=(4,LT),
// PARM.PC=('HOST(IBMCOB)',APOST,APOSTSQL,SOURCE,
// NOXREF,'SQL(DB2)','DEC(31)'),
// PARM.COB=(NOSEQUENCE,QUOTE,RENT,'PGMNAME(LONGUPPER)')
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8EC1),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8EC1),
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8EC1),
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNRLI)
NAME DSN8EC1(R)
//*
//********************************************************************
//* Step 4: Bind the stored procedure package
//* Note: This step is commented out for sample stored
//* procedure DSN8EC1 because it contains no SQL
//* statements. If your stored procedure contains
//* SQL statements, you must bind it as a package.
//********************************************************************
//**PH061S04 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//**DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA,
//** DISP=SHR
//**SYSTSPRT DD SYSOUT=*
//**SYSPRINT DD SYSOUT=*
//**SYSUDUMP DD SYSOUT=*
//**SYSTSIN DD *
//** DSN SYSTEM(DSN)
//** BIND PACKAGE(DSN8EC!!) MEMBER(DSN8EC1) APPLCOMPAT(V!!R1) +
//** ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
//*
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSNTEJ62
This JCL prepares and executes a sample application program, DSN8EC2, that demonstrates how to call a
Db2 stored procedure for IMS ODBA.
//********************************************************************
//* Name = DSNTEJ62
//*
//* Descriptive Name = DB2 Sample Application
//* Phase 6
//* Sample Client: Stored procedure for IMS ODBA
//* Cobol Language
//*
//*
//* LICENSED MATERIALS - PROPERTY OF IBM
//* 5650-DB2
//* (C) COPYRIGHT 1982, 2016 IBM Corp. All Rights Reserved.
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1311
//*
//* STATUS = Version 12
//*
//* Function = This JCL prepares and executes a sample application
//* program, DSN8EC2, that demonstrates how to call a DB2
//* stored procedure for IMS ODBA. The results are
//* directed to the SYSOUT DD.
//*
//* DSN8EC2 accepts a runtime parameter in step PH062S03
//* that specifies -both- the DB2 server location name
//* where the stored procedure is registered -and- the id
//* of the IMS subsystem where the ODBA activity is to
//* occur. You must modify this job to provide the IMS
//* subsystem id. See step PH062S03 for details.
//*
//* Dependencies:
//* (1) Run sample job DSNTEJ61 at the server site before running this
//* job; DSNTEJ61 prepares the sample stored proc for IMS ODBA
//* (2) Modify this job as directed in step PH062S03
//* (3) Run this job at the client site
//*
//*
//* Change activity =
//* 08/18/2014 Single-phase migration s21938_inst1 s21938
//*
//********************************************************************
//JOBLIB DD DSN=DSN!!0.SDSNEXIT,DISP=SHR
// DD DSN=DSN!!0.SDSNLOAD,DISP=SHR
// DD DSN=CEE.V!R!M!.SCEERUN,DISP=SHR
// DD DSN=DSN!!0.RUNLIB.LOAD,DISP=SHR
//*
//********************************************************************
//* Step 1: Pre-compile, compile, and link-edit the client program
//********************************************************************
//PH062S01 EXEC DSNHICOB,MEM=DSN8EC2,
// COND=(4,LT),
// PARM.PC=('HOST(IBMCOB)',APOST,APOSTSQL,SOURCE,
// NOXREF,'SQL(DB2)','DEC(31)'),
// PARM.COB=(NOSEQUENCE,QUOTE,RENT,'PGMNAME(LONGUPPER)'),
// PARM.LKED='AMODE=31,RMODE=ANY,MAP'
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8EC2),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8EC2),
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8EC2),
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNELI)
INCLUDE SYSLIB(DSNTIAR)
//*
//********************************************************************
//* Step 2: Bind the client program package and plan
//********************************************************************
//PH062S02 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA,
// DISP=SHR
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
BIND PACKAGE(DSN8EC!!) MEMBER(DSN8EC2) APPLCOMPAT(V!!R1) +
ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
BIND PACKAGE(SAMPLOC.DSN8EC!!) APPLCOMPAT(V!!R1) +
MEMBER(DSN8EC2) ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
BIND PLAN(DSN8EC2) -
PKLIST(DSN8EC!!.DSN8EC2, -
SAMPLOC.DSN8EC!!.DSN8EC2) -
ACTION(REPLACE) RETAIN +
ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
RUN PROGRAM(DSNTIAD) PLAN(DSNTIA!!) -
LIB('DSN!!0.RUNLIB.LOAD')
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
GRANT BIND, EXECUTE ON PLAN DSN8EC2
TO PUBLIC;
//*
//********************************************************************
//* STEP 3: Invoke the client for the IMS ODBA stored procedure
//* Note: The PARMS keyword in the RUN statement below accepts a
1312 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
//* single argument that specifies the DB2 server location
//* name -and- the IMS subsystem id, in that order and
//* separated by a single blank character.
//*
//* Example: PARMS('SANTA_TERESA_LAB IMSP')
//*
//* Verify that the PARMS keyword below specifies the name
//* of the DB2 server location name where you ran DSNTEJ61.
//*
//* Change the string ?IMSID? to the id of the IMS subsystem
//* where you want the ODBA-directed activity to occur. This
//* subsystem must reside on the same server as the DB2
//* server and must be running IMS/ESA V6 or a subsequent
//* release.
//*
//********************************************************************
//PH062S03 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
RUN PROGRAM(DSN8EC2) -
PLAN(DSN8EC2) -
PARMS('SAMPLOC ?IMSID?')
END
//*
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSNTEJ63
This JCL prepares DSN8ES1, a sample SQL procedure that accepts a department number and returns
salary and bonus data for employees in that department from the Db2 sample data base.
//*********************************************************************
//* Name = DSNTEJ63
//*
//* Descriptive Name =
//* DB2 Sample Application
//* Phase 6
//* Sample SQL Procedure
//* SQL Procedure Language
//*
//*
//* LICENSED MATERIALS - PROPERTY OF IBM
//* 5650-DB2
//* (C) COPYRIGHT 1982, 2016 IBM Corp. All Rights Reserved.
//*
//* STATUS = Version 12
//*
//* Function =
//* This JCL prepares DSN8ES1, a sample SQL procedure that
//* accepts a department number and returns salary and bonus data
//* for employees in that department from the DB2 sample data base.
//*
//* Pseudocode =
//* PH063S01 Step Drop objects created by prior runs of this job
//* PH063S02 Step Prepare DSN8ES1 load module from DSN8ES1 src
//* PH063S03 Step Bind DSN8ES1 package in collection DSN8ES!!
//* Register the stored procedure using generated
//* DDL from the precompiler
//* Create the global temporary table required by
//* the result set
//*
//* Dependencies =
//* (1) This job requires the DB2-provided JCL procedure DSNHSQL
//* (2) Run this job prior to running the client job DSNTEJ64
//*
//* Notes =
//*
//* Change Activity =
//* 08/18/2014 Single-phase migration s21938_inst1 s21938
//*
//*********************************************************************
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1313
//*
//JOBLIB DD DSN=DSN!!0.SDSNEXIT,DISP=SHR
// DD DSN=DSN!!0.SDSNLOAD,DISP=SHR
// DD DSN=CEE.V!R!M!.SCEERUN,DISP=SHR
// DD DSN=DSN!!0.RUNLIB.LOAD,DISP=SHR
//*
//*
//*********************************************************************
//* STEP 1: Drop any pre-existing entries for stored proc DSN8ES1
//* and the global temporary table for its result set
//*********************************************************************
//PH063S01 EXEC PGM=IKJEFT01,DYNAMNBR=20
//SYSTSPRT DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
RUN PROGRAM(DSNTIAD) PLAN(DSNTIA!!) -
LIB('DSN!!0.RUNLIB.LOAD') -
PARM('RC0')
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
//*
//*********************************************************************
//* Step 2: Pre-compile, compile, and link-edit the stored procedure
//*********************************************************************
//PH063S02 EXEC DSNHSQL,MEM=DSN8ES1,
// COND=(4,LT),
// PARM.PC=('HOST(SQL),SOURCE,XREF,MAR(1,72),CCSID(37)',
// 'STDSQL(NO)'),
// PARM.PCC=('HOST(C),SOURCE,XREF,MAR(1,80),CCSID(37)',
// 'TWOPASS,STDSQL(NO)'),
// PARM.C='SOURCE LIST MARGINS(1,80) NOSEQ LO RENT
// LOCALE("SAA") OPTFILE(DD:CCOPTS)',
// PARM.LKED='AMODE=31,RMODE=ANY,MAP,RENT'
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.NEW.SDSNSAMP(DSN8ES1),
// DISP=SHR
//PC.SYSUT2 DD DSN=&&SPDDL,DISP=(,PASS),
// UNIT=SYSDA,SPACE=(TRK,1),
// DCB=(RECFM=FB,LRECL=80)
//PCC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8ES1),
// DISP=SHR
//PCC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8ES1),
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNRLI)
NAME DSN8ES1(R)
//*
//*********************************************************************
//* STEP 3: Create the global temp table for DSN8ES1's result set
//* Register DSN8ES1 in SYSIBM.SYSROUTINES
//* Bind the package for DSN8ES1
//*********************************************************************
//PH063S03 EXEC PGM=IKJEFT01,DYNAMNBR=20,
// COND=(4,LT)
//DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8ES1),
// DISP=SHR
//SYSTSPRT DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
RUN PROGRAM(DSNTIAD) PLAN(DSNTIA!!) -
LIB('DSN!!0.RUNLIB.LOAD') -
PARM('SQLTERM(%)')
BIND PACKAGE(DSN8ES!!) APPLCOMPAT(V!!R1) +
QUALIFIER(DSN8!!0) -
MEMBER(DSN8ES1) -
ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
END
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSIN DD *
1314 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
SET CURRENT SQLID = 'SYSADM'
%
CREATE GLOBAL TEMPORARY TABLE
DSN8.DSN8ES1_RS_TBL
( RS_SEQUENCE INTEGER NOT NULL,
RS_EMPNO CHAR(6) NOT NULL,
RS_FIRSTNME CHAR(12) NOT NULL,
RS_LASTNAME CHAR(15) NOT NULL,
RS_SALARY DECIMAL(9, 2) NOT NULL,
RS_BONUS DECIMAL(9, 2) NOT NULL )
CCSID EBCDIC
%
// DD DSN=&&SPDDL,DISP=(OLD,DELETE) <- From preceding step
//*
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSNTEJ64
This JCL prepares and executes DSN8ED3, a sample caller for the sample SQL procedure DSN8ES1.
//*********************************************************************
//* Name = DSNTEJ64
//*
//* Descriptive Name =
//* DB2 Sample Application
//* Phase 6
//* Sample Caller for sample SQL Procedure DSN8ES1
//* C Language
//*
//* LICENSED MATERIALS - PROPERTY OF IBM
//* 5650-DB2
//* (C) COPYRIGHT 1982, 2016 IBM CORP. ALL RIGHTS RESERVED.
//*
//* Status = VERSION 12
//*
//* Function =
//* This JCL prepares and executes DSN8ED3, a sample caller for the
//* sample SQL procedure DSN8ES1. DSN8ED3 passes a sample
//* department number to DSN8ES1, then processes what is returned:
//* - Parameters containing:
//* - The total earnings (salaries and bonuses) of employees in
//* that department
//* - The number of employees who got a bonus
//* - A result set containing a row of data (serial no, first and
//* last name, salary, and bonus) for each employee who got a
//* bonus
//*
//* Pseudocode =
//* PH064S01 Step Prepare DSN8ED3 load module from DSN8ED3 src
//* PH064S02 Step Bind DSN8ED3 package in collection DSN8ED!!
//* Bind DSN8ED3 plan from DSN8ED!! and DSN8ES!!
//* collection ids
//* PH064S03 Step Run DSN8ED3 to call stored procedure DSN8ES1
//*
//* Dependencies =
//* (1) Run sample job DSNTEJ63 prior to running this job
//* (2) This job requires the DB2-provided JCL procedure DSNHC
//*
//* Notes =
//*
//* Change Activity =
//* 10/16/2013 Don't use prelinker by default PI13612 DM1812
//* 08/18/2014 Single-phase migration s21938_inst1 s21938
//*
//*********************************************************************
//JOBLIB DD DSN=DSN!!0.SDSNEXIT,DISP=SHR
// DD DSN=DSN!!0.SDSNLOAD,DISP=SHR
// DD DSN=CEE.V!R!M!.SCEERUN,DISP=SHR
// DD DSN=DSN!!0.RUNLIB.LOAD,DISP=SHR
//*
//*********************************************************************
//* Step 1: Pre-compile, compile, and link-edit DSN8ED3
//*********************************************************************
//PH064S01 EXEC DSNHC,MEM=DSN8ED3,
// PARM.PC=('HOST(C),CCSID(1047),MARGINS(1,72),STDSQL(NO)',
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1315
// SOURCE,XREF),
// PARM.C='SOURCE LIST MAR(1,72) LO RENT OPTFILE(DD:CCOPTS)',
// PARM.LKED='AMODE=31,RMODE=ANY,MAP,NORENT,UPCASE'
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8ED3),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8ED3),
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8ED3),
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNELI)
INCLUDE SYSLIB(DSNTIAR)
//*
//*********************************************************************
//* Step 2: Bind DSN8ED3's PLAN from its package and DSN8ES1's pkg
//*********************************************************************
//PH064S02 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA,
// DISP=SHR
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
GRANT BIND, EXECUTE ON PLAN DSN8ED3
TO PUBLIC;
//SYSTSIN DD *
DSN SYSTEM(DSN)
BIND PACKAGE(DSN8ED!!) MEMBER(DSN8ED3) APPLCOMPAT(V!!R1) +
ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
BIND PACKAGE(SAMPLOC.DSN8ED!!) APPLCOMPAT(V!!R1) +
MEMBER(DSN8ED3) ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
BIND PLAN(DSN8ED3) -
PKLIST(DSN8ED!!.DSN8ED3, -
SAMPLOC.DSN8ED!!.DSN8ED3, -
SAMPLOC.DSN8ES!!.DSN8ES1) -
ACTION(REPLACE) RETAIN +
ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
RUN PROGRAM(DSNTIAD) PLAN(DSNTIA!!) -
LIB('DSN!!0.RUNLIB.LOAD')
//*
//*********************************************************************
//* STEP 3: Get Bonus and Salary report for department D11
//*********************************************************************
//PH064S03 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
RUN PROGRAM(DSN8ED3) PLAN(DSN8ED3) PARMS('/D11 SAMPLOC')
END
//*
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSNTEJ65
This JCL does the following.
//*********************************************************************
//* Name = DSNTEJ65
//*
//* Descriptive Name =
//* DB2 Sample Application
//* Phase 6
//* - Sample C Caller for DB2 SQL Procedures Processor (DSNTPSMP)
//* - Sample SQL Procedure for DSNTPSMP to prepare
//* - Sample C Caller for SQL Procedure prepared by DSNTPSMP
//*
//*
//* LICENSED MATERIALS - PROPERTY OF IBM
//* 5650-DB2
//* (C) COPYRIGHT 1982, 2016 IBM CORP. ALL RIGHTS RESERVED.
1316 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
//*
//* STATUS = VERSION 12
//*
//* Function =
//* This JCL does the following:
//* (1) Prepares and binds DSN8ED4, a sample caller for DSNTPSMP,
//* the DB2 Stored Procedures Processor.
//* (2) Invokes DSN8ED4 to prequalify that the server has DSNTPSMP
//* at the proper interface level supported by the this client
//* (3) Invokes DSN8ED4 to pass a sample SQL Procedure, DSN8.DSN8ES2,
//* to DSNTPSMP for preparation
//* (4) Prepares, binds, and executes DSN8ED5, a sample caller for
//* DSN8.DSN8ES2
//*
//* Pseudocode =
//* PH065S01 Step Prepare DSN8ED4 (sample caller of DSNTPSMP)
//* PH065S02 Step Bind DSN8ED4
//* PH065S03 Step Call DSN8ED4 to request DSNTPSMP QUERYLEVEL
//* PH065S04 Step Call DSN8ED4 to pass DSN8.DSN8ES2 to DSNTPSMP
//* PH065S05 Step Prepare DSN8ED5 (sample caller of DSN8.DSN8ES2)
//* PH065S06 Step Bind DSN8ED5
//* PH065S07 Step Call DSN8ED5 to call DSN8.DSN8ES2
//*
//* Dependencies =
//* (1) Sample program requires DSNTPSMP (the DB2 SQL Procedures
//* Processor)
//*
//* Notes =
//*
//* Change Activity =
//* 10/16/2013 Don't use prelinker by default PI13612 DM1812
//* 08/18/2014 Single-phase migration s21938_inst1 s21938
//*
//*********************************************************************
//JOBLIB DD DISP=SHR,DSN=DSN!!0.SDSNEXIT
// DD DISP=SHR,DSN=DSN!!0.SDSNLOAD
// DD DISP=SHR,DSN=CEE.V!R!M!.SCEERUN
// DD DISP=SHR,DSN=DSN!!0.RUNLIB.LOAD
//*
//*********************************************************************
//* Step 1: Prepare DSN8ED4, caller for DSNTPSMP
//*********************************************************************
//PH065S01 EXEC DSNHC,MEM=DSN8ED4,
// PARM.PC=('HOST(C),CCSID(1047),MARGINS(1,72),STDSQL(NO)',
// SOURCE,XREF),
// PARM.C='SOURCE LIST MAR(1,72) LO RENT OPTFILE(DD:CCOPTS)',
// PARM.LKED='AMODE=31,RMODE=ANY,MAP,NORENT,UPCASE'
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8ED4),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8ED4),
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8ED4),
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNELI)
INCLUDE SYSLIB(DSNTIAR)
//*
//*********************************************************************
//* Step 2: Bind DSN8ED4's PLAN
//*********************************************************************
//PH065S02 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//DBRMLIB DD DISP=SHR,DSN=DSN!!0.DBRMLIB.DATA
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
GRANT BIND, EXECUTE ON PLAN DSN8ED4
TO PUBLIC;
//SYSTSIN DD *
DSN SYSTEM(DSN)
BIND PACKAGE(DSN8ED!!) MEMBER(DSN8ED4) APPLCOMPAT(V!!R1) +
ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
BIND PACKAGE(SAMPLOC.DSN8ED!!) MEMBER(DSN8ED4) -
APPLCOMPAT(V!!R1) +
ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
BIND PLAN(DSN8ED4) -
PKLIST(DSN8ED!!.DSN8ED4, -
SAMPLOC.DSN8ED!!.DSN8ED4, -
SAMPLOC.DSNREXCS.DSNREXX) -
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1317
ACTION(REPLACE) RETAIN +
ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
RUN PROGRAM(DSNTIAD) PLAN(DSNTIA!!) -
LIB('DSN!!0.RUNLIB.LOAD')
END
//*
//*********************************************************************
//* STEP 3: Invoke DSN8ED4 to pass a QUERYLEVEL request to DSNTPSMP.
//* This is a prequalification that the server has a DSNTPSMP
//* at the correct Interface level for our DSN8ED4 client.
//* Parms: (* used as place holders)
//* (1) QUERYLEVEL
//* (2) *
//* (3) *
//* (4) (optional) name of server where DSNTPSMP is to be run
//* Note: DSN8ED4 requires all the same definitions be present
//* as on a BUILD request, even though only the function
//* request QUERYLEVEL is passed to DSNTPSMP.
//*********************************************************************
//PH065S03 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
RUN PROGRAM(DSN8ED4) PLAN(DSN8ED4) -
PARMS('QUERYLEVEL * * SAMPLOC')
END
//PCOPTS DD *
//COPTS DD *
//PLKDOPTS DD *
//LKEDOPTS DD *
//BINDOPTS DD *
//SQLIN DD *
//*
//REPORT01 DD SYSOUT=*,DCB=(RECFM=FBA)
//REPORT02 DD SYSOUT=*
//REPORT03 DD SYSOUT=*
//REPORT04 DD SYSOUT=*
//REPORT05 DD SYSOUT=*
//REPORT06 DD SYSOUT=*
//*
//*********************************************************************
//* STEP 4: Invoke DSN8ED4 to pass sample SQL Procedure DSN8.DSN8ES2
//* to DSNTPSMP
//* Parms:
//* (1) operation to be performed by DSNTPSMP
//* (2) schema.name of SQL proc to be prepared by DSNTPSMP
//* (3) SQL authid to be used when calling DSNTPSMP
//* (4) (optional) name of server where DSNTPSMP is to be run
//* Note: Options passed in the PCOPTS, COPTS, PLKDOPTS, and
//* BINDOPTS DDs can span more than one input record.
//* Do not use continuation characters (+ or -) to
//* continue BIND options onto the next BINDOPTS record
//*********************************************************************
//PH065S04 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
RUN PROGRAM(DSN8ED4) PLAN(DSN8ED4) -
PARMS('REBUILD DSN8.DSN8ES2 AUTHID SAMPLOC')
END
//PCOPTS DD *
SOURCE,XREF,MAR(1,80),STDSQL(NO)
//COPTS DD *
SOURCE LIST MAR(1,80) NOSEQ LO RENT
//PLKDOPTS DD *
//LKEDOPTS DD *
AMODE=31,RMODE=ANY,MAP,RENT
//BINDOPTS DD *
PACKAGE(DSN8ES!!)
QUALIFIER(DSN8!!0) ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
//SQLIN DD DSN=DSN!!0.NEW.SDSNSAMP(DSN8ES2),
// DISP=SHR
//*
//REPORT01 DD SYSOUT=*,DCB=(RECFM=FBA)
//REPORT02 DD SYSOUT=*
//REPORT03 DD SYSOUT=*
//REPORT04 DD SYSOUT=*
//REPORT05 DD SYSOUT=*
1318 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
//REPORT06 DD SYSOUT=*
//*
//*********************************************************************
//* Step 5: Prepare DSN8ED5, sample caller of DSN8.DSN8ES2
//*********************************************************************
//PH065S05 EXEC DSNHC,MEM=DSN8ED5,COND=(4,LT),
// PARM.PC=('HOST(C),CCSID(1047),MARGINS(1,72),STDSQL(NO)',
// SOURCE,XREF),
// PARM.C='SOURCE LIST MAR(1,72) LO RENT OPTFILE(DD:CCOPTS)',
// PARM.LKED='AMODE=31,RMODE=ANY,MAP,NORENT,UPCASE'
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8ED5),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8ED5),
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8ED5),
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNELI)
INCLUDE SYSLIB(DSNTIAR)
//*
//*********************************************************************
//* Step 6: Bind DSN8ED5's PLAN
//*********************************************************************
//PH065S06 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//DBRMLIB DD DISP=SHR,DSN=DSN!!0.DBRMLIB.DATA
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
GRANT BIND, EXECUTE ON PLAN DSN8ED5
TO PUBLIC;
//SYSTSIN DD *
DSN SYSTEM(DSN)
BIND PACKAGE(DSN8ED!!) MEMBER(DSN8ED5) APPLCOMPAT(V!!R1) +
ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
BIND PACKAGE(SAMPLOC.DSN8ED!!) MEMBER(DSN8ED5) -
APPLCOMPAT(V!!R1) +
ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
BIND PLAN(DSN8ED5) -
PKLIST(DSN8ED!!.DSN8ED5, -
SAMPLOC.DSN8ED!!.DSN8ED5, -
SAMPLOC.DSN8ES!!.*) -
ACTION(REPLACE) RETAIN +
ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
RUN PROGRAM(DSNTIAD) PLAN(DSNTIA!!) -
LIB('DSN!!0.RUNLIB.LOAD')
END
//*
//*********************************************************************
//* STEP 7: Invoke DSN8ED5 to call sample SQL Procedure DSN8.DSN8ES2
//*********************************************************************
//PH065S07 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
RUN PROGRAM(DSN8ED5) PLAN(DSN8ED5) -
PARMS('1500.00 SAMPLOC')
END
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSNTEJ6W
This JCL does the following.
//*
//* DB2 Sample Application
//* Phase 6
//* Sample caller for Stored Procedure WLM_REFRESH
//* IBM C/C++ for z/OS
//*
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1319
//* Licensed Materials - Property of IBM
//* 5650-DB2
//* (C) COPYRIGHT 1982, 2016 IBM Corp. All Rights Reserved.
//*
//* STATUS = Version 12
//*
//* Function =
//* This JCL does the following:
//* * Prepares and executes DSN8ED6, a sample caller of the
//* WLM_REFRESH stored procedure. WLM_REFRESH refreshes a
//* WLM environment specified as an input parameter using an
//* authorization ID also specified as an input parameter. The
//* authorization ID must have READ access on a resource profile
//* called !DSN!.WLM_REFRESH.!WLMENV!
//* Use job DSNTIJRA job step DSNTWR to create and permit access
//* to this resource profile.
//* * Optional: Prepares DSNTWR and DSNTWRE, external modules for
//* WLM_REFRESH. These modules are provided in SDSNLOAD so
//* preparing them is required only if you maintain a customized
//* copy of DSNTWRS, the sample source code for DSNTWR, or
//* DSNTWRE, the sample source code for DSNTWRE.
//*
//* Pseudocode =
//* PH06WS00 Step Optional: Prepare DSNTWRE, a program for
//* getting the DB2 Environment Info Block (EIB)
//* -> Uncomment and run this step if you want to
//* override the DB2-supplied DSNTWRE module
//* PH06WS01 Step Optional: Prepare DSNTWR, the external module
//* for SYSPROC.WLM_REFRESH
//* -> Uncomment and run this step if you want to
//* override the DB2-supplied DSNTWR module
//* PH06WS02 Step Optional: Bind the package for DSNTWR
//* -> Uncomment and run this step only if you
//* also uncomment and run the step PH06WS01
//* PH06WS03 Step Prepare DSN8ED6
//* PH06WS04 Step Bind the plan and package for DSN8ED6
//* PH06WS05 Step Invoke DSN8ED6
//*
//* Dependencies =
//* (1) This job requires the DB2-provided JCL procedures DSNHASM and
//* DSNHC
//* (2) Run this job only after running jobs DSNTIJTM and DSNTIJRT
//* (3) The DSN8ED6 program receives parameters that contain the name
//* of the WLM environment to be refreshed and the authorization
//* ID to be used for the request. The authorization ID must have
//* READ access an a resource profile called
//* !DSN!.WLM_REFRESH.!WLMENV!
//* Use job DSNTIJRA job step DSNTWR to create and permit access
//* to this resource profile.
//*
//* Notes =
//*
//* Change Activity =
//* 10/16/2013 Don't use prelinker by default PI13612 DM1812
//* 08/18/2014 Single-phase migration s21938_inst1 s21938
//*
//*********************************************************************
//*
//JOBLIB DD DISP=SHR,DSN=DSN!!0.SDSNEXIT
// DD DISP=SHR,DSN=DSN!!0.SDSNLOAD
// DD DISP=SHR,DSN=CEE.V!R!M!.SCEERUN
//*
//* //*
//* //* Step 0 (Optional): Prepare DSNTWRE, a program that gets
//* //* the DB2 group attach name
//* //*
//* //PH06WS00 EXEC DSNHASM,COND=(4,LT),
//* // MEM=DSNTWRE,
//* // PARM.PC='HOST(ASM),STDSQL(NO)',
//* // PARM.ASM='RENT,OBJECT,NODECK',
//* // PARM.LKED='LIST,XREF,AMODE=31,RMODE=ANY,RENT'
//* //PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSNTWRE),
//* // DISP=SHR
//* //PC.SYSLIB DD DSN=DSN!!0.SDSNSAMP,
//* // DISP=SHR
//* //PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSNTWRE),
//* // DISP=SHR
//* //ASM.SYSLIB DD DSN=SYS1.MACLIB,
//* // DISP=SHR
//* // DD DSN=CEE.V!R!M!.SCEEMAC,
//* // DISP=SHR
//* // DD DSN=DSN!!0.SDSNMACS,
1320 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
//* // DISP=SHR
//* // DD DSN=DSN!!0.SDSNSAMP,
//* // DISP=SHR
//* //LKED.SYSLMOD DD DSN=DSN!!0.SDSNEXIT(DSNTWRE),
//* // DISP=SHR
//* //LKED.SYSLIB DD DSN=CEE.V!R!M!.SCEELKED,
//* // DISP=SHR
//* // DD DSN=CEE.V!R!M!.SCEERUN,
//* // DISP=SHR
//* // DD DSN=CEE.V!R!M!.SCEESPC,
//* // DISP=SHR
//* // DD DSN=CEE.V!R!M!.SCEESPCO,
//* // DISP=SHR
//* // DD DSN=DSN!!0.SDSNLOAD,
//* // DISP=SHR
//* //LKED.SYSIN DD *
//* INCLUDE SYSLIB(DSNRLI)
//* NAME DSNTWRE(R)
//* /*
//* //*
//* //* Step 1 (Optional): Prepare DSNTWR, the external module for
//* //* WLM_REFRESH
//* //*
//* //PH06WS01 EXEC DSNHASM,COND=(4,LT),
//* // MEM=DSNTWR,
//* // PARM.PC='HOST(ASM),STDSQL(NO)',
//* // PARM.ASM='RENT,OBJECT,NODECK',
//* // PARM.LKED='LIST,XREF,AMODE=31,RMODE=ANY,RENT'
//* //PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSNTWR),
//* // DISP=SHR
//* //PC.SYSLIB DD DSN=DSN!!0.SDSNSAMP,
//* // DISP=SHR
//* //PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSNTWRS),
//* // DISP=SHR
//* //ASM.SYSLIB DD DSN=SYS1.MACLIB,
//* // DISP=SHR
//* // DD DSN=CEE.V!R!M!.SCEEMAC,
//* // DISP=SHR
//* // DD DSN=DSN!!0.SDSNMACS,
//* // DISP=SHR
//* // DD DSN=DSN!!0.SDSNSAMP,
//* // DISP=SHR
//* //LKED.SYSLMOD DD DSN=DSN!!0.SDSNEXIT(DSNTWR),
//* // DISP=SHR
//* //LKED.SYSLIB DD DSN=CEE.V!R!M!.SCEELKED,
//* // DISP=SHR
//* // DD DSN=CEE.V!R!M!.SCEERUN,
//* // DISP=SHR
//* // DD DSN=CEE.V!R!M!.SCEESPC,
//* // DISP=SHR
//* // DD DSN=CEE.V!R!M!.SCEESPCO,
//* // DISP=SHR
//* // DD DSN=DSN!!0.SDSNLOAD,
//* // DISP=SHR
//* //LKED.SYSIN DD *
//* INCLUDE SYSLIB(DSNRLI)
//* SETCODE AC(1)
//* NAME DSNTWR(R)
//* /*
//* //*
//* //* Step 2 (Optional): Bind the package for DSNTWR
//* //*
//* //PH06WS02 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//* //DBRMLIB DD DISP=SHR,DSN=DSN!!0.DBRMLIB.DATA
//* //SYSTSPRT DD SYSOUT=*
//* //SYSPRINT DD SYSOUT=*
//* //SYSUDUMP DD SYSOUT=*
//* //SYSTSIN DD *
//* DSN SYSTEM(DSN)
//* BIND PACKAGE(DSNTWR) MEMBER(DSNTWR) APPLCOMPAT(V!!R1) +
//* ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
//* END
//* /*
//*
//* Step 3: Prepare DSN8ED6, sample caller of WLM_REFRESH
//*
//PH06WS03 EXEC DSNHC,MEM=DSN8ED6,COND=(4,LT),
// PARM.PC=('HOST(C),CCSID(1047),MARGINS(1,72),STDSQL(NO)',
// SOURCE,XREF),
// PARM.C='SOURCE LIST MAR(1,72) LO RENT OPTFILE(DD:CCOPTS)',
// PARM.LKED='AMODE=31,RMODE=ANY,MAP,RENT,UPCASE'
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8ED6),
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1321
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8ED6),
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8ED6),
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNELI)
INCLUDE SYSLIB(DSNTIAR)
//*
//* Step 4: Bind the package and plan for DSN8ED6
//*
//PH06WS04 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//DBRMLIB DD DISP=SHR,DSN=DSN!!0.DBRMLIB.DATA
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
BIND PACKAGE(DSN8ED!!) MEMBER(DSN8ED6) APPLCOMPAT(V!!R1) +
ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
BIND PLAN(DSN8ED6) -
PKLIST(DSN8ED!!.DSN8ED6, -
DSNTWR.DSNTWR) -
ACTION(REPLACE) RETAIN +
ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
RUN PROGRAM(DSNTIAD) PLAN(DSNTIA!!) -
LIB('DSN!!0.RUNLIB.LOAD')
END
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
GRANT BIND, EXECUTE ON PLAN DSN8ED6
TO PUBLIC;
//*
//* Step 5: Invoke DSN8ED6
//*
//PH06WS05 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
RUN PROGRAM(DSN8ED6) PLAN(DSN8ED6) -
LIB('DSN!!0.RUNLIB.LOAD') -
PARMS('!WLMENV! !DSN! !ID!')
END
/*
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSNTEJ6Z
This JCL prepares and executes DSN8ED7, a sample caller of ADMIN_INFO_SYSPARM, a Db2-provided
stored procedure that returns the current settings of your Db2 subsystem parameters.
//*
//* DB2 Sample Application
//* Phase 6
//* Sample Caller of Stored Procedure - ADMIN_INFO_SYSPARM
//* C language
//*
//*
//* LICENSED MATERIALS - PROPERTY OF IBM
//* 5650-DB2
//* (C) COPYRIGHT 1982, 2016 IBM CORP. ALL RIGHTS RESERVED.
//*
//* Status = VERSION 12
//*
//* Function =
//* This JCL prepares and executes DSN8ED7, a sample caller of
//* ADMIN_INFO_SYSPARM, a DB2-provided stored procedure that returns
//* the current settings of your DB2 subsystem parameters. After
//* calling ADMIN_INFO_SYSPARM, DSN8ED7 formats the results in a
//* report format.
//*
1322 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
//* Pseudocode =
//* PH06ZS01 Step Prepare DSN8ED7
//* PH06ZS02 Step Bind the plan and package for DSN8ED7
//* PH06ZS03 Step Invoke DSN8ED7
//*
//* Dependencies =
//* - This job requires the DB2-provided JCL procedure DSNHC
//*
//* Notes =
//*
//* Change Activity =
//* 10/16/2013 Don't use prelinker by default PI13612 DM1812
//* 08/18/2014 Single-phase migration s21938_inst1 s21938
//*
//*********************************************************************
//*
//JOBLIB DD DISP=SHR,DSN=DSN!!0.SDSNEXIT
// DD DISP=SHR,DSN=DSN!!0.SDSNLOAD
// DD DISP=SHR,DSN=CEE.V!R!M!.SCEERUN
//*
//* Step 1: Prepare DSN8ED7, sample caller of ADMIN_INFO_SYSPARM
//*
//PH06ZS01 EXEC DSNHC,MEM=DSN8ED7,COND=(4,LT),
// PARM.PC=('HOST(C),CCSID(1047),MARGINS(1,72),STDSQL(NO)',
// SOURCE,XREF),
// PARM.C='SOURCE LIST MAR(1,72) LO RENT OPTFILE(DD:CCOPTS)',
// PARM.LKED='AMODE=31,RMODE=ANY,MAP,RENT,REUS,UPCASE'
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8ED7),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8ED7),
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8ED7),
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNELI)
INCLUDE SYSLIB(DSNTIAR)
//*
//* Step 2: Bind the package and plan for DSN8ED7
//*
//PH06ZS02 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//DBRMLIB DD DISP=SHR,DSN=DSN!!0.DBRMLIB.DATA
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
BIND PACKAGE(DSN8ED!!) MEMBER(DSN8ED7) APPLCOMPAT(V!!R1) +
ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
BIND PLAN(DSN8ED7) -
PKLIST(DSN8ED!!.DSN8ED7 ) -
ACTION(REPLACE) RETAIN +
ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
RUN PROGRAM(DSNTIAD) PLAN(DSNTIA!!) -
LIB('DSN!!0.RUNLIB.LOAD')
END
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
GRANT BIND, EXECUTE ON PLAN DSN8ED7
TO PUBLIC;
//*
//* Step 3: Invoke DSN8ED7
//*
//PH06ZS03 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
RUN PROGRAM(DSN8ED7) PLAN(DSN8ED7) -
LIB('DSN!!0.RUNLIB.LOAD')
END
/*
Related reference
“Sample applications in TSO” on page 1025
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1323
A set of Db2 sample applications run in the TSO environment.
DSNTEJ66
This JCL does the following.
//*********************************************************************
//* Name = DSNTEJ66
//*
//* Descriptive Name = DB2 Sample Application - Native SQL Procedure
//* Phase 6
//*
//*
//* Licensed Materials - Property of IBM
//* 5650-DB2
//* (C) COPYRIGHT 2006, 2016 IBM Corp. All Rights Reserved.
//*
//* STATUS = Version 12
//*
//* Function = This JCL does the following:
//* - Creates a sample native SQL procedure called
//* DSN8.DSN8ES3 that generates and returns (by result
//* set) a CREATE PROCEDURE statement for a given stored
//* procedure.
//* - Prepares and executes a sample caller of DSN8ES3
//* called DSN8ED9.
//* - Shows how to use ALTER PROCEDURE ... ADD VERSION to
//* create a version V2 of DSN8ES3 that does the same
//* thing as the original version but also adds a
//* terminating semicolon at the end of the generated
//* CREATE PROCEDURE statement
//* - Shows how to ALTER ACTIVATE version V2 to make it
//* the active version of DSN8ES3
//* - Shows how to DEPLOY DSN8ES3 at a remote site
//*
//* Restrictions =
//* As part of the setup to DEPLOY DSN8ES3, the DSNTEP2 application
//* needs to be able to connect to the remote site.
//*
//* Notice =
//*
//* Pseudocode =
//* PH066S01 Step Drop objects created by prior runs of this job
//* PH066S02 Step Create the global temporary table for
//* DSN8.DSN8ES3
//* PH066S03 Step Prepare DSN8ES3 as a native SQL procedure
//* -> Also generates a package called
//* DSN8.DSN8ES3
//* PH066S04 Step Prepare DSN8ED9, sample caller for the DSN8ES3
//* SQL proc
//* PH066S05 Step Bind the plan for DSN8ED9
//* PH066S06 Step Execute DSN8ED9 to request a CREATE PROC
//* statement for the stored procedure
//* SYSPROC.DSNUTILS
//* PH066S07 Step Create a work copy of the DSN8ES3 source code
//* PH066S08 Step Use TSO edit to modify the work copy into an
//* ALTER PROCEDURE that will make a trivial
//* change to DSN8ES3 as VERSION V2
//* -> The generated CREATE PROC statement will be
//* terminated by a semicolon
//* PH066S09 Step Save the work copy as DSN8ES3 in
//* DSN!!0.NEW.SDSNSAMP
//* PH066S10 Step Process the ALTER PROCEDURE DSN8ES3 to ADD
//* VERSION V2
//* -> Also generates a package called
//* DSN8.DSN8ES3 (VERSION V2)
//* PH066S11 Step Activate V2 as the current version of DSN8ES3
//* PH066S12 Step Execute DSN8ED9 to request a CREATE PROC
//* statement for SYSPROC.DSNUTILU
//* -> When using DSN8ES3 V2, it's terminated by a
//* semicolon
//* PH066S13 Step Setup to DEPLOY DSN8ES3: Create a global
//* temporary table on the remote server
//* -> To rerun this step, uncomment the DROP
//* and COMMIT statements
//* PH066S14 Step DEPLOY DSN8ES3 on the remote server
//* PH066S15 Step Bind the plan for DSN8ED9 on the remote server
//* PH066S16 Step Execute DSN8ED9 to request a CREATE PROC
//* statement for SYSPROC.DSNUTILS at the remote
1324 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
//* site
//*
//* Change Activity =
//* 10/16/2013 Don't use prelinker by default PI13612 DM1812
//* 08/18/2014 Single-phase migration s21938_inst1 s21938
//*
//*********************************************************************
//*
//JOBLIB DD DSN=DSN!!0.SDSNEXIT,DISP=SHR
// DD DSN=DSN!!0.SDSNLOAD,DISP=SHR
// DD DSN=CEE.V!R!M!.SCEERUN,DISP=SHR
//*
//* Step 1: Drop objects created by prior runs of this job
//*
//PH066S01 EXEC PGM=IKJEFT01,DYNAMNBR=20
//SYSTSPRT DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
RUN PROGRAM(DSNTIAD) +
PLAN(DSNTIA!!) +
LIB('DSN!!0.RUNLIB.LOAD') +
PARM('RC0')
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
DROP PROCEDURE DSN8.DSN8ES3;
COMMIT;
DROP TABLE DSN8.DSN8ES3_RS_TBL;
COMMIT;
//WORKCOPY DD DSN=DSN!!0.DSN8.DSN8ES3.WORKCOPY,
// DISP=(MOD,DELETE),
// UNIT=SYSDA,SPACE=(TRK,0)
//*
//* Step 2: Create the global temporary table for DSN8.DSN8ES3
//*
//PH066S02 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//SYSTSPRT DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
RUN PROGRAM(DSNTIAD) +
PLAN(DSNTIA!!) +
LIB('DSN!!0.RUNLIB.LOAD')
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
CREATE GLOBAL TEMPORARY TABLE
DSN8.DSN8ES3_RS_TBL
( RS_SEQUENCE INTEGER NOT NULL,
RS_LINE CHAR(80) NOT NULL )
CCSID EBCDIC
//*
//* Step 3: Prepare DSN8ES3 as a native SQL procedure
//* -> Also generates a package called DSN8.DSN8ES3
//*
//PH066S03 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
RUN PROGRAM(DSNTEP2) PLAN(DSNTEP!!) +
LIB('DSN!!0.RUNLIB.LOAD') PARMS('/SQLTERM(%)')
END
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM'
%
// DD DISP=SHR,
// DSN=DSN!!0.SDSNSAMP(DSN8ES3)
// DD *
%
//*
//* Step 4: Prepare DSN8ED9, sample caller for the DSN8ES3 SQL proc
//*
//PH066S04 EXEC DSNHC,MEM=DSN8ED9,COND=(4,LT),
// PARM.PC=('HOST(C),CCSID(1047),MARGINS(1,72),STDSQL(NO)',
// SOURCE,XREF),
// PARM.C='SOURCE LIST MAR(1,72) LO RENT OPTFILE(DD:CCOPTS)',
// PARM.LKED='AMODE=31,RMODE=ANY,MAP,NORENT,UPCASE'
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8ED9),
// DISP=SHR
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1325
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8ED9),
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8ED9),
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNELI)
INCLUDE SYSLIB(DSNTIAR)
//*
//* Step 5: Bind the plan for DSN8ED9
//*
//PH066S05 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA,
// DISP=SHR
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
GRANT BIND, EXECUTE ON PLAN DSN8ED9
TO PUBLIC;
//SYSTSIN DD *
DSN SYSTEM(DSN)
BIND PACKAGE(DSN8ED!!) MEMBER(DSN8ED9) APPLCOMPAT(V!!R1) +
ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
BIND PLAN(DSN8ED9) +
PKLIST(DSN8ED!!.DSN8ED9) +
ACTION(REPLACE) RETAIN +
ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
RUN PROGRAM(DSNTIAD) PLAN(DSNTIA!!) +
LIB('DSN!!0.RUNLIB.LOAD')
//*
//* Step 6: Execute DSN8ED9 to request a CREATE PROC statement
//* for the stored procedure named SYSPROC.DSNUTILS
//*
//PH066S06 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
RUN PROGRAM(DSN8ED9) PLAN(DSN8ED9) +
LIB('DSN!!0.RUNLIB.LOAD') +
PARMS('/SYSPROC DSNUTILS')
END
//*
//* Step 7: Create a work copy of the DSN8ES3 source code
//*
//PH066S07 EXEC PGM=IEBGENER,COND=(4,LT)
//SYSIN DD DUMMY
//SYSPRINT DD SYSOUT=*
//SYSUT1 DD DISP=SHR,
// DSN=DSN!!0.SDSNSAMP(DSN8ES3)
//SYSUT2 DD DSN=DSN!!0.DSN8.DSN8ES3.WORKCOPY,
// DISP=(,CATLG,DELETE),
// UNIT=SYSDA,
// SPACE=(TRK,1),
// DCB=(RECFM=FB,LRECL=80)
//*
//* Step 8: Use TSO edit to modify the work copy into an ALTER PROCE-
//* DURE that will make a trivial change to DSN8ES3 VERSION V2
//* -> The generated CREATE PROC statement will now be
//* terminated by a semicolon
//*
//PH066S08 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSTSIN DD *
EDIT 'DSN!!0.DSN8.DSN8ES3.WORKCOPY' +
DATA OLD NONUM NORECOVER ASIS
FIND /CREATE PROCEDURE DSN8.DSN8ES3/
CHANGE * 1 /CREATE PROCEDURE/ALTER PROCEDURE /
INSERT ADD VERSION V2
FIND /PARAMETER CCSID EBCDIC/
DELETE * 1
FIND /U100: -- Finish up/
CHANGE * 1 /Finish up /Add terminating semicolon/
INSERT SET LINE = ';';
INSERT SET RETURN_POINT = 'DONE';
INSERT GOTO INSERTLINE;
1326 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
LIST 1 9999
END SAVE
//*
//* Step 9: Save in DSN!!0.NEW.SDSNSAMP
//*
//PH066S09 EXEC PGM=IEBGENER,COND=(4,LT)
//SYSIN DD DUMMY
//SYSPRINT DD SYSOUT=*
//SYSUT1 DD DISP=(OLD,DELETE),
// DSN=DSN!!0.DSN8.DSN8ES3.WORKCOPY
//SYSUT2 DD DISP=SHR,
// DSN=DSN!!0.NEW.SDSNSAMP(DSN8ES3)
//*
//* Step 10: Process the ALTER PROCEDURE DSN8ES3 to ADD VERSION V2
//* -> Also generates a package called DSN8.DSN8ES3 (V2)
//*
//PH066S10 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
RUN PROGRAM(DSNTEP2) PLAN(DSNTEP!!) +
LIB('DSN!!0.RUNLIB.LOAD') PARMS('/SQLTERM(%)')
END
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM'
%
// DD DISP=SHR,
// DSN=DSN!!0.NEW.SDSNSAMP(DSN8ES3)
// DD *
%
//*
//* Step 11: Activate V2 as the current version of DSN8ES3
//*
//PH066S11 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
RUN PROGRAM(DSNTIAD) PLAN(DSNTIA!!) +
LIB('DSN!!0.RUNLIB.LOAD')
END
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
ALTER PROCEDURE DSN8.DSN8ES3 ACTIVATE VERSION V2;
//*
//* Step 12: Execute DSN8ED9 to request a CREATE PROC statement
//* for SYSPROC.DSNUTILU
//* -> When using DSN8ES3 V2, it's terminated by a semicolon
//*
//PH066S12 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
REBIND PACKAGE(DSN8ED!!.DSN8ED9) APPLCOMPAT(V!!R1) +
PLANMGMT(OFF)
RUN PROGRAM(DSN8ED9) PLAN(DSN8ED9) +
LIB('DSN!!0.RUNLIB.LOAD') +
PARMS('/SYSPROC DSNUTILU')
END
//*
//* Step 13: Setup to DEPLOY DSN8ES3 - Create a global temporary
//* table on the remote server
//*
//PH066S13 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
RUN PROGRAM(DSNTEP2) +
PLAN(DSNTEP!!) +
LIB('DSN!!0.RUNLIB.LOAD')
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
CONNECT TO SAMPLOC;
* DROP TABLE DSN8.DSN8ES3_RS_TBL;
* COMMIT;
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1327
CREATE GLOBAL TEMPORARY TABLE
DSN8.DSN8ES3_RS_TBL
( RS_SEQUENCE INTEGER NOT NULL,
RS_LINE CHAR(80) NOT NULL )
CCSID EBCDIC;
//*
//* Step 14: DEPLOY DSN8ES3 on the remote server
//*
//PH066S14 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
BIND PACKAGE(SAMPLOC.DSN8) APPLCOMPAT(V!!R1) +
DEPLOY(DSN8.DSN8ES3) +
COPYVER(V2) +
ACTION(REP)
//*
//* Step 15: Bind the plan for DSN8ED9 on the remote server
//*
//PH066S15 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA,
// DISP=SHR
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
GRANT BIND, EXECUTE ON PLAN DSN8ED9
TO PUBLIC;
//SYSTSIN DD *
DSN SYSTEM(DSN)
BIND PACKAGE(SAMPLOC.DSN8ED!!) MEMBER(DSN8ED9) +
APPLCOMPAT(V!!R1) +
ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
BIND PLAN(DSN8ED9) +
PKLIST(DSN8ED!!.DSN8ED9, +
SAMPLOC.DSN8ED!!.DSN8ED9, +
SAMPLOC.DSN8ES!!.*) +
ACTION(REPLACE) RETAIN +
ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
RUN PROGRAM(DSNTIAD) PLAN(DSNTIA!!) +
LIB('DSN!!0.RUNLIB.LOAD')
//*
//* Step 16: Execute DSN8ED9 to request a CREATE PROC statement for
//* SYSPROC.DSNUTILS at the remote site
//*
//PH066S16 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
RUN PROGRAM(DSN8ED9) PLAN(DSN8ED9) +
LIB('DSN!!0.RUNLIB.LOAD') +
PARMS('/SYSPROC DSNUTILS SAMPLOC')
END
//*
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSNTEJ2U
THIS JCL PREPARES THE FOLLOWING Db2 USER-DEFINED FUNCTIONS (UDF'S) AND A DRIVER
PROGRAM TO INVOKE THEM.
//*********************************************************************
//* NAME = DSNTEJ2U
//*
//* DESCRIPTIVE NAME = DB2 SAMPLE APPLICATION
//* PHASE 2
//* USER DEFINED FUNCTIONS (C/C++)
//*
//* Licensed Materials - Property of IBM
//* 5650-DB2
1328 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
//* (C) COPYRIGHT 1982, 2016 IBM Corp. All Rights Reserved.
//*
//* STATUS = Version 12
//*
//* FUNCTION = THIS JCL PREPARES THE FOLLOWING DB2 USER-DEFINED
//* FUNCTIONS (UDF'S) AND A DRIVER PROGRAM TO INVOKE THEM.
//*
//* NOTES = ENSURE THAT LINE NUMBER SEQUENCING IS SET 'ON' IF
//* THIS JOB IS SUBMITTED FROM AN ISPF EDIT SESSION
//*
//* THIS JOB IS RUN AFTER PHASE 1.
//*
//* CHANGE ACTIVITY =
//* 10/16/2013 Don't use prelinker by default PI13612 DM1812
//* 08/18/2014 Single-phase migration s21938_inst1 s21938
//*
//*********************************************************************
//*
//JOBLIB DD DSN=DSN!!0.SDSNEXIT,DISP=SHR
// DD DSN=DSN!!0.SDSNLOAD,DISP=SHR
// DD DSN=CEE.V!R!M!.SCEERUN,DISP=SHR
// DD DSN=DSN!!0.RUNLIB.LOAD,DISP=SHR
//*
//* STEP 1: DROP ANY EXISTING DB2 SAMPLE UDF'S
//*
//PH02US01 EXEC PGM=IKJEFT01,DYNAMNBR=20
//SYSTSPRT DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
RUN PROGRAM(DSNTIAD) -
PLAN(DSNTIA!!) -
LIB('DSN!!0.RUNLIB.LOAD') -
PARM('RC0')
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1329
CREATE FUNCTION
DSN8.ALTDATE(
VARCHAR(13) CCSID EBCDIC )
RETURNS
VARCHAR(17) CCSID EBCDIC
SPECIFIC DSN8.DSN8DUADV
LANGUAGE C
DETERMINISTIC
NO SQL
EXTERNAL NAME DSN8DUAD
PARAMETER STYLE DB2SQL
NULL CALL
NO EXTERNAL ACTION
NO SCRATCHPAD
NO FINAL CALL
ALLOW PARALLEL
NO COLLID
ASUTIME LIMIT 10
STAY RESIDENT NO
PROGRAM TYPE SUB
WLM ENVIRONMENT WLMENV
SECURITY DB2
NO DBINFO;
CREATE FUNCTION
DSN8.ALTDATE(
VARCHAR(17) CCSID EBCDIC,
VARCHAR(13) CCSID EBCDIC,
VARCHAR(13) CCSID EBCDIC )
RETURNS
VARCHAR(17) CCSID EBCDIC
SPECIFIC DSN8.DSN8DUCDVVV
LANGUAGE C
DETERMINISTIC
NO SQL
EXTERNAL NAME DSN8DUCD
PARAMETER STYLE DB2SQL
NULL CALL
NO EXTERNAL ACTION
NO SCRATCHPAD
NO FINAL CALL
ALLOW PARALLEL
NO COLLID
ASUTIME LIMIT 10
STAY RESIDENT NO
PROGRAM TYPE SUB
WLM ENVIRONMENT WLMENV
SECURITY DB2
NO DBINFO;
CREATE FUNCTION
DSN8.ALTDATE(
DATE,
VARCHAR(13) CCSID EBCDIC,
VARCHAR(13) CCSID EBCDIC )
RETURNS
VARCHAR(17) CCSID EBCDIC
SPECIFIC DSN8.DSN8DUCDDVV
SOURCE SPECIFIC DSN8.DSN8DUCDVVV;
CREATE FUNCTION
DSN8.ALTTIME(
VARCHAR(14) CCSID EBCDIC )
RETURNS
VARCHAR(11) CCSID EBCDIC
SPECIFIC DSN8.DSN8DUATV
LANGUAGE C
DETERMINISTIC
NO SQL
EXTERNAL NAME DSN8DUAT
PARAMETER STYLE DB2SQL
NULL CALL
NO EXTERNAL ACTION
NO SCRATCHPAD
NO FINAL CALL
ALLOW PARALLEL
NO COLLID
ASUTIME LIMIT 10
STAY RESIDENT NO
PROGRAM TYPE SUB
WLM ENVIRONMENT WLMENV
1330 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
SECURITY DB2
NO DBINFO;
CREATE FUNCTION
DSN8.ALTTIME(
VARCHAR(11) CCSID EBCDIC,
VARCHAR(14) CCSID EBCDIC,
VARCHAR(14) CCSID EBCDIC )
RETURNS
VARCHAR(11) CCSID EBCDIC
SPECIFIC DSN8.DSN8DUCTVVV
LANGUAGE C
DETERMINISTIC
NO SQL
EXTERNAL NAME DSN8DUCT
PARAMETER STYLE DB2SQL
NULL CALL
NO EXTERNAL ACTION
NO SCRATCHPAD
NO FINAL CALL
ALLOW PARALLEL
NO COLLID
ASUTIME LIMIT 10
STAY RESIDENT NO
PROGRAM TYPE SUB
WLM ENVIRONMENT WLMENV
SECURITY DB2
NO DBINFO;
CREATE FUNCTION
DSN8.ALTTIME(
TIME,
VARCHAR(14) CCSID EBCDIC,
VARCHAR(14) CCSID EBCDIC )
RETURNS
VARCHAR(11) CCSID EBCDIC
SPECIFIC DSN8.DSN8DUCTTVV
SOURCE SPECIFIC DSN8.DSN8DUCTVVV;
CREATE FUNCTION
DSN8.CURRENCY(
FLOAT,
VARCHAR(2) CCSID EBCDIC )
RETURNS
VARCHAR(19) CCSID EBCDIC
SPECIFIC DSN8.DSN8DUCYFV
LANGUAGE C
DETERMINISTIC
NO SQL
EXTERNAL NAME DSN8DUCY
PARAMETER STYLE DB2SQL
NULL CALL
NO EXTERNAL ACTION
NO SCRATCHPAD
NO FINAL CALL
ALLOW PARALLEL
NO COLLID
ASUTIME LIMIT 10
STAY RESIDENT NO
PROGRAM TYPE MAIN
WLM ENVIRONMENT WLMENV
SECURITY DB2
NO DBINFO;
CREATE FUNCTION
DSN8.CURRENCY(
FLOAT,
VARCHAR(2) CCSID EBCDIC,
VARCHAR(5) CCSID EBCDIC )
RETURNS
VARCHAR(19) CCSID EBCDIC
SPECIFIC DSN8.DSN8DUCYFVV
LANGUAGE C
DETERMINISTIC
NO SQL
EXTERNAL NAME DSN8DUCY
PARAMETER STYLE DB2SQL
NULL CALL
NO EXTERNAL ACTION
NO SCRATCHPAD
NO FINAL CALL
ALLOW PARALLEL
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1331
NO COLLID
ASUTIME LIMIT 10
STAY RESIDENT NO
PROGRAM TYPE MAIN
WLM ENVIRONMENT WLMENV
SECURITY DB2
NO DBINFO;
CREATE FUNCTION
DSN8.DAYNAME(
VARCHAR(10) CCSID EBCDIC )
RETURNS
VARCHAR(9) CCSID EBCDIC
SPECIFIC DSN8.DSN8EUDNV
LANGUAGE C
DETERMINISTIC
NO SQL
EXTERNAL NAME DSN8EUDN
PARAMETER STYLE DB2SQL
NULL CALL
NO EXTERNAL ACTION
NO SCRATCHPAD
NO FINAL CALL
ALLOW PARALLEL
NO COLLID
ASUTIME LIMIT 10
STAY RESIDENT NO
PROGRAM TYPE SUB
WLM ENVIRONMENT WLMENV
SECURITY DB2
NO DBINFO;
CREATE FUNCTION
DSN8.DAYNAME(
DATE )
RETURNS
VARCHAR(9) CCSID EBCDIC
SPECIFIC DSN8.DSN8EUDND
SOURCE SPECIFIC DSN8.DSN8EUDNV;
CREATE FUNCTION
DSN8.MONTHNAME(
VARCHAR(10) CCSID EBCDIC )
RETURNS
VARCHAR(9) CCSID EBCDIC
SPECIFIC DSN8.DSN8EUMNV
LANGUAGE C
DETERMINISTIC
NO SQL
EXTERNAL NAME DSN8EUMN
PARAMETER STYLE DB2SQL
NULL CALL
NO EXTERNAL ACTION
NO SCRATCHPAD
NO FINAL CALL
ALLOW PARALLEL
NO COLLID
ASUTIME LIMIT 10
STAY RESIDENT NO
PROGRAM TYPE SUB
WLM ENVIRONMENT WLMENV
SECURITY DB2
NO DBINFO;
CREATE FUNCTION
DSN8.MONTHNAME(
DATE )
RETURNS
VARCHAR(9) CCSID EBCDIC
SPECIFIC DSN8.DSN8EUMND
SOURCE SPECIFIC DSN8.DSN8EUMNV;
CREATE FUNCTION
DSN8.TABLE_NAME(
VARCHAR(18) CCSID EBCDIC )
RETURNS
VARCHAR(18) CCSID EBCDIC
SPECIFIC DSN8.DSN8DUTINV
LANGUAGE C
DETERMINISTIC
READS SQL DATA
EXTERNAL NAME DSN8DUTI
1332 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
PARAMETER STYLE DB2SQL
NULL CALL
NO EXTERNAL ACTION
NO SCRATCHPAD
NO FINAL CALL
ALLOW PARALLEL
COLLID DSN8DU!!
ASUTIME LIMIT 10
STAY RESIDENT NO
PROGRAM TYPE MAIN
WLM ENVIRONMENT WLMENV
SECURITY DB2
NO DBINFO;
CREATE FUNCTION
DSN8.TABLE_NAME(
VARCHAR(18) CCSID EBCDIC,
VARCHAR(8) CCSID EBCDIC )
RETURNS
VARCHAR(18) CCSID EBCDIC
SPECIFIC DSN8.DSN8DUTINVV
LANGUAGE C
DETERMINISTIC
READS SQL DATA
EXTERNAL NAME DSN8DUTI
PARAMETER STYLE DB2SQL
NULL CALL
NO EXTERNAL ACTION
NO SCRATCHPAD
NO FINAL CALL
ALLOW PARALLEL
COLLID DSN8DU!!
ASUTIME LIMIT 10
STAY RESIDENT NO
PROGRAM TYPE MAIN
WLM ENVIRONMENT WLMENV
SECURITY DB2
NO DBINFO;
CREATE FUNCTION
DSN8.TABLE_NAME(
VARCHAR(18) CCSID EBCDIC,
VARCHAR(8) CCSID EBCDIC,
VARCHAR(16) CCSID EBCDIC )
RETURNS
VARCHAR(18) CCSID EBCDIC
SPECIFIC DSN8.DSN8DUTINVVV
LANGUAGE C
DETERMINISTIC
READS SQL DATA
EXTERNAL NAME DSN8DUTI
PARAMETER STYLE DB2SQL
NULL CALL
NO EXTERNAL ACTION
NO SCRATCHPAD
NO FINAL CALL
ALLOW PARALLEL
COLLID DSN8DU!!
ASUTIME LIMIT 10
STAY RESIDENT NO
PROGRAM TYPE MAIN
WLM ENVIRONMENT WLMENV
SECURITY DB2
NO DBINFO;
CREATE FUNCTION
DSN8.TABLE_SCHEMA(
VARCHAR(18) CCSID EBCDIC )
RETURNS
VARCHAR(8) CCSID EBCDIC
SPECIFIC DSN8.DSN8DUTISV
LANGUAGE C
DETERMINISTIC
READS SQL DATA
EXTERNAL NAME DSN8DUTI
PARAMETER STYLE DB2SQL
NULL CALL
NO EXTERNAL ACTION
NO SCRATCHPAD
NO FINAL CALL
ALLOW PARALLEL
COLLID DSN8DU!!
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1333
ASUTIME LIMIT 10
STAY RESIDENT NO
PROGRAM TYPE MAIN
WLM ENVIRONMENT WLMENV
SECURITY DB2
NO DBINFO;
CREATE FUNCTION
DSN8.TABLE_SCHEMA(
VARCHAR(18) CCSID EBCDIC,
VARCHAR(8) CCSID EBCDIC )
RETURNS
VARCHAR(8) CCSID EBCDIC
SPECIFIC DSN8.DSN8DUTISVV
LANGUAGE C
DETERMINISTIC
READS SQL DATA
EXTERNAL NAME DSN8DUTI
PARAMETER STYLE DB2SQL
NULL CALL
NO EXTERNAL ACTION
NO SCRATCHPAD
NO FINAL CALL
ALLOW PARALLEL
COLLID DSN8DU!!
ASUTIME LIMIT 10
STAY RESIDENT NO
PROGRAM TYPE MAIN
WLM ENVIRONMENT WLMENV
SECURITY DB2
NO DBINFO;
CREATE FUNCTION
DSN8.TABLE_SCHEMA(
VARCHAR(18) CCSID EBCDIC,
VARCHAR(8) CCSID EBCDIC,
VARCHAR(16) CCSID EBCDIC )
RETURNS
VARCHAR(8) CCSID EBCDIC
SPECIFIC DSN8.DSN8DUTISVVV
LANGUAGE C
DETERMINISTIC
READS SQL DATA
EXTERNAL NAME DSN8DUTI
PARAMETER STYLE DB2SQL
NULL CALL
NO EXTERNAL ACTION
NO SCRATCHPAD
NO FINAL CALL
ALLOW PARALLEL
COLLID DSN8DU!!
ASUTIME LIMIT 10
STAY RESIDENT NO
PROGRAM TYPE MAIN
WLM ENVIRONMENT WLMENV
SECURITY DB2
NO DBINFO;
CREATE FUNCTION
DSN8.TABLE_LOCATION(
VARCHAR(18) CCSID EBCDIC )
RETURNS
VARCHAR(16) CCSID EBCDIC
SPECIFIC DSN8.DSN8DUTILV
LANGUAGE C
DETERMINISTIC
READS SQL DATA
EXTERNAL NAME DSN8DUTI
PARAMETER STYLE DB2SQL
NULL CALL
NO EXTERNAL ACTION
NO SCRATCHPAD
NO FINAL CALL
ALLOW PARALLEL
COLLID DSN8DU!!
ASUTIME LIMIT 10
STAY RESIDENT NO
PROGRAM TYPE MAIN
WLM ENVIRONMENT WLMENV
SECURITY DB2
NO DBINFO;
1334 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
CREATE FUNCTION
DSN8.TABLE_LOCATION(
VARCHAR(18) CCSID EBCDIC,
VARCHAR(8) CCSID EBCDIC )
RETURNS
VARCHAR(16) CCSID EBCDIC
SPECIFIC DSN8.DSN8DUTILVV
LANGUAGE C
DETERMINISTIC
READS SQL DATA
EXTERNAL NAME DSN8DUTI
PARAMETER STYLE DB2SQL
NULL CALL
NO EXTERNAL ACTION
NO SCRATCHPAD
NO FINAL CALL
ALLOW PARALLEL
COLLID DSN8DU!!
ASUTIME LIMIT 10
STAY RESIDENT NO
PROGRAM TYPE MAIN
WLM ENVIRONMENT WLMENV
SECURITY DB2
NO DBINFO;
CREATE FUNCTION
DSN8.TABLE_LOCATION(
VARCHAR(18) CCSID EBCDIC,
VARCHAR(8) CCSID EBCDIC,
VARCHAR(16) CCSID EBCDIC )
RETURNS
VARCHAR(16) CCSID EBCDIC
SPECIFIC DSN8.DSN8DUTILVVV
LANGUAGE C
DETERMINISTIC
READS SQL DATA
EXTERNAL NAME DSN8DUTI
PARAMETER STYLE DB2SQL
NULL CALL
NO EXTERNAL ACTION
NO SCRATCHPAD
NO FINAL CALL
ALLOW PARALLEL
COLLID DSN8DU!!
ASUTIME LIMIT 10
STAY RESIDENT NO
PROGRAM TYPE MAIN
WLM ENVIRONMENT WLMENV
SECURITY DB2
NO DBINFO;
CREATE FUNCTION
DSN8.WEATHER(
VARCHAR(44) CCSID EBCDIC )
RETURNS
TABLE(
CITY VARCHAR(30) CCSID EBCDIC,
TEMP_IN_F INTEGER,
HUMIDITY INTEGER,
WIND VARCHAR(5) CCSID EBCDIC,
WIND_VELOCITY INTEGER,
BAROMETER FLOAT,
FORECAST VARCHAR(25) CCSID EBCDIC )
SPECIFIC DSN8.DSN8DUWFV
LANGUAGE C
DETERMINISTIC
NO SQL
EXTERNAL NAME DSN8DUWF
PARAMETER STYLE DB2SQL
NULL CALL
NO EXTERNAL ACTION
SCRATCHPAD
FINAL CALL
DISALLOW PARALLEL
NO COLLID
ASUTIME LIMIT 10
STAY RESIDENT NO
PROGRAM TYPE SUB
WLM ENVIRONMENT WLMENV
SECURITY DB2
NO DBINFO;
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1335
GRANT EXECUTE ON SPECIFIC FUNCTION DSN8.DSN8DUADV,
DSN8.DSN8DUCDVVV,
DSN8.DSN8DUCDDVV,
DSN8.DSN8DUATV,
DSN8.DSN8DUCTVVV,
DSN8.DSN8DUCTTVV,
DSN8.DSN8DUCYFV,
DSN8.DSN8DUCYFVV,
DSN8.DSN8EUDNV,
DSN8.DSN8EUDND,
DSN8.DSN8EUMNV,
DSN8.DSN8EUMND,
DSN8.DSN8DUTINV,
DSN8.DSN8DUTINVV,
DSN8.DSN8DUTINVVV,
DSN8.DSN8DUTISV,
DSN8.DSN8DUTISVV,
DSN8.DSN8DUTISVVV,
DSN8.DSN8DUTILV,
DSN8.DSN8DUTILVV,
DSN8.DSN8DUTILVVV,
DSN8.DSN8DUWFV
TO PUBLIC;
//*
//* STEP 3: PREPARE EXTERNAL FOR CURRENT DATE ALTDATE UDF
//*
//PH02US03 EXEC DSNHC,MEM=DSN8DUAD,COND=(4,LT),
// PARM.PC=('HOST(C),CCSID(1047),MARGINS(1,72),STDSQL(NO)',
// SOURCE,XREF),
// PARM.C='SOURCE RENT XREF MARGINS(1,72) OPTFILE(DD:CCOPTS)',
// PARM.LKED='MAP,RENT,REUS,AMODE=31,RMODE=ANY'
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8DUAD),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8DUAD),
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8DUAD),
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNRLI)
NAME DSN8DUAD(R)
//*
//* STEP 4: PREPARE EXTERNAL FOR GIVEN DATE ALTDATE UDF
//*
//PH02US04 EXEC DSNHC,MEM=DSN8DUCD,COND=(4,LT),
// PARM.PC=('HOST(C),CCSID(1047),MARGINS(1,72),STDSQL(NO)',
// SOURCE,XREF),
// PARM.C='SOURCE RENT XREF MARGINS(1,72) OPTFILE(DD:CCOPTS)',
// PARM.LKED='MAP,RENT,REUS,AMODE=31,RMODE=ANY'
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8DUCD),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8DUCD),
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8DUCD),
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNRLI)
NAME DSN8DUCD(R)
//*
//* STEP 5: PREPARE EXTERNAL FOR CURRENT TIME ALTTIME UDF
//*
//PH02US05 EXEC DSNHC,MEM=DSN8DUAT,COND=(4,LT),
// PARM.PC=('HOST(C),CCSID(1047),MARGINS(1,72),STDSQL(NO)',
// SOURCE,XREF),
// PARM.C='SOURCE RENT XREF MARGINS(1,72) OPTFILE(DD:CCOPTS)',
// PARM.LKED='MAP,RENT,REUS,AMODE=31,RMODE=ANY'
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8DUAT),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8DUAT),
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8DUAT),
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNRLI)
NAME DSN8DUAT(R)
//*
1336 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
//* STEP 6: PREPARE EXTERNAL FOR GIVEN TIME ALTTIME UDF
//*
//PH02US06 EXEC DSNHC,MEM=DSN8DUCT,COND=(4,LT),
// PARM.PC=('HOST(C),CCSID(1047),MARGINS(1,72),STDSQL(NO)',
// SOURCE,XREF),
// PARM.C='SOURCE RENT XREF MARGINS(1,72) OPTFILE(DD:CCOPTS)',
// PARM.LKED='MAP,RENT,REUS,AMODE=31,RMODE=ANY'
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8DUCT),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8DUCT),
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8DUCT),
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNRLI)
NAME DSN8DUCT(R)
//*
//* STEP 7: PREPARE EXTERNAL FOR CURRENCY UDF
//*
//PH02US07 EXEC DSNHC,MEM=DSN8DUCY,COND=(4,LT),
// PARM.PC=('HOST(C),CCSID(1047),MARGINS(1,72),STDSQL(NO)',
// SOURCE,XREF),
// PARM.C='SOURCE RENT XREF MARGINS(1,72) OPTFILE(DD:CCOPTS)',
// PARM.LKED='MAP,RENT,REUS,AMODE=31,RMODE=ANY'
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8DUCY),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8DUCY),
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8DUCY),
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNRLI)
NAME DSN8DUCY(R)
//*
//* STEP 8: PREPARE EXTERNAL FOR DAYNAME UDF
//*
//PH02US08 EXEC DSNHCPP,MEM=DSN8EUDN,COND=(4,LT),
// PARM.PC=('HOST(CPP),CCSID(1047),MARGINS(1,80),STDSQL(NO)',
// SOURCE,XREF),
// PARM.CP=('/CXX SOURCE XREF OPTFILE(DD:CCOPTS)',
// 'LANGLVL(EXTENDED)'),
// PARM.LKED='MAP,RENT,REUS,AMODE=31,RMODE=ANY'
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8EUDN),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8EUDN),
// DISP=SHR
//CP.CCOPTS DD DSN=SYS1.PROCLIB(DSNHCPPS),DISP=SHR
//CP.USERLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8EUDN),
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNRLI)
NAME DSN8EUDN(R)
//*
//* STEP 9: PREPARE EXTERNAL FOR MONTHNAME UDF
//*
//PH02US09 EXEC DSNHCPP,MEM=DSN8EUMN,COND=(4,LT),
// PARM.PC=('HOST(CPP),CCSID(1047),MARGINS(1,80),STDSQL(NO)',
// SOURCE,XREF),
// PARM.CP=('/CXX SOURCE XREF OPTFILE(DD:CCOPTS)',
// 'LANGLVL(EXTENDED)'),
// PARM.LKED='MAP,RENT,REUS,AMODE=31,RMODE=ANY'
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8EUMN),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8EUMN),
// DISP=SHR
//CP.CCOPTS DD DSN=SYS1.PROCLIB(DSNHCPPS),DISP=SHR
//CP.USERLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8EUMN),
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNRLI)
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1337
NAME DSN8EUMN(R)
//*
//* STEP 10: PREPARE EXTERNAL FOR TABLE_NAME, TABLE_SCHEMA,
//* AND TABLE_LOCATION UDF'S
//*
//PH02US10 EXEC DSNHC,MEM=DSN8DUTI,COND=(4,LT),
// PARM.PC=('HOST(C),CCSID(1047),MARGINS(1,72),STDSQL(NO)',
// SOURCE,XREF),
// PARM.C='SOURCE RENT XREF MARGINS(1,72) OPTFILE(DD:CCOPTS)',
// PARM.LKED='MAP,RENT,REUS,AMODE=31,RMODE=ANY'
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8DUTI),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8DUTI),
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8DUTI),
// DISP=SHR
//LKED.IGNORE DD *
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNRLI)
NAME DSN8DUTI(R)
//*
//* STEP 11: BIND PACKAGE FOR TABLE_NAME, TABLE_SCHEMA, AND
//* TABLE_LOCATION UDF'S
//*
//PH02US11 EXEC PGM=IKJEFT01,COND=(4,LT)
//DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA,DISP=SHR
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//CEEDUMP DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//REPORT DD SYSOUT=*
//SYSIN DD *
//SYSTSIN DD *
DSN SYSTEM(DSN)
BIND PACKAGE (DSN8DU!!) MEMBER(DSN8DUTI) APPLCOMPAT(V!!R1) +
ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
END
//*
//* STEP 12: EXERCISE THE SAMPLE UDF'S
//*
//PH02US12 EXEC PGM=IKJEFT01,COND=(4,LT),DYNAMNBR=20
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
RUN PROGRAM(DSNTEP2) PLAN(DSNTEP!!) -
LIB('DSN!!0.RUNLIB.LOAD') PARMS('/ALIGN(MID)')
END
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
// DD DSN=DSN!!0.SDSNSAMP(DSNTESU),
// DISP=SHR
//*
//* STEP 13: PREPARE EXTERNAL FOR WEATHER UDF TABLE FUNCTION
//*
//PH02US13 EXEC DSNHC,MEM=DSN8DUWF,COND=(4,LT),
// PARM.PC=('HOST(C),CCSID(1047),MARGINS(1,72),STDSQL(NO)',
// SOURCE,XREF),
// PARM.C='SOURCE RENT XREF MARGINS(1,72) OPTFILE(DD:CCOPTS)',
// PARM.LKED='MAP,RENT,REUS,AMODE=31,RMODE=ANY'
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8DUWF),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8DUWF),
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8DUWF),
// DISP=SHR
//LKED.IGNORE DD *
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNRLI)
NAME DSN8DUWF(R)
//*
//* STEP 14: PREPARE CLIENT FOR WEATHER UDF TABLE FUNCTION
//*
//PH02US14 EXEC DSNHC,MEM=DSN8DUWC,COND=(4,LT),
// PARM.PC=('HOST(C),CCSID(1047),MARGINS(1,72),STDSQL(NO)',
// SOURCE,XREF),
1338 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
// PARM.C='SOURCE RENT XREF MARGINS(1,72) OPTFILE(DD:CCOPTS)',
// PARM.LKED='MAP,RENT,REUS,AMODE=31,RMODE=ANY'
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8DUWC),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8DUWC),
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8DUWC),
// DISP=SHR
//LKED.IGNORE DD *
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNELI)
INCLUDE SYSLIB(DSNTIAR)
NAME DSN8DUWC(R)
//*
//* STEP 15: BIND PACKAGE & PLAN FOR WEATHER TBL FUNC CLIENT
//*
//PH02US15 EXEC PGM=IKJEFT01,COND=(4,LT)
//DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA,DISP=SHR
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//CEEDUMP DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//REPORT DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
BIND PACKAGE (DSN8DU!!) MEMBER(DSN8DUWC) -
ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
BIND PLAN (DSN8UW!!) PKLIST(DSN8DU!!.*) -
ACTION(REPLACE) RETAIN +
ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC) SQLRULES(DB2)
RUN PROGRAM(DSNTIAD) PLAN(DSNTIA!!) -
LIB('DSN!!0.RUNLIB.LOAD')
END
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
GRANT EXECUTE,BIND ON PLAN DSN8UW!!
TO PUBLIC;
//*
//* STEP 16: INVOKE THE SAMPLE UDF TABLE CLIENT
//*
//PH02US16 EXEC PGM=IKJEFT01,COND=(4,LT),DYNAMNBR=20
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
RUN PROGRAM(DSN8DUWC) PLAN(DSN8UW!!) -
LIB('DSN!!0.RUNLIB.LOAD') -
PARMS('DSN!!0.SDSNIVPD(DSN8LWC')
END
//*
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSNTEJ71
PREPARES AND RUNS THE FOLLOWING PROGRAMS IN SUPPORT OF THE Db2 LOB SAMPLE C
APPLICATION.
//*********************************************************************
//* NAME = DSNTEJ71
//*
//* DESCRIPTIVE NAME = DB2 SAMPLE APPLICATION
//* PHASE 7
//* SAMPLE APPLICATIONS: POPULATE, CHECK LOB TABLE
//* C LANGUAGE
//*
//* LICENSED MATERIALS - PROPERTY OF IBM
//* 5650-DB2
//* (C) COPYRIGHT 1982, 2016 IBM CORP. ALL RIGHTS RESERVED.
//*
//* STATUS = VERSION 12
//*
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1339
//* FUNCTION = PREPARES AND RUNS THE FOLLOWING PROGRAMS IN SUPPORT
//* OF THE DB2 LOB SAMPLE C APPLICATION:
//* - DSN8DLPL: POPULATES THE PSEG AND BMP IMAGE COLUMNS
//* IN THE DSN8!!0.EMP_PHOTO_RESUME SAMPLE LOB
//* TABLE. THE INPUT DATA IS READ FROM A TSO
//* DATA SET. THIS PROGRAM DEMONSTRATES HOW
//* TO POPULATE LOB COLUMNS WITH MORE THAN 32
//* KB OF DATA.
//*
//* - DSN8DLTC: VALIDATES THE CONTENTS OF THE LOB COLUMNS
//* IN THE DSN8!!0.EMP_PHOTO_RESUME TABLE.
//* THIS IS DONE BY COMPARING THE DATA IN THE
//* TABLE TO THE SOURCE DATA SETS.
//*
//* CHANGE ACTIVITY =
//* 08/18/2014 Single-phase migration s21938_inst1 s21938
//*
//*********************************************************************
//JOBLIB DD DSN=DSN!!0.SDSNEXIT,DISP=SHR
// DD DSN=DSN!!0.SDSNLOAD,DISP=SHR
// DD DSN=CEE.V!R!M!.SCEERUN,DISP=SHR
// DD DSN=DSN!!0.RUNLIB.LOAD,DISP=SHR
//*
//* STEP 1: PREPARE LOADER FOR EMPLOYEE PHOTO IMAGES
//*
//PH071S01 EXEC DSNHC,MEM=DSN8DLPL,COND=(4,LT),
// PARM.PC=('HOST(C),CCSID(1047),MARGINS(1,72),STDSQL(NO)',
// SOURCE,XREF),
// PARM.C='SOURCE RENT XREF MARGINS(1,72) OPTFILE(DD:CCOPTS)',
// PARM.LKED='MAP,RENT,REUS,AMODE=31,RMODE=ANY'
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8DLPL),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8DLPL),
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8DLPL),
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNELI)
NAME DSN8DLPL(R)
//*
//* STEP 2: PREPARE SAMPLE LOB TABLE VALIDATOR
//*
//PH071S02 EXEC DSNHC,MEM=DSN8DLTC,COND=(4,LT),
// PARM.PC=('HOST(C),CCSID(1047),MARGINS(1,72),STDSQL(NO)',
// SOURCE,XREF),
// PARM.C='SOURCE RENT XREF MARGINS(1,72) OPTFILE(DD:CCOPTS)',
// PARM.LKED='MAP,RENT,REUS,AMODE=31,RMODE=ANY'
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8DLTC),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8DLTC),
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8DLTC),
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNELI)
NAME DSN8DLTC(R)
//*
//* STEP 3: BIND PACKAGES AND PLANS FOR DSN8DLPL AND DSN8DLTC
//*
//PH071S03 EXEC PGM=IKJEFT01,COND=(4,LT)
//DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA,DISP=SHR
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//CEEDUMP DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//REPORT DD SYSOUT=*
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
GRANT BIND, EXECUTE ON PLAN DSN8LC!!, DSN8LL!!
TO PUBLIC;
//SYSTSIN DD *
DSN SYSTEM(DSN)
BIND PACKAGE (DSN8LL!!) MEMBER(DSN8DLPL) APPLCOMPAT(V!!R1) +
QUALIFIER(DSN8!!0) -
ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
BIND PLAN(DSN8LL!!) PKLIST(DSN8LL!!.*) -
ACTION(REPLACE) RETAIN +
1340 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC) SQLRULES(DB2)
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSNTEJ73
PREPARES AND RUNS THE FOLLOWING PROGRAMS IN SUPPORT OF THE Db2 LOB SAMPLE C
APPLICATION.
//*********************************************************************
//* NAME = DSNTEJ73
//*
//* DESCRIPTIVE NAME = DB2 SAMPLE APPLICATION
//* PHASE 7
//* SAMPLE APPLICATIONS: VIEW, MANIPULATE CLOB DATA
//* C LANGUAGE
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1341
//*
//* LICENSED MATERIALS - PROPERTY OF IBM
//* 5650-DB2
//* (C) COPYRIGHT 1982, 2016 IBM CORP. ALL RIGHTS RESERVED.
//*
//* STATUS = VERSION 12
//*
//* FUNCTION = PREPARES AND RUNS THE FOLLOWING PROGRAMS IN SUPPORT
//* OF THE DB2 LOB SAMPLE C APPLICATION:
//* - DSN8SDM: CAF CONNECTION MANAGER (C LANGUAGE), USED
//* TO INVOKE THE DB2 SAMPLE APPLICATIONS MENU
//* UNDER ISPF AND TO MANAGE INVOKATION OF THE
//* DB2 SAMPLE APPLICATION PROGRAMS, INCLUDING
//* THE LOB SAMPLE RESUME AND PHOTO IMAGE
//* VIEWERS.
//*
//* - DSN8DLRV: EXTRACTS A SPECIFIED EMPLOYEE'S RESUME IN
//* CLOB FORMAT FROM DSN8!!0.EMP_PHOTO_RESUME.
//* DB2 LOB LOCATOR FUNCTIONS ARE USED TO PARSE
//* DATA FROM CLOB FORMAT INTO ISPF FIELDS AND
//* THE RESULT IS DISPLAYED TO THE USER.
//*
//* CHANGE ACTIVITY =
//* 08/18/2014 Single-phase migration s21938_inst1 s21938
//*
//*********************************************************************
//JOBLIB DD DSN=DSN!!0.SDSNEXIT,DISP=SHR
// DD DSN=DSN!!0.SDSNLOAD,DISP=SHR
// DD DSN=CEE.V!R!M!.SCEERUN,DISP=SHR
// DD DSN=DSN!!0.RUNLIB.LOAD,DISP=SHR
//*
//* STEP 1: PREPARE SAMPLE CALL ATTACH CONTROLLER
//*
//PH073S01 EXEC DSNHC,MEM=DSN8SDM,COND=(4,LT),
// PARM.PC=('HOST(C),CCSID(1047),MARGINS(1,72),STDSQL(NO)',
// SOURCE,XREF),
// PARM.C='SOURCE RENT XREF MARGINS(1,72) OPTFILE(DD:CCOPTS)',
// PARM.LKED='MAP,RENT,REUS,AMODE=31,RMODE=ANY'
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8SDM),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8SDM),
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8SDM),
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNALI)
NAME DSN8SDM(R)
//*
//* STEP 2: PREPARE EMPLOYEE RESUME VIEWER (ISPF)
//*
//PH073S02 EXEC DSNHC,MEM=DSN8DLRV,COND=(4,LT),
// PARM.PC=('HOST(C),CCSID(1047),MARGINS(1,72),STDSQL(NO)',
// SOURCE,XREF),
// PARM.C='SOURCE RENT XREF MARGINS(1,72) OPTFILE(DD:CCOPTS)',
// PARM.LKED='MAP,RENT,REUS,AMODE=31,RMODE=ANY'
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8DLRV),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8DLRV),
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8DLRV),
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNALI)
NAME DSN8DLRV(R)
//*
//* STEP 3: BIND PACKAGE AND PLAN FOR THE RESUME VIEWER
//*
//PH073S03 EXEC PGM=IKJEFT01,COND=(4,LT)
//DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA,DISP=SHR
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//CEEDUMP DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//REPORT DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
BIND PACKAGE (DSN8LR!!) APPLCOMPAT(V!!R1) +
1342 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
MEMBER(DSN8DLRV) -
QUALIFIER(DSN8!!0) -
ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
BIND PLAN(DSN8LR!!) -
PKLIST(DSN8LR!!.*) -
ACTION(REPLACE) RETAIN +
ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC) SQLRULES(DB2)
RUN PROGRAM(DSNTIAD) -
PLAN(DSNTIA!!) -
LIB('DSN!!0.RUNLIB.LOAD')
END
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
GRANT EXECUTE,BIND ON PLAN DSN8LR!!
TO PUBLIC;
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
DSNTEJ75
PREPARES AND RUNS THE FOLLOWING PROGRAM IN SUPPORT OF THE Db2 LOB SAMPLE C
APPLICATION.
//*********************************************************************
//* NAME = DSNTEJ75
//*
//* DESCRIPTIVE NAME = DB2 SAMPLE APPLICATION
//* PHASE 7
//* SAMPLE APPLICATIONS: VIEW, MANIPULATE BLOB DATA
//* C LANGUAGE
//*
//* LICENSED MATERIALS - PROPERTY OF IBM
//* 5650-DB2
//* (C) COPYRIGHT 1982, 2016 IBM CORP. ALL RIGHTS RESERVED.
//*
//* STATUS = VERSION 12
//*
//* FUNCTION = PREPARES AND RUNS THE FOLLOWING PROGRAM IN SUPPORT
//* OF THE DB2 LOB SAMPLE C APPLICATION:
//* - DSN8DLPV: EXTRACTS A SPECIFIED EMPLOYEE'S PSEG PHOTO
//* IMAGE IN BLOB FORMAT FROM THE SMAPLE TABLE
//* DSN8!!0.EMP_PHOTO_RESUME. THE DATA IS
//* HANDED OFF TO GDDM FOR CONVERSION FOR CON-
//* VERSION AND DISPLAY.
//*
//* CHANGE ACTIVITY =
//* 08/18/2014 Single-phase migration s21938_inst1 s21938
//*
//*********************************************************************
//JOBLIB DD DSN=DSN!!0.SDSNEXIT,DISP=SHR
// DD DSN=DSN!!0.SDSNLOAD,DISP=SHR
// DD DSN=CEE.V!R!M!.SCEERUN,DISP=SHR
// DD DSN=DSN!!0.RUNLIB.LOAD,DISP=SHR
//*
//* STEP 1: PREPARE EMPLOYEE PHOTO VIEWER (GDDM)
//*
//PH075S01 EXEC DSNHC,MEM=DSN8DLPV,COND=(4,LT),
// PARM.PC=('HOST(C),CCSID(1047),MARGINS(1,72),STDSQL(NO)',
// SOURCE,XREF),
// PARM.C='SOURCE RENT XREF MARGINS(1,72) OPTFILE(DD:CCOPTS)',
// PARM.LKED='MAP,RENT,REUS,AMODE=31,RMODE=ANY'
//PC.DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA(DSN8DLPV),
// DISP=SHR
//PC.SYSLIB DD DSN=DSN!!0.SRCLIB.DATA,
// DISP=SHR
//PC.SYSIN DD DSN=DSN!!0.SDSNSAMP(DSN8DLPV),
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN!!0.RUNLIB.LOAD(DSN8DLPV),
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(ADMASRT)
INCLUDE SYSLIB(DSNTIAR)
INCLUDE SYSLIB(DSNALI)
NAME DSN8DLPV(R)
//*
//* STEP 2: BIND PACKAGE AND PLAN FOR THE PHOTO VIEWER
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1343
//*
//PH075S02 EXEC PGM=IKJEFT01,COND=(4,LT)
//DBRMLIB DD DSN=DSN!!0.DBRMLIB.DATA,DISP=SHR
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//CEEDUMP DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//REPORT DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DSN)
BIND PACKAGE (DSN8LP!!) APPLCOMPAT(V!!R1) +
MEMBER(DSN8DLPV) -
QUALIFIER(DSN8!!0) -
ACT(REP) ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC)
BIND PLAN(DSN8LP!!) -
PKLIST(DSN8LP!!.*) -
ACTION(REPLACE) RETAIN +
ISO(CS) CURRENTDATA(YES) ENCODING(EBCDIC) SQLRULES(DB2)
RUN PROGRAM(DSNTIAD) -
PLAN(DSNTIA!!) -
LIB('DSN!!0.RUNLIB.LOAD')
END
//SYSIN DD *
SET CURRENT SQLID = 'SYSADM';
GRANT EXECUTE ON PLAN DSN8LP!!
TO PUBLIC;
Related reference
“Sample applications in TSO” on page 1025
A set of Db2 sample applications run in the TSO environment.
Related reference
Data sets that the precompiler uses
1344 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
When you invoke the precompiler you need to provide data sets that contain input for the precompiler,
such as the host programming statements and SQL statements. You also need to provide data sets where
the precompiler can store its output, such as the modified source code and diagnostics messages.
DSN8IC0
THIS MODULE RECEIVES AN INPUT MESSAGE AND DEFORMATS IT, CALLS DSN8IC1, FORMATS OUTPUT
MESSAGE AND SENDS IT.
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1345
* CONTAINS TERMINAL INPUT AND * 00650000
* OUTPUT AREAS. * 00660000
* * 00670000
* CONTROL-BLOCKS = * 00680000
* IN-MESSAGE - MFS INPUT * 00690000
* OUT-MESSAGE - MFS OUTPUT * 00700000
* * 00710000
* TABLES = NONE * 00720000
* * 00730000
* CHANGE-ACTIVITY = * 00740000
* 05/18/2012: SWITCH ARITHMETICS FROM COMP TO COMP-5 PM66408* 00750002
* * 00751000
* * 00760000
* *PSEUDOCODE* * 00770000
* * 00780000
* PROCEDURE * 00790000
* DECLARATIONS. * 00800000
* ALLOCATE COBOL WORK AREA FOR COMMAREA. * 00810000
* INITIALIZATION. * 00820000
* PUT MODNAME 'DSN8ICGO' IN MODNAME FIELD. * 00830000
* PUT MODULE NAME 'DSN8IC0' IN AREA USED BY * 00840000
* ERROR-HANDLER. * 00850000
* * 00860000
* STEP1. * 00870000
* CALL DLI GU INPUT MESSAGE. * 00880000
* IF STATUS CODE NOT OK THEN SEND ERROR MESSAGE AND * 00890000
* STOP PROGRAM. * 00900000
* * 00910000
* IF SCREEN CLEARED/UNFORMATTED , MOVE '00' TO PFKIN. * 00920000
* MOVE INPUT MESSAGE FIELDS TO CORRESPONDING * 00930000
* INAREA FIELDS IN COMPARM. * 00940000
* CALL DSN8IC1 (COMMAREA) * 00950000
* MOVE OUTAREA FIELDS IN PCONVSTA TO CORRESPONDING * 00960000
* OUTPUT MESSAGE FIELDS. * 00970000
* IF LASTSCR 'DSN8001' MOVE 'DSN8ICGO' TO MODNAME FIELD * 00980000
* ELSE MOVE 'DSN8ICDO' TO MODNAME FIELD. * 00990000
* * 01000000
* CALL DLI ISRT OUTPUT MESSAGE. * 01010000
* IF STATUS CODE NOT OK THEN SEND ERROR MESSAGE AND * 01020000
* STOP PROGRAM. * 01030000
* * 01040000
* END. * 01050000
* * 01060000
***************************************************************** 01070000
* 01080000
ENVIRONMENT DIVISION. 01130000
*------------------------ 01140000
01150000
DATA DIVISION. 01160000
*------------------------ 01170000
WORKING-STORAGE SECTION. 01180000
**************************************************************** 01190000
* DECLARATION FOR PASSING INPUT/OUTPUT DATA BETWEEN THE * 01200000
* SUBSYSTEM DEPENDENT MODULE IMS/DLI AND SQL1 AND SQL2 * 01210000
**************************************************************** 01220000
* 01230000
01 COMMAREA. 01240000
EXEC SQL INCLUDE DSN8MCCA END-EXEC. 01250000
**************************************************************** 01260000
* DECLARATION FOR INPUT: MIDNAME DSN8ICGI/DSN8ICDI * 01270000
**************************************************************** 01280000
* 01290000
01 IN-MESSAGE. 01300000
02 LL PIC S9(3) COMP-5. 01310000
02 Z1 PIC X. 01320000
02 Z2 PIC X. 01330000
02 TC-CODE PIC X(7). 01340000
02 IN-PUT. 01350000
03 MAJSYS PIC X. 01360000
03 ACTION PIC X. 01370000
03 OBJFLD PIC X(2). 01380000
03 SRCH PIC X(2). 01390000
03 PFKIN PIC X(2). 01400000
03 DATAIN PIC X(60). 01410000
03 TRANDATA PIC X(40) OCCURS 15. 01420000
* 01430000
02 IN-PUT0 REDEFINES IN-PUT PIC X(668). 01440000
**************************************************************** 01450000
* DECLARATION FOR OUTPUT: MODNAME DSN8ICGO/DSN8ICDO * 01460000
**************************************************************** 01470000
* 01480000
01 OUT-MESSAGE. 01490000
1346 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
02 LL PIC S9(3) COMP-5. 01500000
02 ZZ PIC S9(3) COMP-5 VALUE +0. 01510000
02 OUTPUTAREA. 01520000
03 MAJSYS PIC X. 01530000
03 ACTION PIC X. 01540000
03 OBJFLD PIC X(2). 01550000
03 SRCH PIC X(2). 01560000
03 DATAOUT PIC X(60). 01570000
03 HTITLE PIC X(50). 01580000
03 DESC2 PIC X(50). 01590000
03 DESC3 PIC X(50). 01600000
03 DESC4 PIC X(50). 01610000
03 MSG. 01620000
05 STC PIC X(4). 01630000
05 MSGTEXT PIC X(75). 01640000
03 PFKTEXT PIC X(79). 01650000
03 OUTPUT0 OCCURS 15. 01660000
05 LINE0 PIC X(79). 01670000
* 01680000
02 OUTPUTAREA0 REDEFINES OUTPUTAREA PIC X(1609). 01690000
**************************************************************** 01700000
* FIELDS SENT TO MESSAGE ROUTINE * 01710000
**************************************************************** 01720000
01 MSGCODE PIC X(04). 01730000
01740000
01 OUTMSG PIC X(69). 01750000
**************************************************************** 01760000
* DECLARATION FOR PGM-LOGIC * 01770000
**************************************************************** 01780000
* 01790000
77 GU-FKT PIC X(4) VALUE 'GU '. 01800000
77 ISRT-FKT PIC X(4) VALUE 'ISRT'. 01810000
77 CHNG-FKT PIC X(4) VALUE 'CHNG'. 01820000
77 ROLL-FKT PIC X(4) VALUE 'ROLL'. 01830000
* 01840000
77 MODNAME PIC X(8). 01850000
**************************************************************** 01860000
* LINKAGE SECTION * 01870000
**************************************************************** 01880000
LINKAGE SECTION. 01890000
**************************************************************** 01900000
* DECLARATION FOR IO / ALTPCB * 01910000
**************************************************************** 01920000
* 01930000
01 IOPCB. 01940000
02 IOLTERM PIC X(8). 01950000
02 FILLER PIC X(2). 01960000
02 STC-CODE PIC X(2). 01970000
02 CDATE PIC X(4). 01980000
02 CTIME PIC X(4). 01990000
02 SEQNUM PIC X(4). 02000000
02 MOD-NAME PIC X(8). 02010000
02 USERID PIC X(8). 02020000
* 02030000
01 ALTPCB. 02040000
02 ALTLTERM PIC X(8). 02050000
02 FILLER PIC X(2). 02060000
02 STC-CODE PIC X(2). 02070000
02080000
PROCEDURE DIVISION. 02090000
*--------------------- 02100000
* 02110000
ENTRY 'DLITCBL' USING IOPCB ALTPCB. 02120000
**************************************************************** 02130000
* ALLOCATE COBOL WORK AREA /INITIALIZATIONS * 02140000
**************************************************************** 02150000
* 02160000
CSTART. 02170000
MOVE SPACES TO COMMAREA. 02180000
MOVE SPACES TO IN-MESSAGE. 02190000
MOVE 'DSN8ICGO' TO MODNAME. 02200000
MOVE 'DSN8IC0' TO MAJOR IN DSN8-MODULE-NAME. 02210000
MOVE 'O' TO MAJSYS IN OUTAREA. 02220000
MOVE '0' TO EXITCODE. 02230000
MOVE +1613 TO LL IN OUT-MESSAGE. 02240000
* 02250000
**************************************************************** 02260000
* CALL DL1 GU INPUT MESSAGE * 02270000
* PRINT ERROR MESSAGE IF STATUS CODE NOT OK * 02280000
**************************************************************** 02290000
02300000
* **CALL DL1 GU 02310000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1347
CALL 'CBLTDLI' 02320000
USING GU-FKT IOPCB IN-MESSAGE. 02330000
02340000
* **ERROR? 02350000
IF STC-CODE IN IOPCB NOT = ' ' 02360000
THEN MOVE '064E' TO MSGCODE 02370000
CALL 'DSN8MCG' USING MAJOR MSGCODE OUTMSG 02380000
MOVE OUTMSG TO MSGTEXT IN OUTPUTAREA 02390000
MOVE STC-CODE IN IOPCB TO STC IN OUTPUTAREA 02400000
GO TO CSEND. 02410000
02420000
**************************************************************** 02430000
* CLEARED AND UNFORMATTED SCREEN? * 02440000
**************************************************************** 02450000
02460000
IF Z2 = LOW-VALUE 02470000
THEN MOVE '00' TO PFKIN IN INAREA. 02480000
MOVE IOLTERM IN IOPCB TO TRMID IN CONVID. 02490000
MOVE USERID IN IOPCB TO USERID IN CONVID. 02500000
02510000
* **MOVE INPUT MESSAGE 02520000
* **FIELDS TO INAREA FIELDS 02530000
MOVE IN-PUT0 TO INAREA0. 02540000
MOVE 'O' TO MAJSYS IN INAREA. 02550000
* 02560000
CALL 'DSN8IC1' USING COMMAREA. 02570000
02580000
* **MOVE OUTAREA FIELDS TO 02590000
* **OUTPUT MESSAGE FIELDS 02600000
MOVE OUTAREA0 TO OUTPUTAREA0. 02610000
* 02620000
IF LASTSCR = 'DSN8002' 02630000
THEN MOVE 'DSN8ICDO' TO MODNAME 02640000
ELSE MOVE 'DSN8ICGO' TO MODNAME. 02650000
02660000
**************************************************************** 02670000
* CALL DL ISRT OUTPUT MESSAGE * 02680000
* PRINT ERROR MESSAGE IF STATUS CODE NOT OK * 02690000
**************************************************************** 02700000
02710000
CSEND. 02720000
02730000
* **CALL DL1 ISRT 02740000
CALL 'CBLTDLI' 02750000
USING ISRT-FKT IOPCB OUT-MESSAGE MODNAME. 02760000
02770000
* **STATUS CODE OK 02780000
IF STC-CODE IN IOPCB = ' ' THEN GO TO CEND. 02790000
02800000
* **STATUS CODE NOT OK 02810000
* **PRINT ERROR MESSAGE 02820000
MOVE '065E' TO MSGCODE. 02830000
CALL 'DSN8MCG' USING MAJOR MSGCODE OUTMSG. 02840000
MOVE OUTMSG TO MSGTEXT IN OUTPUTAREA. 02850000
02860000
MOVE STC-CODE IN IOPCB TO STC IN OUTPUTAREA. 02870000
02880000
* **CALL DL1 CHNG 02890000
CALL 'CBLTDLI' 02900000
USING CHNG-FKT ALTPCB IOLTERM. 02910000
02920000
* **ERROR? 02930000
IF STC-CODE IN ALTPCB NOT = ' ' THEN 02940000
GO TO CSEND1. 02950000
02960000
* **CALL DL1 ISRT 02970000
CALL 'CBLTDLI' 02980000
USING ISRT-FKT IOPCB OUT-MESSAGE MODNAME. 02990000
03000000
* **PERFORM ROLLBACK 03010000
CSEND1. 03020000
CALL 'CBLTDLI' USING ROLL-FKT. 03030000
03040000
* **RETURN 03050000
CEND. 03060000
GOBACK. 03070000
03071000
Related reference
“Sample applications in IMS” on page 1344
1348 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
A set of Db2 sample applications run in the IMS environment.
DSN8IC1
THIS MODULE RETRIEVES THE ROW CONTAINING INFORMATION ON THE CURRENT CONVERSATION,
VALIDATES SELECTION CRITERIA, AND ISSUES MESSAGES TO COMPLETE THE ACTION, OBJECT, AND
SEARCH CRITERIA.
IDENTIFICATION DIVISION.
*------------------------
PROGRAM-ID. DSN8IC1.
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1349
* DATA-AREAS = *
* DSN8MCCA - COBOL STRUCTURE FOR COMMAREA *
* DSN8MCC2 - COMMAREA PART 2 *
* DSN8MCCS - VCONA TABLE DCL & PCONA DCLGEN *
* DSN8MCOV - VOPTVAL TABLE DCL & POPTVAL DCLGEN *
* DSN8MCVO - VALIDATION CURSORS *
* DSN8MCXX - SQL ERROR HANDLING MODULE *
* DSN8MC1 - SQL1 COMMON MODULE FOR IMS & CICS *
* DSN8MC3 - DSN8MC5 - VALIDATION MODULES CALLED BY DSN8MC1*
* *
* CONTROL-BLOCKS = *
* SQLCA - SQL COMMUNICATION AREA *
* *
* TABLES = NONE *
* *
* CHANGE-ACTIVITY = NONE *
* *
* *
* *PSEUDOCODE* *
* PROCEDURE *
* INCLUDE DECLARATIONS. *
* INCLUDE DSN8MC1. *
* *
* CC1EXIT: ( REFERENCED BY DSN8MC1 ) *
* RETURN. *
* *
* CC1CALL: ( REFERENCED BY DSN8MC1 ) *
* CALL 'DSN8IC2' USING COMMAREA. *
* GO TO MC1SAVE. (LABEL IN DSN8MC1) *
* *
* INCLUDE VALIDATION MODULES. *
* *
* END. *
*---------------------------------------------------------------*
*
ENVIRONMENT DIVISION.
*--------------------
DATA DIVISION.
*--------------------
WORKING-STORAGE SECTION.
*****************************************************************
* * DECLARE FIELD SENT TO MESSAGE ROUTINE *
* * DECLARE CONVERSATION STATUS *
* * DECLARE MESSAGE TEXT *
* * DECLARE OPTION VALIDATION *
* * DECLARE COMMON AREA AND COMMON AREA PART 2 *
*****************************************************************
********************************************************
* **SQL ERROR HANDLING
********************************************************
EXEC SQL WHENEVER SQLERROR GO TO DB-ERROR END-EXEC
EXEC SQL WHENEVER SQLWARNING GO TO DB-ERROR END-EXEC.
*
MOVE 'DSN8IC1 ' TO MAJOR IN DSN8-MODULE-NAME.
***********************************************************
* FIND VALID OPTIONS FOR ACTION, OBJECT, SEARCH CRITERION*
* RETRIEVE CONVERSATION, VALIDATE, CALL SQL2 *
***********************************************************
1350 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
*
* **RETURN
CC1-EXIT.
GOBACK.
***********************************************************
* VALIDATE ACTION, OBJECT, SEARCH CRITERIA *
* HANDLE ERRORS *
***********************************************************
CC1-CALL.
CALL 'DSN8IC2' USING COMMAREA.
GO TO MC1-SAVE.
Related reference
“Sample applications in IMS” on page 1344
A set of Db2 sample applications run in the IMS environment.
DSN8IC2
ROUTER FOR SECONDARY SELECTION AND/OR DETAIL PROCESSING CALLS SECONDARY SELECTION
MODULES DSN8MCA DSN8MCM CALLS DETAIL MODULES DSN8MCD DSN8MCE DSN8MCF DSN8MCT
DSN8MCV DSN8MCW DSN8MCX DSN8MCZ CALLED BY DSN8IC1 (SQL1) .
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1351
* 00460000
* OUTPUT = POINTER TO COMMAREA (COMMUNICATION AREA) 00470000
* 00480000
* SYMBOLIC LABEL/NAME = COMMAREA 00490000
* DESCRIPTION = COMMUNICATION AREA PASSED BETWEEN 00500000
* MODULES 00510000
* 00520000
* EXIT-NORMAL = 00530000
* 00540000
* EXIT-ERROR = IF SQLERROR OR SQLWARNING, SQL WHENEVER 00550000
* CONDITION SPECIFIED IN DSN8IC2 WILL BE RAISED 00560000
* AND PROGRAM WILL GO TO THE LABEL DB-ERROR. 00570000
* 00580000
* 00590000
* RETURN CODE = NONE 00600000
* 00610000
* ABEND CODES = NONE 00620000
* 00630000
* ERROR-MESSAGES = 00640000
* DSN8062E-AN OBJECT WAS NOT SELECTED 00650000
* DSN8066E-UNSUPPORTED PFK OR LOGIC ERROR 00660000
* DSN8072E-INVALID SELECTION ON SECONDARY SCREEN 00670000
* 00680000
* 00690000
* EXTERNAL REFERENCES = 00700000
* ROUTINES/SERVICES = 10 MODULES LISTED ABOVE 00710000
* DSN8MCG - ERROR MESSAGE ROUTINE 00720000
* 00730000
* DATA-AREAS = 00740000
* DSN8MCA - SECONDARY SELECTION FOR 00750000
* DSN8MCD - DEPARTMENT STRUCTURE DETAIL 00760000
* DSN8MCE - DEPARTMENT DETAIL 00770000
* DSN8MCF - EMPLOYEE DETAIL 00780000
* ORGANIZATION 00790000
* DSN8MCAD - DECLARE ADMINISTRATION DETAIL 00800000
* DSN8MCAE - CURSOR EMPLOYEE LIST 00810000
* DSN8MCAL - CURSOR ADMINISTRATION LIST 00820000
* DSN8MCA2 - DECLARE ADMINISTRATION DETAIL 00830000
* DSN8MCC2 - SQL COMMON AREA PART 2 00840000
* DSN8MCDA - CURSOR ADMINISTRATION DETAIL 00850000
* DSN8MCDH - CURSOR FOR DISPLAY TEXT FROM 00860000
* TDSPTXT TABLE 00870000
* DSN8MCDP - DECLARE DEPARTMENT 00880000
* DSN8MCEM - DECLARE EMPLOYEE 00890000
* DSN8MCED - DECLARE EMPLOYEE-DEPARTMENT 00900000
* DSN8MCDM - DECLARE DEPARTMENT MANAGER 00910000
* DSN8MCAD - DECLARE ADMINISTRATION DETAIL 00920000
* DSN8MCA2 - DECLARE ADMINISTRATION DETAIL 00930000
* DSN8MCOV - DECLARE OPTION VALIDATION 00940000
* DSN8MCDT - DECLARE DISPLAY TEXT 00950000
* DSN8MCCA - SQL COMMON AREA 00960000
* DSN8MCXX - ERROR HANDLER 00970000
* 00980000
* CONTROL-BLOCKS = 00990000
* SQLCA - SQL COMMUNICATION AREA 01000000
* 01010000
* TABLES = NONE 01020000
* 01030000
* CHANGE-ACTIVITY = 01040000
* - ADD NEW VARIABLES FOR REFERENTIAL INTEGRITY V2R1 01050000
* 01060000
* *PSEUDOCODE* 01070000
* 01080000
* THIS MODULE DETERMINES WHICH SECONDARY SELECTION AND/OR 01090000
* DETAIL MODULE(S) ARE TO BE CALLED FOR THE IMS/COBOL ENVIRONMENT 01100000
* 01110000
* WHAT HAS HAPPENED SO FAR?.............. THE SUBSYSTEM 01120000
* DEPENDENT MODULE (IMS,CICS) (SQL 0) HAS READ THE 01130000
* INPUT SCREEN, FORMATTED THE INPUT, AND PASSED CONTROL 01140000
* TO SQL 1. SQL 1 PERFORMS VALIDATION ON THE SYSTEM DEPENDENT 01150000
* FIELDS (MAJOR SYSTEM, ACTION, OBJECT, SEARCH CRITERIA). IF 01160000
* ALL SYSTEM FIELDS ARE VALID, SQL 1 PASSED CONTROL TO THIS 01170000
* MODULE. PASSED PARAMETERS CONSIST ONLY OF A POINTER WHICH 01180000
* POINTS TO A COMMUNICATION CONTROL AREA USED TO COMMUNICATE 01190000
* BETWEEN SQL 0 , SQL 1, SQL 2, AND THE SECONDARY SELECTION 01200000
* AND DETAIL MODULES. 01210000
* 01220000
* WHAT IS INCLUDED IN THIS MODULE?............ 01230000
* ALL SECONDARY SELECTION AND DETAIL MODULES ARE 'INCLUDED'. 01240000
* ALL VARIABLES KNOWN IN THIS PROCEDURE ARE KNOWN IN THE 01250000
* SUB PROCEDURES. ALL SQL CURSOR DEFINITIONS AND 01260000
* SQL 'INCLUDES' ARE DONE IN THIS PROCEDURE. ALL CURSOR HOST 01270000
1352 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* VARIABLES ARE DECLARED IN THIS PROCEDURE BECAUSE OF THE 01280000
* RESTRICTION THAT CURSOR HOST VARIABLES MUST BE DECLARED BEFORE 01290000
* THE CURSOR DEFINITION. 01300000
* 01310000
* PROCEDURE 01320000
* IF ANSWER TO DETAIL SCREEN & DETAIL PROCESSOR 01330000
* IS NOT WILLING TO ACCEPT AN ANSWER THEN 01340000
* NEW REQUEST* 01350000
* 01360000
* ELSE 01370000
* IF ANSWER TO A SECONDARY SELECTION THEN 01380000
* DETERMINE IF NEW REQUEST. 01390000
* 01400000
* CASE (NEW REQUEST) 01410000
* 01420000
* SUBCASE ('ADD') 01430000
* DETAIL PROCESSOR 01440000
* RETURN TO SQL 1 01450000
* ENDSUB 01460000
* 01470000
* SUBCASE ('DISPLAY','ERASE','UPDATE') 01480000
* CALL SECONDARY SELECTION 01490000
* IF # OF POSSIBLE CHOICES IS ^= 1 THEN 01500000
* RETURN TO SQL 1 01510000
* ELSE 01520000
* CALL THE DETAIL PROCESSOR 01530000
* RETURN TO SQL 1. 01540000
* ENDSUB 01550000
* 01560000
* ENDCASE 01570000
* 01580000
* IF ANSWER TO SECONDARY SELECTION AND A SELECTION HAS 01590000
* ACTUALLY BEEN MADE THEN 01600000
* VALID SELECTION #? 01610000
* IF IT IS VALID THEN 01620000
* CALL DETAIL PROCESSOR 01630000
* RETURN TO SQL 1 01640000
* ELSE 01650000
* PRINT ERROR MSG 01660000
* RETURN TO SQL 1. 01670000
* 01680000
* IF ANSWER TO SECONDARY SELECTION THEN 01690000
* CALL SECONDARY SELECTION 01700000
* RETURN TO SQL 1. 01710000
* 01720000
* IF ANSWER TO DETAIL THEN 01730000
* CALL DETAIL PROCESSOR 01740000
* RETURN TO SQL 1. 01750000
* 01760000
* END. 01770000
* 01780000
* *EXAMPLE- A ROW IS SUCCESSFULLY ADDED, THE OPERATOR RECEIVES 01790000
* THE SUCCESSFULLY ADDED MESSAGE AND JUST HITS ENTER. 01800000
*----------------------------------------------------------- 01810000
/ 01820000
01830000
ENVIRONMENT DIVISION. 01840000
*-------------------------- 01850000
01860000
DATA DIVISION. 01870000
*------------------- 01880000
WORKING-STORAGE SECTION. 01890000
01900000
******************************************************* 01910000
* FIELD SENT TO MESSAGE ROUTINE 01920000
******************************************************* 01930000
01 MSGCODE PIC X(04). 01940000
01 OUTMSG PIC X(69). 01950000
01960000
*************************************** 01970000
* NULL INDICATOR * 01980000
*************************************** 01990000
01 NULLIND1 PIC S9(4) COMP-4. 02000000
01 NULLIND2 PIC S9(4) COMP-4. 02010000
01 NULLIND3 PIC S9(4) COMP-4. 02020000
01 NULLIND4 PIC S9(4) COMP-4. 02030000
01 NULLIND5 PIC S9(4) COMP-4. 02040000
01 NULLARRY. 02050000
03 NULLARRY1 PIC S9(4) USAGE COMP OCCURS 13 TIMES. 02060000
02070000
EXEC SQL INCLUDE SQLCA END-EXEC. 02080000
02090000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1353
EXEC SQL INCLUDE DSN8MCC2 END-EXEC. 02100000
EXEC SQL INCLUDE DSN8MCDP END-EXEC. 02110000
EXEC SQL INCLUDE DSN8MCEM END-EXEC. 02120000
EXEC SQL INCLUDE DSN8MCDM END-EXEC. 02130000
EXEC SQL INCLUDE DSN8MCAD END-EXEC. 02140000
EXEC SQL INCLUDE DSN8MCA2 END-EXEC. 02150000
EXEC SQL INCLUDE DSN8MCOV END-EXEC. 02160000
EXEC SQL INCLUDE DSN8MCDT END-EXEC. 02170000
EXEC SQL INCLUDE DSN8MCED END-EXEC. 02180000
02190000
01 CONSTRAINTS. 02200000
03 PARM-LENGTH PIC S9(4) COMP-4. 02210000
03 REF-CONSTRAINT PIC X(08). 02220000
03 FILLER PIC X(62). 02230000
01 MGRNO-CONSTRAINT PIC X(08) VALUE 'RDE '. 02240000
02250000
LINKAGE SECTION. 02260000
01 COMMAREA. 02270000
EXEC SQL INCLUDE DSN8MCCA END-EXEC. 02280000
02290000
PROCEDURE DIVISION USING COMMAREA. 02300000
*------------------ 02310000
******************************************************* 02320000
* SQL ERROR CODE HANDLING 02330000
******************************************************* 02340000
EXEC SQL WHENEVER SQLERROR GO TO DB-ERROR END-EXEC 02350000
EXEC SQL WHENEVER SQLWARNING GO TO DB-ERROR END-EXEC. 02360000
02370000
EXEC SQL INCLUDE DSN8MCAE END-EXEC. 02380000
EXEC SQL INCLUDE DSN8MCAL END-EXEC. 02390000
EXEC SQL INCLUDE DSN8MCDH END-EXEC. 02400000
EXEC SQL INCLUDE DSN8MCDA END-EXEC. 02410000
02420000
******************************************************* 02430000
* INITIALIZATIONS 02440000
******************************************************* 02450000
02460000
MOVE 'DSN8IC2' TO MAJOR. 02470000
MOVE SPACES TO MINOR. 02480000
02490000
02500000
IF NEWREQ OF COMPARM = 'Y' THEN GO TO IC2008. 02510000
02520000
******************************************************* 02530000
* DETERMINES WHETHER NEW REQUEST OR NOT 02540000
******************************************************* 02550000
IC2005. 02560000
IF PREV OF PCONVSTA = ' ' THEN 02570000
MOVE 'Y' TO NEWREQ OF COMPARM. 02580000
02590000
IF NEWREQ OF COMPARM = 'N' AND PREV OF PCONVSTA = 'S' 02600000
AND DATA01 NOT = ' ' 02610000
AND DATAIN NOT = 'NEXT' 02620000
THEN MOVE 'Y' TO NEWREQ OF COMPARM. 02630000
02640000
IF NEWREQ OF COMPARM NOT = 'Y' THEN GO TO IC2010. 02650000
******************************************************* 02660000
* IF NEW REQUEST AND ACTION IS 'ADD' THEN 02670000
* CALL DETAIL PROCESSOR 02680000
* ELSE CALL SECONDARY SELECTION 02690000
******************************************************* 02700000
IC2008. 02710000
IF ACTION OF INAREA = 'A' THEN 02720000
* **DETAIL PROCESSOR 02730000
GO TO DETAIL0. 02740000
* **SECONDARY SELECTION 02750000
PERFORM SECSEL THRU END-SECSEL. 02760000
* **IF NO. OF CHOICES = 1 02770000
* **GO TO DETAIL PROCESSOR 02780000
IF MAXSEL = 1 THEN GO TO DETAIL0. 02790000
GO TO EXIT0. 02800000
******************************************************* 02810000
* DETERMINE IF VALID SELECTION NUMBER GIVEN 02820000
******************************************************* 02830000
IC2010. 02840000
* **VALID SELECTION NO. GIVEN 02850000
IF PREV OF PCONVSTA NOT = 'S' 02860000
OR MAXSEL < 1 02870000
OR DATAIN = 'NEXT' 02880000
OR DATA2 = DATO2 THEN GO TO IC201. 02890000
* 02900000
IF DAT1 NUMERIC AND DAT2 = ' ' THEN 02910000
1354 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
MOVE DAT1 TO DAT2 02920000
MOVE '0' TO DAT1. 02930000
02940000
* **DETAIL SELECTION GIVEN 02950000
IF DATA2 NUMERIC 02960000
AND DATA2 > '00' AND DATA2 NOT > MAXSEL THEN 02970000
MOVE 'Y' TO NEWREQ OF COMPARM 02980000
GO TO DETAIL0. 02990000
03000000
* **INVALID SELECTION NO. 03010000
* **PRINT ERROR MESSAGE 03020000
MOVE '072E' TO MSGCODE. 03030000
CALL 'DSN8MCG' USING MAJOR MSGCODE OUTMSG. 03040000
MOVE OUTMSG TO MSG OF OUTAREA. 03050000
GO TO EXIT0. 03060000
03070000
******************************************************* 03080000
* DETERMINES WHETHER SECONDARY SELECTION OR DETAIL 03090000
******************************************************* 03100000
IC201. 03110000
* **SECONDARY SELECTION 03120000
IF PREV OF PCONVSTA = 'S' THEN 03130000
PERFORM SECSEL THRU END-SECSEL 03140000
GO TO EXIT0. 03150000
03160000
* **DETAIL PROCESSOR 03170000
IF PREV OF PCONVSTA = 'D' THEN GO TO DETAIL0. 03180000
03190000
* **LOGIC ERROR 03200000
* **PRINT ERROR MESSAGE 03210000
MOVE '066E' TO MSGCODE. 03220000
CALL 'DSN8MCG' USING MAJOR MSGCODE OUTMSG. 03230000
MOVE OUTMSG TO MSG OF OUTAREA. 03240000
GO TO EXIT0. 03250000
03260000
*********************************************************** 03270000
* CALLS SECONDARY SELECTION PROCESSOR AND RETURNS TO SQL 1 03280000
*********************************************************** 03290000
SECSEL. 03300000
MOVE 'DSN8001 ' TO LASTSCR IN PCONVSTA. 03310000
IF OBJFLD OF INAREA = 'DS' THEN 03320001
* **ADMINISTRATIVE 03330000
* **DEPARTMENT STRUCTURE 03340000
PERFORM DSN8MCA THRU END-DSN8MCA 03350000
ELSE 03360000
IF OBJFLD OF INAREA = 'DE' THEN 03370001
* **INDIVIDUAL DEPARTMENT 03380000
* **PROCESSING 03390000
PERFORM DSN8MCA THRU END-DSN8MCA 03400000
ELSE 03410000
IF OBJFLD OF INAREA = 'EM' THEN 03420001
* **INDIVIDUAL EMPLOYEE 03430000
* **PROCESSING 03440000
PERFORM DSN8MCA THRU END-DSN8MCA 03450000
ELSE 03460000
* **ERROR MESSAGE 03470000
* **UNSUPPORTED SEARCH 03480000
* **CRITERIA FOR OBJECT 03490000
MOVE '062E' TO MSGCODE 03500000
CALL 'DSN8MCG' USING MAJOR MSGCODE OUTMSG 03510000
MOVE OUTMSG TO MSG OF OUTAREA 03520000
GO TO EXIT0. 03530000
END-SECSEL. 03540000
03550000
******************************************************* 03560000
* CALLS DETAIL PROCESSOR AND RETURNS TO SQL 1 03570000
******************************************************* 03580000
DETAIL0. 03590000
MOVE 'DSN8002 ' TO LASTSCR IN PCONVSTA. 03600000
03610000
IF OBJFLD OF INAREA = 'DS' THEN 03620001
* **ADMINISTRATIVE 03630000
* **DEPARTMENT STRUCTURE 03640000
PERFORM DSN8MCD THRU END-DSN8MCD 03650000
ELSE 03660000
IF OBJFLD OF INAREA = 'DE' THEN 03670001
* **INDIVIDUAL DEPARTMENT 03680000
* **PROCESSING 03690000
PERFORM DSN8MCE THRU END-DSN8MCE 03700000
ELSE 03710000
IF OBJFLD OF INAREA = 'EM' THEN 03720001
* **INDIVIDUAL EMPLOYEE 03730000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1355
* **PROCESSING 03740000
PERFORM DSN8MCF THRU END-DSN8MCF 03750000
ELSE 03760000
* **ERROR MESSAGE 03770000
* **UNSUPPORTED SEARCH 03780000
* **CRITERIA FOR OBJECT 03790000
MOVE '062E' TO MSGCODE 03800000
CALL 'DSN8MCG' USING MAJOR MSGCODE OUTMSG 03810000
MOVE OUTMSG TO MSG OF OUTAREA. 03820000
GO TO EXIT0. 03830000
* **HANDLES ERRORS 03840000
* **RETURN TO SQL 1 03850000
EXEC SQL INCLUDE DSN8MCXX END-EXEC. 03860000
EXIT0. GOBACK. 03870000
03880000
EXEC SQL INCLUDE DSN8MCA END-EXEC. 03890000
EXEC SQL INCLUDE DSN8MCD END-EXEC. 03900000
EXEC SQL INCLUDE DSN8MCE END-EXEC. 03910000
EXEC SQL INCLUDE DSN8MCF END-EXEC. 03920000
03930000
Related reference
“Sample applications in IMS” on page 1344
A set of Db2 sample applications run in the IMS environment.
DSN8IP0
THIS MODULE RECEIVES INPUT MESSAGE AND DEFORMATS IT, CALLS DSN8IP1, FORMATS OUTPUT
MESSAGE AND SENDS IT .
1356 Db2 12 for z/OS: Application Programming and SQL Guide (Last updated: 2023-10-24)
* EXIT-ERROR = * 00490000
* * 00500000
* RETURN CODE = NONE * 00510000
* * 00520000
* ABEND CODES = NONE * 00530000
* * 00540000
* ERROR-MESSAGES = * 00550000
* DSN8064E - INVALID DL/I STC-CODE ON GU MSG * 00560000
* DSN8065E - INVALID DL/I STC-CODE ON ISRT MSG * 00570000
* * 00580000
* EXTERNAL REFERENCES = * 00590000
* ROUTINES/SERVICES = MODULE DSN8IP1 * 00600000
* MODULE PLITDLI * 00610000
* MODULE DSN8MPG * 00620000
* * 00630000
* DATA-AREAS = * 00640000
* DSN8MPCA - PARAMETER TO BE PASSED TO DSN8CP1 * 00650000
* CONTAINS TERMINAL INPUT AND * 00660000
* OUTPUT AREAS. * 00670000
* IN_MESSAGE - MFS INPUT * 00680000
* OUT_MESSAGE - MFS OUTPUT * 00690000
* * 00700000
* CONTROL-BLOCKS = NONE * 00710000
* * 00720000
* TABLES = NONE * 00730000
* * 00740000
* CHANGE-ACTIVITY = NONE * 00750000
* * 00760000
* * 00770000
* *PSEUDOCODE* * 00780000
* * 00790000
* PROCEDURE * 00800000
* DECLARATIONS. * 00810000
* ALLOCATE PL/I WORK AREA FOR COMMAREA. * 00820000
* INITIALIZATION. * 00830000
* PUT MODNAME 'DSN8IPGO' IN MODNAME FIELD. * 00840000
* PUT MODULE NAME 'DSN8IP0' IN AREA USED BY * 00850000
* ERROR_HANDLER. * 00860000
* * 00870000
* STEP1. * 00880000
* CALL DLI GU INPUT MESSAGE. * 00890000
* IF STATUS CODE NOT OK THEN SEND ERROR MESSAGE AND * 00900000
* STOP PROGRAM. * 00910000
* * 00920000
* IF SCREEN CLEARED/UNFORMATTED , MOVE '00' TO PFKIN. * 00930000
* MOVE INPUT MESSAGE FIELDS TO CORRESPONDING * 00940000
* INAREA FIELDS IN COMPARM. * 00950000
* CALL DSN8IP1 (COMMAREA) * 00960000
* MOVE OUTAREA FIELDS IN PCONVSTA TO CORRESPONDING * 00970000
* OUTPUT MESSAGE FIELDS. * 00980000
* IF LASTSCR 'DSN8001' MOVE 'DSN8IPGO' TO MODNAME FIELD * 00990000
* ELSE MOVE 'DSN8IPDO' TO MODNAME FIELD. * 01000000
* * 01010000
* CALL DLI ISRT OUTPUT MESSAGE. * 01020000
* IF STATUS CODE NOT OK THEN SEND ERROR MESSAGE AND * 01030000
* STOP PROGRAM. * 01040000
* END. * 01050000
* * 01060000
*--------------------------------------------------------------------* 01070000
1/*********************************************************************/01080000
/* DECLARATION FOR INPUT: MIDNAME DSN8IPGI/DSN8IPDI */01090000
/*********************************************************************/01100000
0DCL 1 IN_MESSAGE STATIC, 01110000
2 LL BIN FIXED (31), 01120000
2 Z1 CHAR (1), 01130000
2 Z2 CHAR (1), 01140000
2 TC_CODE CHAR (7), 01150000
2 MESSAGE, 01160000
3 INPUT, 01170000
5 MAJSYS CHAR (1), 01180000
5 ACTION CHAR (1), 01190000
5 OBJFLD CHAR (2), 01200002
5 SEARCH CHAR (2), 01210000
5 PFKIN CHAR (2), 01220000
5 DATA CHAR (60), 01230000
5 TRANDATA(15) CHAR (40); 01240000
-/*********************************************************************/01250000
/* DECLARATION FOR OUTPUT: MODNAME DSN8IPGO/DSN8IPDO */01260000
/*********************************************************************/01270000
0DCL 1 OUT_MESSAGE STATIC, 01280000
2 LL BIN FIXED (31) INIT (1613), 01290000
2 ZZ BIN FIXED (15) INIT (0), 01300000
Chapter 12. Sample data and applications supplied with Db2 for z/OS 1357
2 OUTPUT, 01310000
3 OUTPUTAREA, 01320000
5 MAJSYS CHAR (1), 01330000
5 ACTION CHAR (1), 01340000
5 OBJFLD CHAR (2), 01350002
5 SEARCH CHAR (2), 01360000
5 DATA CHAR (60), 01370000
5 TITLE CHAR (50), 01380000
5 DESC2 CHAR (50), 01390000
5 DESC3 CHAR (50), 01400000
5 DESC4 CHAR (50), 01410000
5 MSG CHAR (79), 01420000
5 PFKTEXT CHAR (79), 01430000
5 OUTPUT, 01440000
7 LINE (15) CHAR (79); 01450000
1/*********************************************************************/01460000
/* DECLARATION FOR PASSING INPUT/OUTPUT DATA BETWEEN THE */01470000
/* SUBSYSTEM DEPENDENT MODULE IMS/DL1 AND SQL1 AND SQL2 */01480000
/*********************************************************************/01490000
EXEC SQL INCLUDE DSN8MPCA; 01500000
01510000
DCL DSN8MPG EXTERNAL ENTRY;