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

HP NonStop SQL

Programming Manual
for TAL

Abstract
This manual describes the programmatic interface to HP NonStop™ SQL for the
Transaction Application Language (TAL). The NonStop SQL relational database
management system (RDBMS) uses the structured query language (SQL) to describe
and manipulate data in NonStop SQL databases. This manual is intended for
application programmers who are coding embedded SQL statements in a TAL
program.
Product Version
NonStop SQL C30
Supported Release Version Updates (RVUs)
This publication supports D40.00 and all subsequent D-series RVUs and G06.00 and
all subsequent G-series RVUs until otherwise indicated by its replacement publication.

Part Number Published


527887-001 March 2004
Document History
Part Number Product Version Published
N.A. NonStop SQL C30 September 1990
N.A. NonStop SQL C30 December 1991
527887-001 NonStop SQL C30 March 2004
HP NonStop SQL Programming
Manual for TAL

Index Figures Tables

What’s New in This Manual ix


Manual Information ix
New and Changed Information ix
About This Manual xi
Audience xi
Organization xii
Related Manuals xii
Notation Conventions xv

1. Introduction
Why Use Embedded SQL Statements? 1-1
Developing a Program 1-2
Embedding SQL Statements 1-2
Declaring Host Variables 1-3
Calling SQL System Procedures 1-3
Using Static SQL Statements 1-4
Using Dynamic SQL Operations 1-5
Compiling and Executing a Program 1-7

2. Host Variables and Parameters


Host Variables 2-1
Declaring Host Variables 2-2
Using Corresponding SQL and TAL Data Types 2-2
Overriding Default Data Types 2-5
Using Host Variables 2-6
Using Indicator Variables for Null Values 2-17
Creating Host Variables With the INVOKE Directive 2-20
Parameters 2-23
Using a Parameter List 2-24
Using Parameters in Loops 2-25
Using Indicator Parameters 2-25
Using Default Parameter Data Types 2-26

Hewlett-Packard Company—527887-001
i
Contents 3. NonStop SQL Statements and Directives

3. NonStop SQL Statements and Directives


Embedding SQL Statements and Directives 3-1
Coding Statements and Directives 3-2
Placing Statements and Directives in a Program 3-2
Locating Information About SQL Statements and Directives 3-4
BEGIN DECLARE SECTION and END DECLARE SECTION 3-6
CLOSE 3-7
CONTROL Directives 3-8
DECLARE CURSOR 3-11
DELETE 3-13
DESCRIBE and DESCRIBE INPUT 3-16
DROP 3-17
EXECUTE and EXECUTE IMMEDIATE 3-18
FETCH 3-18
INCLUDE SQLCA, INCLUDE SQLDA, and INCLUDE SQLSA 3-19
INSERT 3-19
INVOKE 3-22
OPEN 3-29
PREPARE 3-30
RELEASE 3-31
SELECT 3-31
SQL 3-35
SQLMEM 3-37
SYMBOLPAGES 3-42
UPDATE 3-42
WHENEVER 3-47

4. System Procedures
Procedure Descriptions 4-2
SQLCADISPLAY 4-2
SQLCAFSCODE 4-7
SQLCAGETINFOLIST 4-8
SQLCATOBUFFER 4-13
SQLGETCATALOGVERSION 4-19
SQLGETOBJECTVERSION 4-19
SQLGETSYSTEMVERSION 4-21
SQLSADISPLAY 4-22

HP NonStop SQL Programming Manual for TAL—527887-001


ii
Contents 5. Program Compilation and Execution

5. Program Compilation and Execution


Compiling a TAL Program 5-2
Running the TAL Compiler 5-3
Using the Binder Program 5-4
Including the TALLIB Run-Time Library 5-4
Running the Accelerator 5-5
Running the SQL Compiler 5-5
Using the EXPLAIN Utility 5-17
Determining Program File Validity 5-22
Changes to a Program File 5-22
Changes to Database Objects 5-23
Other Changes 5-23
Understanding Automatic SQL Recompilation 5-24
Predicting Automatic SQL Recompilation 5-24
Understanding the Run-Time Timestamp Check 5-26
Understanding Run-Time Recompilation Errors 5-28
Maximizing Local Autonomy 5-28
Using a Local Partition 5-28
Using TACL DEFINEs 5-29
Using Current Statistics 5-29
Skipping Unavailable Partitions 5-30
Executing an SQL Program File 5-30
Using the RUN Command 5-30
Using TACL DEFINEs 5-31
Estimating Program Size 5-32

6. Error and Status Processing


Getting Error and Warning Information 6-1
Using the SQLCODE Variable 6-1
Using the WHENEVER Directive 6-4
Getting Information From the SQLCA 6-9
Getting Performance and Statistics Information 6-10
Getting Information About Dynamic SQL Operations 6-13
Declaring the SQLDA and Names Buffer 6-14
Initializing the EYE^CATCHER Field 6-18
Using Literal Declarations for the SQLDA 6-18
Example of Using the SQLDA 6-21

HP NonStop SQL Programming Manual for TAL—527887-001


iii
Contents 7. Dynamic NonStop SQL Operations

7. Dynamic NonStop SQL Operations


Determining Uses for Dynamic SQL Operations 7-2
Developing a Dynamic SQL Application 7-2
Writing a Dynamic SQL Pathway Server 7-3
Specifying Input Parameters and Output Variables 7-4
Using the SQLDA and Names Buffer 7-5
Using Dynamic SQL Programming Techniques 7-7
Overview of a Dynamic SQL Program 7-7
Dynamically Allocating Memory 7-14
Using the Names Buffer 7-23
Allocating and Filling in Output Variables 7-27
Using Dynamic Cursors 7-31
Using Statement and Cursor Host Variables 7-33
Handling Null Values 7-36

A. Sample NonStop SQL Database


B. Examples of Static NonStop SQL Programs
Insertion Program B-1
Date-Time Program B-10

C. Examples of Dynamic NonStop SQL Programs


Dynamic SQL Program C-1
Detailed Dynamic SQL Program C-9

D. NonStop SQL Version Issues


Version 1 and Version 2 Definitions D-1
Summary of Incompatible Changes D-3
Migrating a C10 Program to Run on a C30 System D-4
Migrating a C10 Program to Access Version 2 Objects D-7
Dynamic SQL Operations D-7
Static SQL Operations D-8
Catalog Tables D-8
Summary D-8
Installing Migrated Programs D-8
SQL Component Compatibility D-9
Developing C10 Programs with C30 Software D-10
Binding C10 and C30 Object Files D-10
Mixed-Version Programmatic Features D-11
Release Specification Options D-11

HP NonStop SQL Programming Manual for TAL—527887-001


iv
Contents D. NonStop SQL Version Issues (continued)

D. NonStop SQL Version Issues (continued)


System Procedures D-11
Techniques for Mixed-Version Programming D-12
Handling Mixed-Version-Objects D-12
Running on Multiple NonStop SQL Releases D-13
Using the Single-Code Thread Design D-14

E. Enforcing Data Integrity


Using Constraints E-1
Managing Referential Integrity E-2

Index
Figures
Figure i. Related Manuals xiv
Figure 1-1. Static SQL Statements in a TAL Program 1-5
Figure 1-2. Dynamic SQL Statements in a TAL Program 1-6
Figure 1-3. Compiling and Executing a Program 1-8
Figure 4-1. SQLSADISPLAY Display 4-24
Figure 5-1. Compiling and Executing a Program 5-2
Figure 5-2. NonStop SQL Program File Format 5-12
Figure 5-3. Sample SQL Compiler Listing 5-16
Figure 5-4. OBEY Command File Format of the EXPLAIN DEFINES Report 5-19
Figure 5-5. INFO DEFINE Format of the EXPLAIN DEFINES Report 5-20
Figure 5-6. EXPLAIN Utility Report 5-21
Figure 5-7. Run-Time Checks and Automatic SQL Recompilation 5-27
Figure 6-1. Checking the SQLCODE Variable 6-3
Figure 6-2. Enabling and Disabling the WHENEVER Directive 6-6
Figure 6-3. Using WHENEVER Directives 6-8
Figure 6-4. Calling an SQL System Procedure 6-10
Figure 6-5. SQLSA Structure Description 6-11
Figure 6-6. Release C30 SQLDA Template and Names Buffer 6-15
Figure 6-7. Release C10 SQLDA Template and Names Buffer 6-16
Figure 6-8. SQLDA Structure Template 6-22
Figure 7-1. Using a PREPARE Statement to Compile a Statement 7-16
Figure 7-2. Allocating the SQLDA Structure 7-19
Figure 7-3. Allocating Memory for Values 7-22
Figure 7-4. Getting Parameter Values 7-25
Figure 7-5. Displaying Output 7-29
Figure 7-6. Statement and Cursor Host Variables 7-34
HP NonStop SQL Programming Manual for TAL—527887-001
v
Contents Figures (continued)

Figures (continued)
Figure A-1. Sample NonStop SQL Database Relations A-2
Figure A-2. Sample Database Source File A-3
Figure B-1. Insertion Program Output B-2
Figure B-2. Date-Time Program Run B-12
Figure C-1. Output for the Dynamic SQL Program C-2
Figure C-2. Output for the Detailed Dynamic SQL Program C-11
Figure D-1. Developing a Program For Mixed-Version Nodes D-15

Tables
Table 1-1. NonStop SQL Statements 1-2
Table 1-2. NonStop SQL Directives 1-3
Table 2-1. Corresponding NonStop SQL and TAL Data Types 2-3
Table 2-2. Default and Override Data Type Mapping 2-6
Table 2-3. Date-Time and INTERVAL Data Types 2-16
Table 2-4. INVOKE Directive Override Data Type Mapping 2-20
Table 3-1. Summary of NonStop SQL Statements and Directives 3-4
Table 3-2. INVOKE Directive Override Data Type Mapping 3-23
Table 3-3. NonStop SQL Data Structures 3-38
Table 4-1. System Procedures for NonStop SQL Operations 4-1
Table 4-2. SQLCAGETINFOLIST Procedure Item Codes 4-11
Table 4-3. SQLCAGETINFOLIST Procedure Error Codes 4-12
Table 4-4. NonStop SQL Release C30 (Version 2) Features 4-20
Table 4-5. SQLSADISPLAY Procedure Display Elements 4-23
Table 5-1. Calculating Virtual Memory Requirements for Each SQL Statement or
Directive 5-33
Table 6-1. TAL Compiler Pseudocode for Checking SQLCODE 6-4
Table 6-2. System Procedures for the SQLCA Structure 6-9
Table 6-3. SQLSA Fields 6-11
Table 6-4. SQLDA Fields 6-17
Table 6-5. Literal Declarations for Character, Numeric, and Decimal Values 6-19
Table 6-6. Literal Declarations for Date-Time and INTERVAL Values 6-19
Table 6-7. Literal Declarations for Ranges of Date-Time Fields 6-20
Table 7-1. Literal Declarations for Data Types 7-21
Table D-1. Version 2 Items and Descriptions D-2
Table D-2. Version 1 Items and Descriptions D-2
Table D-3. Summary of New Columns in Version 2 Catalogs D-3
Table D-4. Incompatible NonStop SQL Release C30 Features D-4

HP NonStop SQL Programming Manual for TAL—527887-001


vi
Contents Tables (continued)

Tables (continued)
Table D-5. Accessing Version 2 Objects from a C10 Program D-8
Table D-6. Release C10 Versioning IPM Summary D-9

HP NonStop SQL Programming Manual for TAL—527887-001


vii
Contents

HP NonStop SQL Programming Manual for TAL—527887-001


viii
What’s New in This Manual
Manual Information
HP NonStop SQL Programming Manual for TAL

Abstract
This manual describes the programmatic interface to HP NonStop™ SQL for the
Transaction Application Language (TAL). The NonStop SQL relational database
management system (RDBMS) uses the structured query language (SQL) to describe
and manipulate data in NonStop SQL databases. This manual is intended for
application programmers who are coding embedded SQL statements in a TAL
program.
Product Version
NonStop SQL C30
Supported Release Version Updates (RVUs)
This publication supports D40.00 and all subsequent D-series RVUs and G06.00 and
all subsequent G-series RVUs until otherwise indicated by its replacement publication.

Part Number Published


527887-001 March 2004

Document History
Part Number Product Version Published
N.A. NonStop SQL C30 September 1990
N.A. NonStop SQL C30 December 1991
527887-001 NonStop SQL C30 March 2004

New and Changed Information


This publication has been updated to reflect new product names:
• Since product names are changing over time, this publication might contain both
HP and Compaq product names.
• Product names in graphic representations are consistent with the current product
interface.
• The technical content of this publication has not been updated and reflects the
state of the product at the G06.22 release version update (RVU).

HP NonStop SQL Programming Manual for TAL—527887-001


ix
What’s New in This Manual New and Changed Information

HP NonStop SQL Programming Manual for TAL—527887-001


x
About This Manual
This manual describes the programmatic interface to NonStop SQL for the Transaction
Application Language (TAL). The NonStop SQL relational database management
system (RDBMS) uses the structured query language (SQL) to define and manipulate
data in NonStop SQL databases.
NonStop SQL provides both a conversational and a programmatic interface. Using the
programmatic interface, a C, COBOL85, Pascal, or TAL programmer can use
embedded SQL statements to access a NonStop SQL database.

Audience
This manual is intended for TAL programmers who are coding embedded SQL
statements in a TAL program. A reader should be familiar with:
• TAL
• NonStop SQL terms and concepts (as described in the Introduction to NonStop
SQL)
• The HP NonStop Kernel operating system

Organization
Section 1 Provides an overview of the TAL programmatic interface to NonStop SQL.
Section 2 Describes how to declare and use host variables and parameters in a TAL
program.
Section 3 Describes the statements and directives that have unique TAL
considerations, data structures, or examples.
Section 4 Describes the SQL system library procedures and shows how to call them
from a TAL program.
Section 5 Describes how to compile and execute a TAL program that contains
embedded SQL statements.
Section 6 Describes how to process error and status messages and statistics
information using the SQLCODE variable and the SQLCA, SQLDA, and
SQLSA data structures.
Section 7 Describes how to use dynamic SQL operations.
Appendix A Describes the sample NonStop SQL database that is used by the
programming examples.
Appendix B Includes two programming examples that use static SQL operations.
Appendix C Includes two programming examples that use dynamic SQL operations.
Appendix D Describes version issues for NonStop SQL release C10 and release C30
software.
Appendix E Describes how to use constraints and to check for referential integrity.

HP NonStop SQL Programming Manual for TAL—527887-001


xi
About This Manual Related Manuals

Related Manuals
You will probably want to use other books from the SQL/MP library set, shown in
Figure i, in conjunction with this reference manual. The complete library includes:
The SQL/MP Reference Manual describes the SQL/MP language elements,
expressions, predicates, functions, and SQL statements that can be run in SQLCI. The
manual also describes SQLCI commands and utilities.

Optional NonStop SQL/MP Library Manuals


• Introduction to SQL/MP provides an overview of the SQL/MP relational database
management system.
• The SQL/MP Messages Manual describes NonStop SQL messages.
• The SQL/MP Installation and Management Guide explains how to plan, install,
create, and manage a SQL database.
• The SQL/MP Programming Manual for C and SQL/MP Programming Manual for
COBOL85 describe the SQL/MP programmatic interfaces for C and COBOL85,
respectively. The SQL/MP Programming Manual for Pascal and SQL/MP
Programming Manual for TAL are the equivalent manuals for Pascal and TAL.

Program Development Manuals


• The TAL Reference Manual describes TAL.
• The Inspect Manual describes the Inspect program, an interactive source-level or
machine-level debugger that enables you to interrupt and resume program
execution and to display and modify variables.
• The Guardian Programmer’s Guide describes the programmatic interface between
user programs and the operating system.
• The Binder Manual describes the Binder program, an interactive linker that enables
you to examine, modify, and combine object files and to generate load maps and
cross-reference listings.
If plan to run your object file on a TNS/R system and you use the Accelerator to
optimize the object code, see the Accelerator Manual.

HP NonStop SQL Programming Manual for TAL—527887-001


xii
About This Manual Related Manuals

Figure i. Related Manuals

Related Manuals

SQL
Introduction Programming SQL/MP
to SQL/MP Manual for Reference
TAL Manual
Prerequisite Companion
Manual Manual

Program Development Manuals Optional NonStop SQL Manuals

SQL /MP
TAL Inspect SQL /MP Installation
Reference Manual Messages and
Manual Manual Management
Guide

Guardian' SQL/MP
Binder SQL/MP
Programmer's Version
Manual Management Reference
Guide Summary
Guide

Other NonStop SQL Programming Manuals

SQL/MP SQL/MP
SQL/MP Programming Programming
Programming Manual for Manual for
Manual for C COBOL85 Pascal

VSTAB01.vsd

HP NonStop SQL Programming Manual for TAL—527887-001


xiii
About This Manual Notation Conventions

Notation Conventions
The list summarizes the conventions used for syntax and programming examples in
this manual.

Notation Meaning
UPPERCASE LETTERS Uppercase letters represent keywords and reserved words;
enter these items exactly as shown.
Uppercase letters in text also represent variable names that
are used in programming examples.
lowercase italic letters Lowercase letters in italics represent information you supply.
Brackets [ ] Brackets enclose optional syntax items. A group of vertically
aligned items enclosed in brackets represents a list of
selections from which you can choose one or none.
Braces { } Braces enclose required syntax items. A group of vertically
aligned items enclosed in braces represents a list of
selections from which you must choose one.
Vertical line | A vertical line separates alternative syntax items in a
horizontal list. Such a list, enclosed in either brackets or
braces, is an alternative to a vertical list for presenting
selections.
Ellipsis ... An ellipsis immediately following a pair of brackets or braces
indicates that you can repeat the enclosed syntax items any
number of times.
An ellipsis in a programming example indicates that one or
more lines of source code have been omitted.
Spaces If a space separates two items, that space is required. If one
of the items is a punctuation symbol, such as a parenthesis
or a comma, spaces are optional.
i and o In the syntax for SQL system procedure calls, i and o are
used as follows:
i Input parameters (parameters that pass data to
the called procedure)
o Output parameters (parameters that return data
to the calling program)
i:o Input and output parameters (parameters that
both pass and return data)
Punctuation Parentheses, commas, semicolons, and other symbols not
described above must be entered precisely as shown.

HP NonStop SQL Programming Manual for TAL—527887-001


xiv
About This Manual Hypertext Links

Hypertext Links
Blue underline is used to indicate a hypertext link within text. By clicking a passage of
text with a blue underline, you are taken to the location described. For example:
This requirement is described under Backup DAM Volumes and Physical Disk
Drives on page 3-2.

General Syntax Notation


This list summarizes the notation conventions for syntax presentation in this manual.

UPPERCASE LETTERS. Uppercase letters indicate keywords and reserved words. Type
these items exactly as shown. Items not enclosed in brackets are required. For
example:
MAXATTACH

lowercase italic letters. Lowercase italic letters indicate variable items that you supply.
Items not enclosed in brackets are required. For example:
file-name

computer type. Computer type letters within text indicate C and Open System Services
(OSS) keywords and reserved words. Type these items exactly as shown. Items not
enclosed in brackets are required. For example:
myfile.c
italic computer type. Italic computer type letters within text indicate C and Open
System Services (OSS) variable items that you supply. Items not enclosed in brackets
are required. For example:
pathname

[ ] Brackets. Brackets enclose optional syntax items. For example:


TERM [\system-name.]$terminal-name
INT[ERRUPTS]
A group of items enclosed in brackets is a list from which you can choose one item or
none. The items in the list can be arranged either vertically, with aligned brackets on
each side of the list, or horizontally, enclosed in a pair of brackets and separated by
vertical lines. For example:
FC [ num ]
[ -num ]
[ text ]
K [ X | D ] address
{ } Braces. A group of items enclosed in braces is a list from which you are required to
choose one item. The items in the list can be arranged either vertically, with aligned

HP NonStop SQL Programming Manual for TAL—527887-001


xv
About This Manual General Syntax Notation

braces on each side of the list, or horizontally, enclosed in a pair of braces and
separated by vertical lines. For example:
LISTOPENS PROCESS { $appl-mgr-name }
{ $process-name }
ALLOWSU { ON | OFF }

| Vertical Line. A vertical line separates alternatives in a horizontal list that is enclosed in
brackets or braces. For example:
INSPECT { OFF | ON | SAVEABEND }

… Ellipsis. An ellipsis immediately following a pair of brackets or braces indicates that you
can repeat the enclosed sequence of syntax items any number of times. For example:
M address [ , new-value ]…
[ - ] {0|1|2|3|4|5|6|7|8|9}…
An ellipsis immediately following a single syntax item indicates that you can repeat that
syntax item any number of times. For example:
"s-char…"

Punctuation. Parentheses, commas, semicolons, and other symbols not previously


described must be typed as shown. For example:
error := NEXTFILENAME ( file-name ) ;
LISTOPENS SU $process-name.#su-name
Quotation marks around a symbol such as a bracket or brace indicate the symbol is a
required character that you must type as shown. For example:
"[" repetition-constant-list "]"

Item Spacing. Spaces shown between items are required unless one of the items is a
punctuation symbol such as a parenthesis or a comma. For example:
CALL STEPMOM ( process-id ) ;
If there is no space between two items, spaces are not permitted. In this example, no
spaces are permitted between the period and any other items:
$process-name.#su-name

Line Spacing. If the syntax of a command is too long to fit on a single line, each
continuation line is indented three spaces and is separated from the preceding line by
a blank line. This spacing distinguishes items in a continuation line from items in a
vertical list of selections. For example:
ALTER [ / OUT file-spec / ] LINE

[ , attribute-spec ]…

HP NonStop SQL Programming Manual for TAL—527887-001


xvi
About This Manual Notation for Messages

!i and !o. In procedure calls, the !i notation follows an input parameter (one that passes data
to the called procedure); the !o notation follows an output parameter (one that returns
data to the calling program). For example:
CALL CHECKRESIZESEGMENT ( segment-id !i
, error ) ; !o

!i,o. In procedure calls, the !i,o notation follows an input/output parameter (one that both
passes data to the called procedure and returns data to the calling program). For
example:
error := COMPRESSEDIT ( filenum ) ; !i,o

!i:i. In procedure calls, the !i:i notation follows an input string parameter that has a
corresponding parameter specifying the length of the string in bytes. For example:
error := FILENAME_COMPARE_ ( filename1:length !i:i
, filename2:length ) ; !i:i

!o:i. In procedure calls, the !o:i notation follows an output buffer parameter that has a
corresponding input parameter specifying the maximum length of the output buffer in
bytes. For example:
error := FILE_GETINFO_ ( filenum !i
, [ filename:maxlen ] ) ; !o:i

Notation for Messages


This list summarizes the notation conventions for the presentation of displayed
messages in this manual.

Bold Text. Bold text in an example indicates user input typed at the terminal. For example:
ENTER RUN CODE
?123
CODE RECEIVED: 123.00
The user must press the Return key after typing the input.

Nonitalic text. Nonitalic letters, numbers, and punctuation indicate text that is displayed or
returned exactly as shown. For example:
Backup Up.

lowercase italic letters. Lowercase italic letters indicate variable items whose values are
displayed or returned. For example:
p-register
process-name

HP NonStop SQL Programming Manual for TAL—527887-001


xvii
About This Manual Notation for Management Programming Interfaces

[ ] Brackets. Brackets enclose items that are sometimes, but not always, displayed. For
example:
Event number = number [ Subject = first-subject-value ]
A group of items enclosed in brackets is a list of all possible items that can be
displayed, of which one or none might actually be displayed. The items in the list can
be arranged either vertically, with aligned brackets on each side of the list, or
horizontally, enclosed in a pair of brackets and separated by vertical lines. For
example:
proc-name trapped [ in SQL | in SQL file system ]

{ } Braces. A group of items enclosed in braces is a list of all possible items that can be
displayed, of which one is actually displayed. The items in the list can be arranged
either vertically, with aligned braces on each side of the list, or horizontally, enclosed in
a pair of braces and separated by vertical lines. For example:
obj-type obj-name state changed to state, caused by
{ Object | Operator | Service }
process-name State changed from old-objstate to objstate
{ Operator Request. }
{ Unknown. }

| Vertical Line. A vertical line separates alternatives in a horizontal list that is enclosed in
brackets or braces. For example:
Transfer status: { OK | Failed }

% Percent Sign. A percent sign precedes a number that is not in decimal notation. The
% notation precedes an octal number. The %B notation precedes a binary number.
The %H notation precedes a hexadecimal number. For example:
%005400
%B101111
%H2F
P=%p-register E=%e-register

Notation for Management Programming Interfaces


This list summarizes the notation conventions used in the boxed descriptions of
programmatic commands, event messages, and error lists in this manual.

UPPERCASE LETTERS. Uppercase letters indicate names from definition files. Type these
names exactly as shown. For example:
ZCOM-TKN-SUBJ-SERV

HP NonStop SQL Programming Manual for TAL—527887-001


xviii
About This Manual Change Bar Notation

lowercase letters. Words in lowercase letters are words that are part of the notation,
including Data Definition Language (DDL) keywords. For example:
token-type

!r. The !r notation following a token or field name indicates that the token or field is
required. For example:
ZCOM-TKN-OBJNAME token-type ZSPI-TYP-STRING. !r

!o. The !o notation following a token or field name indicates that the token or field is
optional. For example:
ZSPI-TKN-MANAGER token-type ZSPI-TYP-FNAME32. !o

Change Bar Notation


Change bars are used to indicate substantive differences between this edition of the
manual and the preceding edition. Change bars are vertical rules placed in the right
margin of changed portions of text, figures, tables, examples, and so on. Change bars
highlight new or revised information. For example:
The message types specified in the REPORT clause are different in the COBOL85
environment and the Common Run-Time Environment (CRE).
The CRE has many new message types and some new message type codes for
old message types. In the CRE, the message type SYSTEM includes all messages
except LOGICAL-CLOSE and LOGICAL-OPEN.

HP NonStop SQL Programming Manual for TAL—527887-001


xix
About This Manual Change Bar Notation

HP NonStop SQL Programming Manual for TAL—527887-001


xx
1 Introduction
The NonStop SQL relational database management system (RDBMS) uses the
structured query language (SQL) to define and manipulate data in a NonStop SQL
database. Because NonStop SQL is integrated with other HP NonStop software
products, you can execute SQL statements interactively or programmatically.
Using the SQL conversational interface (SQLCI), you can enter SQL statements and
directives interactively from a terminal or an OBEY command file. NonStop SQL
compiles and executes the statement immediately and then issues a response at your
terminal. Using SQLCI, you can also test programmatic SQL statements before you
embed and compile them in a program.
Using the programmatic interface, you can embed SQL statements and directives in a
C, COBOL85, Pascal, or TAL program. You compile the host language statements
using the host language compiler and the embedded SQL statements using the SQL
compiler. The SQL statements execute when the object file runs.
NonStop SQL also provides system library procedures you can call from a program to
perform various SQL functions (for example, to get error and statistics information after
executing an SQL statement).
This manual describes the TAL programmatic interface to NonStop SQL. It shows you
how to embed SQL statements and directives in a TAL program and how to call the
SQL system library procedures from a TAL program.

Why Use Embedded SQL Statements?


Using embedded SQL statements in a TAL program to access a NonStop SQL
database has these advantages:
• High-level language for accessing a database. Using SQL statements, you code a
request to access a database, and NonStop SQL determines the most efficient
method to perform the request.
• Insulation against database changes. If a database administrator modifies a
database (for example, adds columns to a table), the logic of your program is not
affected.
• Use of TAL for processing data. You can use SQL statements to retrieve data from
a database or insert data into a database, and you can use TAL statements to
process and manipulate the data.
• System support for data consistency. When you use audited tables and views, the
system maintains data consistency with the locking facility and the HP NonStop
Transaction Manangement Facility (TMF).

HP NonStop SQL Programming Manual for TAL—527887-001


1-1
Introduction Developing a Program

Developing a Program
A TAL program that contains embedded SQL statements can use both static and
dynamic SQL operations. A static SQL operation processes SQL statements that you
embed and compile in the TAL source code. A dynamic SQL operation enables a
program to construct, compile, and execute an SQL statement at run time.

Embedding SQL Statements


You embed SQL statements by preceding each SQL statement with the keywords
EXEC SQL and terminating the statement with either a semicolon (;) or an END, ELSE,
or UNTIL keyword if it is appropriate for the statement. This example shows a TAL
source file that contains embedded SQL statements.
! TAL source file
...
EXEC SQL BEGIN DECLARE SECTION;
... ; ! SQL host variable declarations
EXEC SQL END DECLARE SECTION;
...
! TAL procedure
...
EXEC SQL ... ; ! SQL statement
...
Table 1-1 shows the NonStop SQL statements you can embed in a TAL program.

Table 1-1. NonStop SQL Statements


Type Statement
Data Control Language (DCL) FREE RESOURCES, LOCK TABLE, UNLOCK
TABLE
Data Definition Language (DDL) ALTER, COMMENT, CREATE, DROP, HELP TEXT,
UPDATE STATISTICS
Data Manipulation Language (DML) CLOSE, DECLARE CURSOR, DELETE, FETCH,
INSERT, OPEN, SELECT, UPDATE
Dynamic SQL DECLARE CURSOR, DESCRIBE, DESCRIBE
INPUT, EXECUTE, EXECUTE IMMEDIATE,
PREPARE, RELEASE
Transaction Control BEGIN WORK, COMMIT WORK, ROLLBACK
WORK

HP NonStop SQL Programming Manual for TAL—527887-001


1-2
Introduction Declaring Host Variables

Table 1-2 shows the NonStop SQL directives you can embed in a TAL program.

Table 1-2. NonStop SQL Directives


Type Directive
Data Declaration BEGIN DECLARE SECTION, END DECLARE SECTION, INCLUDE
SQLCA, INCLUDE SQLDA, INCLUDE SQLSA
Data Control CONTROL EXECUTOR, CONTROL QUERY, CONTROL TABLE
Error Checking WHENEVER

For more information, see Section 3, NonStop SQL Statements and Directives

Declaring Host Variables


A host variable provides communication between TAL statements and SQL statements
in a program. A host variable is a TAL variable with a data type that corresponds to an
SQL data type. You use host variables in SQL statements to receive data from a
database and to insert data into a database. When you use a host variable with an
SQL statement, you precede the host variable name with a colon (:).
You declare host variables in a Declare Section with the TAL variable declarations. A
Declare Section begins with the BEGIN DECLARE SECTION directive and ends with
the END DECLARE SECTION directive. In this example, FILE^NUMBER and
MESSAGE are host variables.
! TAL declarations
...
EXEC SQL BEGIN DECLARE SECTION;
INT file^number; ! SQL host variables
STRING .message[80] ;
EXEC SQL END DECLARE SECTION;
...
! More TAL declarations
...
For more information, see Section 2, Host Variables and Parameters.

Calling SQL System Procedures


Use the provided TAL system library procedures to perform various SQL operations
and functions. For example, the SQLCADISPLAY procedure returns error and statistics
information after an SQL statement executes.
A TAL program can call SQL system procedures in the same manner that it might call
other system procedures such as OPEN, READ, WRITEREAD, and CLOSE. The
$SYSTEM.SYSTEM.EXTDECS file contains source declarations of these procedures

HP NonStop SQL Programming Manual for TAL—527887-001


1-3
Introduction Using Static SQL Statements

that you can include in your program. This example shows a call to the
SQLCADISPLAY procedure using all default parameters.
?SOURCE $SYSTEM.SYSTEM.EXTDECS (SQLCADISPLAY)
...
CALL SQLCADISPLAY (SQLCA);
! Process errors or statistics from the SQLCA structure
...
For more information, see Section 4, System Procedures.

Using Static SQL Statements


You can embed static SQL statements in both TAL data declarations and TAL
executable statements. Figure 1-1 on page 1-5 shows an example of static SQL
statements embedded in a TAL program. In this example, the program inserts a row in
the PARTS table, which has the columns PARTNUM, PRICE, and PARTDESC. This
example also declares data items as host variables so that they can contain input
values for the columns of the row.

HP NonStop SQL Programming Manual for TAL—527887-001


1-4
Introduction Using Dynamic SQL Operations

Figure 1-1. Static SQL Statements in a TAL Program

! TAL variable declarations:


EXEC SQL BEGIN DECLARE SECTION;
! SQL host variable declarations

STRUCT .in^parts^rec;
BEGIN
INT in^partnum;
FIXED(2) in^price;
STRING in^partdesc[0:17];
END;
EXEC SQL END DECLARE SECTION;
...
! Procedure Code:
in^parts^rec.in^partnum := 4120;
in^parts^rec.in^price := 60000.00F;

! Blank fill in^partdesc:


in^parts^rec.in^partdesc ':='
[ $OCCURS(in^parts^rec.in^partdesc) * [" "] ];

in^parts^rec.in^partdesc ':=' "V8 DISK OPTION";

EXEC SQL INSERT INTO SALES.PARTS


( PARTNUM, PRICE, PARTDESC)
VALUES (:in^parts^rec.in^partnum,
:in^parts^rec.in^price,
:in^parts^rec.in^partdesc);

VST0101.vsd
...

For other examples of static SQL programming, see Section B, Examples of Static
NonStop SQL Programs.

Using Dynamic SQL Operations


A dynamic SQL operation enables a TAL program to construct, compile, and execute
an SQL statement at run time. With a static SQL operation, you code the SQL
statement to be executed in the source file; however, with a dynamic SQL operation,
you code only the host variable that will contain the SQL statement.
A dynamic SQL operation requires some input, usually from a user at a terminal, to
construct the final statement. The SQL statement is constructed from the user’s input,
compiled by the SQL compiler, and then executed using an EXECUTE or EXECUTE
IMMEDIATE statement.

HP NonStop SQL Programming Manual for TAL—527887-001


1-5
Introduction Using Dynamic SQL Operations

Figure 1-2 shows a dynamic SQL operation that uses an INSERT statement similar to
the static INSERT statement in Figure 1-1 on page 1-5. In Figure 1-1 on page 1-5, the
static INSERT statement is embedded in the source program code; however, in
Figure 1-2, the program dynamically builds the INSERT statement from information
entered by a user.
The program in Figure 1-2 accesses the PARTS table, which has the same file name,
but resides on a different subvolume. When this program runs, it prompts a user for
information to build the INSERT statement. The user enters this information in the
INTEXT variable to specify the specific PARTS table and other values needed to
construct the INSERT statement:
INSERT INTO $vol5.sales.parts
partnum, price, partdesc)
VALUES (4120, 60000.00, "V8 DISK OPTION")
The program builds the INSERT statement from the information in INTEXT and moves
the statement to the host variable OPERATION. The program has declared
OPERATION as a host variable, so that it is available to both TAL and SQL statements.
The program then uses the EXECUTE IMMEDIATE to execute the INSERT statement
in OPERATION.

Figure 1-2. Dynamic SQL Statements in a TAL Program

! TAL data declarations

EXEC SQL BEGIN DECLARE SECTION;


STRING operation[0:199]; ! Host variable

EXEC SQL END DECLARE SECTION;

! TAL procedure

! Copy intext into :operation host variable


...
! Execute the SQL statement:
EXEC SQL EXECUTE IMMEDIATE :operation;
... VST0102.vsd

For more information, see Section 7, Dynamic NonStop SQL Operations and
Section C, Examples of Dynamic NonStop SQL Programs.

HP NonStop SQL Programming Manual for TAL—527887-001


1-6
Introduction Compiling and Executing a Program

Compiling and Executing a Program


Compiling and executing a TAL program that contains embedded SQL statements is
similar to the steps you use for a TAL program that does not contain embedded SQL
statements. You must perform only one extra step: you compile the SQL statements
using the SQL compiler. These steps are shown in Figure 1-3.
1. Compile your source file (or files) using the TAL compiler. The TAL compiler
generates an object file for each compilation. Each object file contains TAL object
code and SQL source statements.
2. Use the Binder program, if necessary, to combine multiple object files into one
object file or to specify the TALLIB run-time library if you did not include it during
the TAL compilation in Step 1.
3. Optionally, run the Accelerator on the object file generated from Step 1 or 2 if you
plan to run the object file on a TNS/R system.
4. Compile the SQL statements in the TAL object file using the SQL compiler.
5. Run the object file from a terminal using the TACL RUN (or RUND) command or
from a process using a system procedure such as NEWPROCESS.

HP NonStop SQL Programming Manual for TAL—527887-001


1-7
Introduction Compiling and Executing a Program

Figure 1-3. Compiling and Executing a Program

TAL/SQL

Source
File (s)

1 Run the TAL compiler for each TAL Compiler


source file

Binder Process
2 Run the Binder program
(if necessary)

Run the Accelerator (optional step for Accelerator


3 TNS/R systems only)

TAL/SQL
SQL Compiler
4 Run the SQL compiler Object
File
5 Run the object file
VST0103.vsd

For more information, see Section 5, Program Compilation and Execution.

HP NonStop SQL Programming Manual for TAL—527887-001


1-8
2 Host Variables and Parameters
This section describes the data items that you use to provide for communication
between TAL and SQL statements in a TAL program.

Host Variables
A host variable is a data item you can use in both TAL and SQL statements to provide
for communication between the two types of statements.
For static SQL operations, a host variable can be an input or output variable (or both in
some cases) in SQL statements. An input variable transfers data from the program to
the database, while an output variable transfers data from the database to the
program. (For dynamic SQL operations, input parameters and output variables fulfill
the same function as input and output host variables in static SQL statements.)
A host variable can be a:
Simple variable
Whole STRING array (SQL type DECIMAL or CHAR)
Element in an array
Indirect array or structure (including standard and extended indirection)
Structure that conforms to SQL data type VARCHAR
Field in a structure
SQLDA structure
However, a host variable cannot be a:
Constant
TAL DEFINE identifier
Variable of TAL data type UNSIGNED
Pointer
TAL array of type other than STRING
Structure except VARCHAR and SQLDA structures
A host variable can be any TAL data item that has a corresponding SQL data type as
shown in Table 2-1 on page 2-3. NonStop SQL must be able to convert the data
between the two data types. If your program returns a TAL assignment expression to a
host variable, the TAL compiler must be able to convert the value of the expression to
the data type of the host variable.

HP NonStop SQL Programming Manual for TAL—527887-001


2-1
Host Variables and Parameters Declaring Host Variables

Declaring Host Variables


You declare host variables in a Declare Section in the variable declarations of your
program. You can use multiple Declare Sections in a TAL program, but you cannot nest
the sections. The SQL directives that delimit a Declare Section are BEGIN DECLARE
SECTION and END DECLARE SECTION.
Use TAL naming conventions for your host variables. Host variable names (and
indicator variable names):
• Can contain from 1 to 31 alphanumeric characters including the circumflex (^) and
the underscore (_)
• Must begin with a letter, circumflex, or underscore
To prevent naming conflicts, avoid ending your names with an underscore.
Examples of host variable declarations are:
EXEC SQL BEGIN DECLARE SECTION;
! host variables
STRING .buffer[0:length];
INT number[0:9];
STRUCT .s^buffer;
BEGIN
INT buffer_length;
STRING text[0:2046];
END;
EXEC SQL END DECLARE SECTION;
For information about using the INVOKE directive to create host variables, see
Section 3, NonStop SQL Statements and Directives

Using Corresponding SQL and TAL Data Types


Table 2-1 on page 2-3 shows the corresponding NonStop SQL and TAL data types. If
you have an SQL data type shown in the left column and you want to send data to a
variable with that data type or receive data from a variable with that data type, declare
a TAL host variable as shown in the right column.

HP NonStop SQL Programming Manual for TAL—527887-001


2-2
Host Variables and Parameters Using Corresponding SQL and TAL Data Types

Table 2-1. Corresponding NonStop SQL and TAL Data Types


SQL Data Type TAL Data Type
Character Data
CHAR(n), PIC X(n) STRING [0: n - 1]
VARCHAR(n) STRUCT identifier;
BEGIN
INT length;
STRING value[0: n-1];
END;
Numeric Data
NUMERIC (1 to 4, s) SIGNED INT
NUMERIC (1 to 4, s) UNSIGNED INT / SMALLINT UNSIGNED / 1
NUMERIC (5 to 9, s) SIGNED INT(32)
NUMERIC (5 to 9, s) UNSIGNED INT(32) / INTEGER UNSIGNED/ 1
NUMERIC (10 to 18, s) SIGNED FIXED(s)
PIC [s]9(n- s)V9(s) [COMP] Same as TAL data types for NUMERIC
DECIMAL(n, s) STRING[0: n-1] / DECIMAL / 1
DECIMAL(n, s) UNSIGNED STRING[0: n-1] /DECIMAL UNSIGNED/ 1
PIC[s] 9(n- s)V9(s)
SMALLINT INT
SMALLINT UNSIGNED INT / SMALLINT UNSIGNED / 1
INTEGER INT(32)
INTEGER UNSIGNED INT(32) / INTEGER UNSIGNED / 1
LARGEINT SIGNED FIXED(0)
FLOAT (1 to 22), REAL REAL
Date-Time Data
DATETIME, TIMESTAMP, DATE, TIME STRING [0: n-1]
INTERVAL Data
INTERVAL STRING[0: n] 2
n is a positive integer that represents the length. For DECIMAL, n must range from 1 through 18.
s is a positive integer that represents the scale of the number.
1 SQL data types between slashes specify override data type mapping (on page 2-4).
2 A host variable for an INTERVAL value has an extra byte to hold a sign.

HP NonStop SQL Programming Manual for TAL—527887-001


2-3
Host Variables and Parameters Using Corresponding SQL and TAL Data Types

Data Conversion
NonStop SQL performs the conversion from SQL data types to TAL data types and
from TAL data types to SQL data types as follows:
• When a host variable serves as an input variable (supplies a value to the
database), the system first converts the value that the variable contains to a
compatible SQL data type and then uses the value in the SQL operation.
• When a host variable serves as an output variable (receives a value from a
database), the system converts the value to the data type of the host variable.
NonStop SQL supports conversion within character types and numeric types, but it
does not support conversion between character and numeric types. The SQL date-time
and INTERVAL types are compatible only with TAL STRING types (and the STRING
host variable used to store the date-time or INTERVAL value must have a TYPE AS
clause). For more information, see Using Date-Time and INTERVAL Data Types as
Host Variables on page 2-15.
For conversion between character strings of different lengths, NonStop SQL pads the
receiving string on the right with blanks as necessary. If the receiving string is too
short, NonStop SQL truncates the right part of the longer string and returns a warning
code in the SQLCODE variable.
If an input value is too large for an SQL column, NonStop SQL returns error 8300 (file-
system error encountered). If you are using the SQLCADISPLAY procedure to obtain
an error message, SQLCADISPLAY also returns file-system error number 1031.
For conversion between numeric types, NonStop SQL converts data between signed
and unsigned types and between types with different precisions. You can use the
SETSCALE function to communicate a number’s scale to and from a database.
Examples of host variable declarations using the default data types are:
EXEC SQL BEGIN DECLARE SECTION;
! SQL recognizes address as a SMALLINT host variable
INT address;
! SQL recognizes name as a CHAR(20) host variable
STRING .name[0:19];
!SQL recognizes message as a VARCHAR(200) host variable
STRUCT .message;
BEGIN
INT msg^length;
STRING text[0:199];
END;
EXEC SQL END DECLARE SECTION;

HP NonStop SQL Programming Manual for TAL—527887-001


2-4
Host Variables and Parameters Overriding Default Data Types

Overriding Default Data Types


Each TAL data type has a default SQL data type used by the SQL compiler. In most
cases, you can define your host variables to match the SQL data types shown in
Table 2-1 on page 2-3. Sometimes, however, you might want to use another data type.
Some TAL data types allow you to override the default type by specifying an override
SQL data type as an attribute of the host variable. The syntax to override a data type
is:

TAL-type hostvar-name [array-bounds] [/ override-SQL-type/]

TAL-type
is the TAL data type plus any indirection symbol. For example:
INT
INT(32)
INT .
INT .EXT

hostvar-name
is the name of the host variable.

array-bounds
is the bounds of an array. For example, in the declaration:
INT numbers[0:19];
[0:19] is the bounds.

override-SQL-type
is the SQL data type that will override the default type that NonStop SQL normally
uses for TAL-type. Specify override-SQL-type after the host variable and any array
bounds but before initialization or address equivalence takes place.
Also, when you use a host variable in an SQL statement, you can override character
data types by using the:
• TYPE AS clause to specify that the character string should be interpreted as a
date-time value. The TYPE AS clause is described under Using Date-Time and
INTERVAL Data Types as Host Variables on page 2-15.
• SETSCALE function to indicate that an integer host variable is to be interpreted as
having scale. SETSCALE is described under Using Scaled Numeric Data Items as
Host Variables on page 2-12.
Table 2-2 shows how NonStop SQL interprets TAL data types, and the override data
types you can specify.

HP NonStop SQL Programming Manual for TAL—527887-001


2-5
Host Variables and Parameters Using Host Variables

Table 2-2. Default and Override Data Type Mapping


TAL Data Type Default SQL Data Type Override SQL Data Type
STRING CHAR(1) / DECIMAL(1) /
/ DECIMAL(1) UNSIGNED /
STRING[0: n-1] CHAR(n) / DECIMAL(n) / *
/ DECIMAL(n) UNSIGNED / *
INT SMALLINT / SMALLINT UNSIGNED /
INT(32) INTEGER / INTEGER UNSIGNED /
FIXED(0) LARGEINT -
FIXED(s) LARGEINT(s) ** -
REAL REAL -
REAL(64) DOUBLE PRECISION -
STRUCT SQLDA -
VARCHAR(n) ***
n is a positive integer that represents the length.
s is a positive integer that represents the scale of the number.
* For DECIMAL types, n must be in the range 1 through 18.
** LARGEINT(s) type is used internally to SQL, but it is not an SQL type.
*** The default is the SQLDA unless the structure conforms to type VARCHAR (see Table 2-1 on page 2-3).

Examples of overriding default data type mapping are:


EXEC SQL BEGIN DECLARE SECTION;
! SQL recognizes empid as a DECIMAL(10) host variable
STRING .empid[0:9]/DECIMAL(10)/;
! SQL recognizes partnum as a SMALLINT UNSIGNED host variable
INT partnum /SMALLINT UNSIGNED/;
! SQL recognizes size as an INTEGER UNSIGNED host variable
INT(32) size /INTEGER UNSIGNED/;
EXEC SQL END DECLARE SECTION;

Using Host Variables


After you declare a host variable, you can use the variable in an SQL statement just as
you would in a TAL statement, except that you must precede the host variable name
with a colon(:). The colon causes the TAL compiler to treat the name as a host

HP NonStop SQL Programming Manual for TAL—527887-001


2-6
Host Variables and Parameters Using Host Variables

variable. The syntax for using a host variable in an SQL statement is shown below.
For a complete description of this syntax, see the SQL/MP Reference Manual.

:host-identifier[[ INDICATOR ]: indicator-host-identifier ]

[ TYPE AS {DATETIME [start-date-time TO] end-date-time } ]


[ { } ]
[ {DATE } ]
[ { } ]
[ {TIME } ]
[ { } ]
[ {TIMESTAMP } ]
[ { } ]
[ {INTERVAL start-date-time } ]
[ { [ ( start-field-precision ) ] } ]
[ { [ TO end-date-time ] } ]

:host-identifier
is a TAL data item. Use :host-identifier in DML statements where a literal can be
used (except in the INVOKE and INCLUDE directives).

INDICATOR
is a keyword that allows for:
• Handling null values that might be returned to the host variable
• Inserting null values into the database through the host variable

:indicator-host-identifier
is an indicator variable with type INT. For values returned to a host variable,
: indicator-host-identifier is:
-1 if the value is null
0 if the value is not null
To insert t null values into the database, set : indicator-host-identifier to a value less
than zero.

TYPE AS
directs NonStop SQL to treat the variable as a date-time (DATETIME, DATE, TIME,
or TIMESTAMP) or INTERVAL value. To direct NonStop SQL to treat the host
variable as a scaled value, either define the variable as TAL data type FIXED or
use the SETSCALE function, which is described under Using Scaled Numeric Data
Items as Host Variables on page 2-12.

HP NonStop SQL Programming Manual for TAL—527887-001


2-7
Host Variables and Parameters Using Host Variables

Using Structures as Host Variables


Follow the guidelines below when you declare and use structures or fields within
structures as host variables.
INVOKE Directive. Use the INVOKE directive to declare structure descriptions
corresponding to SQL tables and views. The structure fields (which correspond to the
columns in the table or view) become host variables. For information about using the
INVOKE directive to create host variables, see Creating Host Variables With the
INVOKE Directive on page 2-20.
VARCHAR Type. Declare host variables that correspond to the SQL VARCHAR type
as TAL structures. See Table 2-1 on page 2-3 for an example of the TAL structure. For
these structures, you can refer to both the TAL structure name and the individual fields;
however, only the structure name is recognized as a host variable of SQL type
VARCHAR.
Structure Name References. You can refer to a structure name as a host variable
only if the structure:
• Represents an item of SQL type VARCHAR
• Is an SQLDA
• Has an array of type STRING as its only field
For other TAL structures, you can refer to only the individual fields in the structure as
host variables, but you cannot refer to the structure name. Except for the above cases,
you must use the structure name with the field name to reference a host variable that is
a field within a structure. For example, the structure named EMPLOYEE^INFO
contains the EMPID, EMPNAME, and SALARY host variables.
EXEC SQL BEGIN DECLARE SECTION;
STRUCT .employee^info;
BEGIN
STRING empid[0:9];
STRING empname[0:19];
FIXED(2) salary;
END;
EXEC SQL END DECLARE SECTION;
When you use these host variables in an SQL statement, refer to them by the structure
and field names. For example:
EXEC SQL SELECT empid, empname, salary
INTO :employee^info.empid, :employee^info.empname,
:employee^info.salary
FROM =employee
WHERE empid = 12345;

HP NonStop SQL Programming Manual for TAL—527887-001


2-8
Host Variables and Parameters Using Host Variables

Structure Pointers. Although you cannot use a pointer by itself as a host


variable, you can refer to a field in a structure by using a structure pointer. For
example, you can use this host variable declaration and reference:
! Declaration:
EXEC SQL BEGIN DECLARE SECTION;
STRUCT s^template(*);
BEGIN
INT field1; ! Fields cannot be pointers in SQL
INT field2;
END;
STRING .EXT s^ptr (s^template); ! Structure pointer
EXEC SQL END DECLARE SECTION;
! Reference:

EXEC SQL SELECT col1 INTO :s^ptr.field1 FROM tbl1;


You can also use a structure as a host variable by:
• Using array indexing within the structure
• Allowing a field in the structure to be a substructure or an array
These examples show TAL structures that you can use as host variables:
! Substructures and array within a structure:
STRUCT .outer^struct; ! Structure
BEGIN
INT int^array[0:4]; ! Array
STRUCT sub^struct^1; ! Substructure
BEGIN
STRUCT sub^struct^2; ! Substructure
BEGIN
INT int^1;
INT int^2;
END;
END;
END;
! A three-dimensional structure of VARCHAR items:
STRUCT .first^dim[0:3];
BEGIN;
STRUCT second^dim[0:3];
BEGIN
STRUCT third^dim[0:3];
BEGIN
INT len;
STRING name[0:19];
END;
END;
END;

HP NonStop SQL Programming Manual for TAL—527887-001


2-9
Host Variables and Parameters Using Host Variables

! Reference to an integer within an array


! of integers in a structure:
EXEC SQL SELECT integer^value INTO
:outer^struct.int^array[1]
FROM table1;
! A reference to an integer within nested structures:
EXEC SQL SELECT integer^value INTO
:outer^struct.nested^struct^1.nested^struct^2.int^1
FROM table1;
! A reference to a VARCHAR item:
EXEC SQL SELECT character^string INTO
:first^dim.second^dim.third^dim
FROM table1;
In this example, after the VARCHAR item is accessed, NonStop SQL sets:
• FIRST^DIM.SECOND^DIM.THIRD.DIM.NAME to CHARACTER^STRING
• FIRST^DIM.SECOND^DIM.THIRD.DIM.LEN to the byte length of
CHARACTER^STRING
Structures as Character Host Variables. A value from an SQL column of SQL data
type CHAR can be stored into a host variable that is a structure containing a single
array of TAL type STRING. Reference the structure either directly through the structure
name, or indirectly through a structure pointer.
In this example, PEOPLE is an SQL table that contains the 10-character column
EMPNAME. You can use the names DIRECT^STRUCT, INDIRECT^STRUCT, and
STRUCT^POINTER as host variables to store EMPNAME.
! Host variable declarations:
EXEC SQL BEGIN DECLARE SECTION;
STRUCT direct^struct;
BEGIN
STRING name [0:9];
END;
INT .struct^pointer(direct^struct);
STRUCT .indirect^struct;
BEGIN
STRING name [0:9];
END;
EXEC SQL END DECLARE SECTION;
To use the host variable DIRECT^STRUCT, specify:
EXEC SQL
SELECT empname INTO :direct^struct FROM people;
If you make STRUCT^POINTER point to DIRECT^STRUCT, you can also specify:
EXEC SQL
SELECT empname INTO :struct^pointer FROM people;

HP NonStop SQL Programming Manual for TAL—527887-001


2- 10
Host Variables and Parameters Using Host Variables

To use the host variable INDIRECT^STRUCT, specify:


EXEC SQL
SELECT empname INTO :indirect^struct FROM people;
If you make STRUCT^POINTER point to INDIRECT^STRUCT, you can also specify:
EXEC SQL
SELECT empname INTO :struct^pointer FROM people;

Using Arrays as Host Variables


Follow these guidelines when you declare and use arrays as host variables.
The TAL compiler interprets STRING arrays of length [0: size - 1] as one of these SQL
data types:
• CHAR(size)
• DECIMAL(size), if you specified overriding the default data type
• Date-time or INTERVAL, if you used the TYPE AS clause
The size of a STRING array does not have to match the size of the character field in
the VARCHAR column, CHAR column, or the date-time or INTERVAL column.
NonStop SQL pads or truncates the value to fit the host variable. For arrays of a data
type other than STRING, the size of an array element must be compatible with the size
of the SQL column.

Using STRING Parameters as Host Variables


Host variables that are passed as TAL STRING parameters require special
consideration because TAL does not allow you to specify bounds on a parameter
declaration. Use either of these two methods to handle this type of parameter:
• Declare the parameter as a structure.
• Declare an equivalenced local structure.
Declaring the Parameter as a Structure. Declare the STRING parameter as a field in
a structure. In SQL statements, always refer to the parameter as:
structure-name.field-name
However, when you pass the parameter, use the structure name (and not the field
name). For example:
STRUCT .struc;
BEGIN
STRING val [0:maxsize-1];
END;

HP NonStop SQL Programming Manual for TAL—527887-001


2- 11
Host Variables and Parameters Using Host Variables

The declaration for the called procedure is:


PROC process^cmd(struc);
STRUCT .struc;
BEGIN
STRING val [0:maxsize-1];
END;
...
BEGIN
EXEC SQL PREPARE dyn^cmd FROM :struc.val;
...
END;
Declaring an Equivalenced Local Structure. Declare the parameter as a STRING
array. In SQL statements that are within the scope of the STRING array's declaration,
refer to the parameter using the STRING array name.
Before the STRING array is passed to a procedure as a parameter, declare a local
structure template with a STRING array as the only field, declare a pointer to that
structure template, and equivalence the pointer to the STRING array that was passed
as the parameter. In SQL statements local to the procedure, refer to the parameter as:
structure-name. field-name
For example, you might make these declarations and references:
STRING .strng[0:maxsize-1];
...
PROC process^cmd(s);
STRING .strng;
BEGIN
STRUCT strng^equiv(*);
BEGIN;
STRING val[0:maxsize-1];
END;
STRING .new^strng(strng^equiv) = strng;
...
EXEC SQL PREPARE new^cmd FROM :new^strng.val;
END;

Using Scaled Numeric Data Items as Host Variables


Use one of these two methods to declare a host variable with scale:
• Declare the host variable using FIXED(n) data type, where n is the number of
decimal places to the right of the decimal point.
• Declare the host variable with a numeric data type that is compatible with the SQL
column, and then use the SETSCALE function to communicate the scale.

HP NonStop SQL Programming Manual for TAL—527887-001


2- 12
Host Variables and Parameters Using Host Variables

Using the FIXED Data Type. This method is the simplest method to handle scale;
follow these guidelines when you use it:
• The value stored in the FIXED host variable must fit into the database column.
FIXED variables are stored in 64 bits and can hold 19 digits. You must ensure that
the host variable never contains a value greater than will fit in the column;
otherwise, NonStop SQL reports an error.
For example, if the SQL column is defined as type NUMERIC (7,3), ensure that
values in the corresponding host variable of type FIXED(3) are never greater than
9999.999 or smaller than -9999.999.
• If you use FIXED host variables, the SQL executor must use quadrupleword
arithmetic to evaluate expressions.
Using the SETSCALE Function. If you must ensure that a database column size
matches the host variable size (for example, you might be transferring data between a
NonStop SQL database and an Enscribe file), use a TAL numeric data type that
corresponds to the data type of the SQL column. You can use the INVOKE directive
and then use the SETSCALE function to communicate the scale between the TAL and
SQL statements.
If you use the SETSCALE function and your program must also use the host variables
in calculations, include the necessary code to scale the values in the host variables.
The SETSCALE function has this syntax:

SETSCALE (: host-variable

[ [INDICATOR] : indicator-variable ] , scale )

: host-variable
is a numeric host variable.

INDICATOR : indicator-variable
is an indicator variable associated with the host variable. For more information
about using indicator variables to specify or read null values, see Using Date-Time
and INTERVAL Data Types as Host Variables on page 2-15.

scale
is an integer that designates the scale of :host-variable. The values allowed for
scale depend on the size of :host-variable as follows:
Size TAL Type Values Allowed
2-byte integer INT 0 through 5 decimal digits
4-byte integer INT (32) 0 through 10 decimal digits
8-byte integer FIXED 0 through 18 decimal digits

HP NonStop SQL Programming Manual for TAL—527887-001


2- 13
Host Variables and Parameters Using Host Variables

The SETSCALE function causes NonStop SQL to use :host-variable in the context of
SQL statements as if :host-variable were declared with a scale of scale. For example,
the sequence SETSCALE (hostvar, n) causes NonStop SQL to interpret the host
variable hostvar as:
hostvar * 10 - n
If the value in :host-variable is to be entered into a database using an INSERT or
UPDATE statement, the program must assign a value to :host-variable that allows for
the scale. For example, if the program is representing a price of $123.45, then the
program should assign 12345 to :host-variable and use SETSCALE to specify a scale
of 2.
If the value is retrieved from the database using a SELECT statement, NonStop SQL
assigns a value to :host-variable that allows for the scale. For example, if the value
123.45 is stored in the database, then the value 12345 is returned to :host-variable
when the program specifies SETSCALE with a scale of 2 in the SELECT statement. If
the value 123 is stored in the database and the program specifies SETSCALE with a
scale of 2, the value 12300 is returned to :host-variable.

Caution. Consider these points when you use the SETSCALE function:

• At the upper boundary scale for each data type, you must ensure that the value returned
from the database fits into the host variable. For example, if the host variable is specified to
SETSCALE with a scale of 5 (the upper boundary on scale for a 2-byte integer) and the
value 0.70000 is stored in the database, NonStop SQL sends a value of 70000, which
does not fit in a variable of type INT.

• To use SETSCALE in an expression, you must apply SETSCALE to each host variable
individually rather than to the result of the expression. For example, this expression adds
two prices with a scale of 2 decimal places:

SETSCALE (:price1, 2) + SETSCALE (:price2, 2)

• Remember to allow room in host variables for digits to the left of the decimal point. For
example, if the value in the database is 12.345, and you specify a scale of 5, the output
value, 1234500, will not fit in an INT host variable.

These examples use a TACL DEFINE named =PARTS for the PARTS table.
• Using SETSCALE with the INSERT statement
A program creates a new row with the value 98.34 in the PARTS.PRICE column after
storing the value in the host variable :HOSTVAR1. The value is multiplied by 100 and
stored in :HOSTVAR1.
! Assign 9834 to :hostvar1
EXEC SQL
INSERT INTO =parts (price)
VALUES ( SETSCALE (:hostvar1, 2) ) ;

HP NonStop SQL Programming Manual for TAL—527887-001


2- 14
Host Variables and Parameters Using Host Variables

• Using SETSCALE with the UPDATE statement


A program updates the PARTS.PRICE column for a disk controller to $158.34. The
value is multiplied by 100 and stored in the host variable :HOSTVAR2.
! Assign 15834 to :hostvar2
EXEC SQL
UPDATE =parts SET parts.price = SETSCALE (:hostvar2, 2)
WHERE parts.partdesc = "disk controller" ;
• Using SETSCALE with the SELECT statement for retrieving a value
A program retrieves the value in the PARTS.PRICE column for a disk controller and
stores the value in the host variable :HOSTVAR3. The value has a scale of 2.
EXEC SQL
SELECT parts.price INTO SETSCALE ( :hostvar3, 2 )
FROM =parts
WHERE parts.partdesc = "disk controller" ;
IF hostvar3/100 > 50000 THEN
! (print message that manager approval
! is required for purchase )
If the price of the disk controller is $60,000.00 in the database, :HOSTVAR3 has the
value 6,000,000 on output.
• Using SETSCALE with the SELECT statement for comparisons
A program retrieves the part description for the part with a price of $999.50. The price
value is stored in the host variable :HOSTVAR4 and supplied to SQL in the search
condition. The retrieved value is stored in the host variable :HVSTORE.
! Assign 99950 to :hostvar4
EXEC SQL
SELECT parts.partdesc INTO :hvstore
FROM =parts
WHERE parts.price = SETSCALE ( :hostvar4, 2 );

Using Date-Time and INTERVAL Data Types as Host Variables


NonStop SQL provides a set of special data types for specifying:
• Date-time values including separate date and time values
• Intervals or durations of time
Table 2-3 shows the date-time and INTERVAL data types. For more information on the
complete syntax, see the SQL/MP Reference Manual.

HP NonStop SQL Programming Manual for TAL—527887-001


2- 15
Host Variables and Parameters Using Host Variables

Table 2-3. Date-Time and INTERVAL Data Types


Data Type Description
DATETIME Represents a date, time, or date and time, from year to microsecond
(logical subsets, such as MONTH TO DAY, are allowed)
DATE Represents a date and is a synonym for DATETIME YEAR TO DAY
TIME Represents a time and is a synonym for DATETIME HOUR TO SECOND
TIMESTAMP Represents a date and time and is a synonym for DATETIME YEAR TO
FRACTION(6)
INTERVAL Represents a duration of time as a year-month or day-time interval

To communicate date-time values between TAL and SQL statements, you declare a
TAL STRING array as a host variable. Then you use the TYPE AS clause to cause
NonStop SQL to interpret the value in the STRING host variable as a date-time or
INTERVAL value. Some sample TYPE AS clauses are:
• TYPE AS DATETIME YEAR TO HOUR
• TYPE AS DATE
• TYPE AS TIME
• TYPE AS TIMESTAMP
• TYPE AS INTERVAL YEAR
You can also use date-time and INTERVAL literals. For example, to insert a date-time
or INTERVAL value using a literal into TABLE:
EXEC SQL INSERT INTO table (START_DATE )
VALUES DATE "1990-03-21";
Or, to insert the value using a host variable:
! Variable declarations:
EXEC SQL BEGIN DECLARE SECTION;
STRING datevar[O:9];
EXEC SQL END DECLARE SECTION;
...
! Procedure
! Copy "1990-03-21" into datevar
...
EXEC SQL INSERT INTO table (START_DATE)
VALUES :datevar TYPE AS DATE;
You can insert or retrieve date-time values in any of three formats, independently of the
SQL column definition. For example, you can specify formats such as 02/15/2004,
2004-02-15, or 15.02.2004. You control the display format by inserting the value in the

HP NonStop SQL Programming Manual for TAL—527887-001


2- 16
Host Variables and Parameters Using Indicator Variables for Null Values

format you want and retrieving the value using the DATEFORMAT function. You should
declare the host variable size to be consistent with the format you will use.
If you use the INVOKE directive to generate host variables from an SQL table
definition, you can specify the DATEFORMAT clause to create host variables of the
appropriate size. For more examples of the INVOKE directive, see Section 3, NonStop
SQL Statements and Directives.

Using Indicator Variables for Null Values


An indicator variable is a 2-byte integer variable defined in the Declare Section. An
indicator variable is always associated with a host variable and is used to indicate
whether a column can (or does) contain a null value. A null value in a column means
that a value is either unknown for the row or does not apply to the row.
When sending a value to NonStop SQL, a program sets the indicator variable to:
• Less than zero (0) for a null value
• Zero (0) for a nonnull value
When returning a value to a program, NonStop SQL sets the indicator variable to:
• Less than zero (0) for a null value
• Zero (0) for a nonnull value
The INVOKE directive automatically declares indicator variables for columns that allow
null values. If SQL columns can contain null values, a program should use indicator
variables when referring to those columns. For example, a program might:
• Insert null values into the database with an INSERT or UPDATE statement
• Retrieve null values from the database with a SELECT statement
• Specify null values in an INSERT, UPDATE, DELETE, or SELECT statement
You can also use indicator variables with the INSERT, UPDATE, DELETE, and
SELECT statements. You can use the keyword NULL, as shown in the subsequent
examples in this section.

HP NonStop SQL Programming Manual for TAL—527887-001


2- 17
Host Variables and Parameters Using Indicator Variables for Null Values

Inserting a Null Value


These examples use indicator variables to insert a null value and to select from a
column that can return a null value. the TACL DEFINEs =RETIREES and
=SHIPMENTS are in effect for the respective tables.
This example uses an indicator variable to insert a null value:
! Variable declarations:
EXEC SQL BEGIN DECLARE SECTION;
INT empnum;
STRING retire^date[0:9];
INT retire^ind; ! indicator variable
EXEC SQL END DECLARE SECTION;
...
PROC insert^data;
BEGIN
empnum := 22346;
retire^ind := -1;
...
EXEC SQL
INSERT INTO =retirees (empnum, retire_date)
VALUES (:empnum,
:retire^date INDICATOR :retire^ind);
! It is not necessary to assign a value to
! retire^date in order to specify a null value.
...
END;
You can also use the NULL keyword instead of an indicator variable to insert a null
value:
PROC insert^data;
BEGIN
empnum := 22346;
EXEC SQL
INSERT INTO =retirees (empnum, retire_date)
VALUES (:empnum, NULL );
...
END;

HP NonStop SQL Programming Manual for TAL—527887-001


2- 18
Host Variables and Parameters Using Indicator Variables for Null Values

Selecting a Null Value


This example selects data from the SHIPMENTS table and tests for null values using
the indicator variable named PROD^REC.SHIP^IND:
! Variable declarations:
EXEC SQL BEGIN DECLARE SECTION;
STRUCT .prod^rec;
BEGIN
INT prodnum;
INT ship^ind;
STRING date^shipped[0:9];
END;
EXEC SQL END DECLARE SECTION;
...
EXEC SQL DECLARE c1 CURSOR FOR
SELECT prodnum, date^shipped
FROM =SHIPMENTS
WHERE prodnum > 7999;
...
! Procedure code:
WHILE sqlcode = 0 DO
BEGIN
EXEC SQL
FETCH c1 INTO
:prod^rec.prodnum,
:prod^rec.date^shipped
INDICATOR :prod^rec.ship^ind;
IF prod^rec.ship^ind < 0 THEN ...
! display "?", "NULL", or other symbol to
! indicate a null value.
END;

HP NonStop SQL Programming Manual for TAL—527887-001


2- 19
Host Variables and Parameters Creating Host Variables With the INVOKE Directive

Creating Host Variables With the INVOKE Directive


You can use the INVOKE directive in a Declare Section to create host variables that
correspond to the columns in an SQL table. INVOKE converts the column names to
TAL identifiers and writes a TAL data description for each column. If a column allows a
null value, INVOKE also generates an indicator variable for the column.

Caution. If you use INVOKE and later change data types in your SQL tables, you must ensure
that numeric constants in the TAL program also change to reflect the new data types;
otherwise, the program will not compile. For example, if host variable :PARTNUM is originally
defined as an integer (INT), the test::

IF partnum > 1000

is valid. However, if the :PARTNUM column is changed to INVOKE statement with the data
type INT(32), the test must be:

IF partnum > 1000D

Table 2-4 shows the override data type mapping used by the INVOKE directive.

Table 2-4. INVOKE Directive Override Data Type Mapping


SQL Data Type Host Variable Description Generated by the INVOKE Directive
SMALLINT INT name / SMALLINT UNSIGNED /
UNSIGNED
INTEGER INT(32) name / INTEGER UNSIGNED /
UNSIGNED
NUMERIC (1 - 4, UNSIGNED INT name / SMALLINT UNSIGNED /
s)
NUMERIC (5 - 9, UNSIGNED INT(32) name / INTEGER UNSIGNED /
s)6
DECIMAL(1) STRING name / DECIMAL(1) /
DECIMAL(1) UNSIGNED STRING name / DECIMAL(1) UNSIGNED /
DECIMAL (n) STRING name [0 : n - 1] / DECIMAL(n) /
DECIMAL (n) UNSIGNED STRING name [0 : n - 1] / DECIMAL (n) UNSIGNED /
name is the name of the host variable.
n is a positive integer that represents the length.
s is a positive integer that represents the scale of the number.

This example shows the TAL compiler output for a table that contains columns of the
TAL data types. This example includes the INVOKE directive as it appears in the
source program, the CREATE TABLE statement that defines the table, and the
generated structure type. The table contains columns of all SQL data types. INVOKE
generates override data type mapping for some data types.

HP NonStop SQL Programming Manual for TAL—527887-001


2- 20
Host Variables and Parameters Creating Host Variables With the INVOKE Directive

The INVOKE directive as it appears in the source program is:


EXEC SQL BEGIN DECLARE SECTION;
EXEC SQL INVOKE typestbl AS types^rec;
EXEC SQL END DECLARE SECTION;
The CREATE TABLE statement that defines the table is:

CREATE TABLE $vol.sales.typestbl


( a_char CHAR (10) NOT NULL,
b_varchar VARCHAR (10) NOT NULL,
c_num4_s NUMERIC (4) SIGNED NOT NULL,
d_num4_u NUMERIC (4) UNSIGNED NOT NULL,
e_num9_s NUMERIC (9,2) SIGNED NOT NULL,
f_num9_u NUMERIC (9,2) UNSIGNED NOT NULL,
g_num18_S NUMERIC (18,2) SIGNED NOT NULL,
h_small_S SMALLINT SIGNED NOT NULL,
j_small_U SMALLINT UNSIGNED NOT NULL,
k_int_s INTEGER SIGNED NOT NULL,
l_int_u INTEGER UNSIGNED NOT NULL,
m_large_s LARGEINT SIGNED NOT NULL,
n_dec_s DECIMAL (18,2) SIGNED NOT NULL,
o_dec_u DECIMAL (9,2) UNSIGNED NOT NULL,
p_cob_p9 PIC 9(9) COMP NOT NULL,
q_cob_px PIC X(10) NOT NULL,
z_long PIC X(20) NOT NULL,
a_dbl FLOAT (15) NOT NULL,
b_dbl FLOAT (30) NOT NULL,
c_dbl REAL NOT NULL,
d_dbl DOUBLE PRECISION NOT NULL,
a_dt_time DATETIME YEAR TO DAY NOT NULL,
b_dt_time DATE NOT NULL,
c_dt_time TIME NOT NULL,
d_dt_time TIMESTAMP NOT NULL,
e_dt_time INTERVAL MONTH(6) NOT NULL
)
CATALOG $vol1.sales ;

HP NonStop SQL Programming Manual for TAL—527887-001


2- 21
Host Variables and Parameters Creating Host Variables With the INVOKE Directive

The generated structure template is:


struct types^rec(*);
BEGIN
string a^char[0:9];
struct b^varchar;
begin
int len;
string val [0:9];
end;
int c^num4^s;
int d^num4^u /SMALLINT UNSIGNED/;
int(32) e^num9^s; !scale is 2
int(32) f^num9^u /INTEGER UNSIGNED/; !scale is 2
fixed(2) g^num18^s; !scale is 2
int h^small^s;
int j^small^u /SMALLINT UNSIGNED/;
int(32) k^int^s;
int(32) l^int^u /INTEGER UNSIGNED/;
fixed(0) m^large^s;
string n^dec^s [0:17] /DECIMAL(18)/; !scale is 2
string o^dec^u [0:8] /DECIMAL(9)UNSIGNED/; !scale is 2
int(32) p^cob^p9 /INTEGER UNSIGNED/;
string q^cob^px [0:9];
string z^long [0:19];
real a^dbl;
real(64) b^dbl;
real c^dbl;
real(64) d^dbl;
string a^dt^time [0:9];
string b^dt^time [0:9];
string c^dt^time [0:7];
string d^dt^time [0:25];
string e^dt^time [0:6];
END;

To use the table in your program, declare a structure as:


STRUCT .tbl(types^rec); ! Declare an instance, tbl, of
! the template, types^rec

HP NonStop SQL Programming Manual for TAL—527887-001


2- 22
Host Variables and Parameters Parameters

Your program can now read the values stored in the columns of the SQL table into the
host variables. For example:
EXEC SQL SELECT typestbl.a_char, typestbl.a_dbl
INTO :tbl.a^char, :tbl.a^dbl;

Parameters
A parameter is a place holder variable in an SQL statement that enables you to specify
run-time input in a dynamic SQL statement. You compile the SQL statement without
the input values and then supply the values when the statement is executed. The
syntax for a parameter is shown below. For a complete description of the parameter
syntax elements, see the SQL/MP Reference Manual.

?[ identifier] [ [ INDICATOR ] ?[indicator-parameter] ]


[ TYPE AS {DATETIME [ start-date-time TO] end-date-time} ]
[ { } ]
[ {DATE } ]
[ { } ]
[ {TIME } ]
[ { } ]
[ {TIMESTAMP } ]
[ { } ]
[ {INTERVAL start-date-time } ]
[ { [ ( start-field-precision ) ] } ]
[ { [ TO end-date-time ] } ]

identifier
is an SQL identifier that is the name of the parameter. Follow these guidelines when
you declare and use parameter names:
• You cannot qualify a parameter name.
• An unnamed parameter, which is a question mark (?) by itself, is always a distinct
parameter even with multiple occurrences in a statement.
• You can use a parameter name in any SQL statement (except a DDL statement)
where a numeric or string literal is allowed.

indicator-parameter
is the indicator parameter name. The indicator parameter has the same format as
the parameter name with which it is associated. You use an indicator parameter to
handle null values that might be returned to the parameter or to insert null values
into a database through the parameter.
For handling a null value returned to the parameter, the value of identifier can be –
1 if the value is null or 0 if the value is not null. For inserting a value into a
database, set indicator-param to –1 (null) or 0 (not null) before executing the
INSERT or UPDATE statement.

HP NonStop SQL Programming Manual for TAL—527887-001


2- 23
Host Variables and Parameters Using a Parameter List

TYPE AS ...
indicates that NonStop SQL should treat the value entered for the parameter as a
date-time or INTERVAL value. A parameter that represents a date-time or
INTERVAL value must have a character data type.

Using a Parameter List


To ensure a one-to-one correspondence between a parameter list and the host
variables that you use to supply values for the parameters, use unnamed parameters.
If duplicate parameter names appear in a statement, the names require a value for
only the first occurrence, and the duplicate occurrences receive the same value.
Suppose that the following UPDATE statement is stored in the host variable
:UPDATE^STMT:
UPDATE table SET col1 = ?a, col2= ?a, col3 = ?b
A PREPARE statement prepares the statement in the host variable :UPDATE^STMT:
PREPARE exec^stmt FROM :update^stmt
To supply values for the UPDATE statement at run time, the program uses the two host
variables :HOST^VAR1 and :HOST^VAR2 :
EXECUTE exec^stmt USING :host^var1, :host^var2
The value stored in HOST^VAR1 is used for both instances of the parameter named
?A. The value stored in :HOST^VAR2 is used for the parameter named ?B. If you use
three host variables, NonStop SQL uses the value in the first host variable for both
occurrences of parameter ?A. The value in the second host variable is used for
parameter ?B, and the value in the third host variable remains unused. For example, in
this statement:
EXECUTE exec^stmt USING :host^var1, :host^var2, :host^var3;
NonStop SQL uses the value in :HOST^VAR1 for both occurrences of parameter ?A
and the value in :HOST^VAR2 for parameter ?B. The value in :HOST^VAR3 is ignored.

Caution. If you use the same parameter name more than once in a statement, NonStop SQL
gives each duplicate occurrence of the parameter the same data type, length, and other
attributes as the first occurrence.Thus, data can be lost in some cases.

For example, during the execution of an INSERT statement, a parameter gets the same data
type and attributes as the column into which the parameter’s value is first inserted. If the
parameter value is truncated to fit into the column, the values of any duplicate occurrences of
the parameter are also truncated, even if a column is large enough to hold the complete value.

HP NonStop SQL Programming Manual for TAL—527887-001


2- 24
Host Variables and Parameters Using Parameters in Loops

Using Parameters in Loops


Parameters are often used when a dynamic SQL statement is executed repeatedly
with different input values. In this example, a dynamic SQL statement uses a
parameter. Because the user of this program can enter any SQL statement, the
program does not have compile-time information about the statement. The TACL
DEFINE named =PARTS represents the PARTS table.
1. A user enters this SQL statement from a terminal:
UPDATE =parts SET price = ?p
2. The program copies the statement into the host variable named :INTEXT.
3. The program uses the PREPARE and DESCRIBE INPUT statements to get a
description of the parameter in the input SQLDA (IN^SQLDA) and to get the name
of the parameter in the input names buffer (I^NAMESBUF). The prepared
statement is named EXEC^STMT.
EXEC SQL PREPARE exec^stmt FROM :intext;
EXEC SQL DESCRIBE INPUT s1 INTO :in^sqlda
NAMES INTO :i^namesbuf;
4. The program enters a loop to prompt the user to supply values for successive
execution of the statement:
! Beginning of loop
! Prompt the user for a value using the parameter
! name from the names buffer
...
! Store the value in a value buffer pointed to by in^sqlda
! Execute the statement using each successive value:
EXEC SQL EXECUTE s1 USING DESCRIPTOR :in^sqlda;
! End of loop

Using Indicator Parameters


A program uses an indicator parameter to show that a null value was entered for a
parameter. The indicator parameter follows the parameter in the SQL statement. For
example:
INSERT INTO =employee VALUES (1000, ?p INDICATOR ?i );
If a user enters a null value for ?P, the program should set ?I to a value less than zero.
If a user enters a nonnull value, the program should set ?I to 0. Both ?P and ?I are in
the names buffer to allow prompting the user for a null value.
For more information and examples for using parameters in dynamic SQL statements,
see Section 7, Dynamic NonStop SQL Operations

HP NonStop SQL Programming Manual for TAL—527887-001


2- 25
Host Variables and Parameters Using Default Parameter Data Types

Using Default Parameter Data Types


If the TYPE AS clause is omitted from a dynamic SQL statement that uses date-time or
INTERVAL data types with parameters, NonStop SQL assigns a default data type to a
parameter as follows:

INTERVAL The parameter name is followed by a range of fields and start-


field-precision is specified.
DATETIME The parameter name is followed by a range of fields and start-
field-precision is not specified
DATETIME The expression takes any of these forms:
parameter-name { + | - } interval-term
interval-expression + parameter-name
date-time-expression - parameter-name
NUMERIC The expression takes any of these forms:
parameter-name { + | - } scalar-value
{ + | - } parameter-name

For more information about parameters in dynamic SQL statements, see Section 7,
Dynamic NonStop SQL Operations. For examples that use parameters in dynamic
SQL statements, see Appendix C, Examples of Dynamic NonStop SQL Programs.

HP NonStop SQL Programming Manual for TAL—527887-001


2- 26
3
NonStop SQL Statements and
Directives
This section describes:
• NonStop SQL statements and directives that you can embed in a TAL program
• SQL, SQLMEM, and SYMBOLPAGES TAL compiler directives
The NonStop SQL statements and directives that are described in this section have
specific TAL data structures, considerations, and examples. For the complete
description and syntax of all NonStop SQL statements and directives, see the SQL/MP
Reference Manual.
For a description of all TAL compiler directives, see the TAL Reference Manual.

Embedding SQL Statements and Directives


An SQL statement or directive embedded in a TAL program must begin with the
keywords EXEC SQL and end with a semicolon (;) or an END, ELSE, or UNTIL
keyword according to TAL statement separator conventions. The syntax is:

EXEC SQL sql-statement-or-directive [;]

sql-statement-or-directive
is an SQL statement or directive that is allowed in a TAL program as shown in
Table 3-1 on page 3-4.
You terminate an embedded SQL statement or directive as follows:
• In the data declarations, terminate an SQL statement or directive with a semicolon:
EXEC SQL BEGIN DECLARE SECTION; ! SQL directive
INT .name ; ! Host variable
EXEC SQL END DECLARE SECTION; ! SQL directive
• In the executable statements, terminate an SQL statement with a semicolon except
before an END, ELSE, or UNTIL keyword as appropriate for the TAL statement:
IF in^numvars > 0 THEN
EXEC SQL EXECUTE state^ment^1 USING DESCRIPTOR :sdao
ELSE
EXEC SQL EXECUTE state^ment^2;

HP NonStop SQL Programming Manual for TAL—527887-001


3-1
NonStop SQL Statements and Directives Coding Statements and Directives

Coding Statements and Directives


In general, consider embedded SQL statements and directives as if they are TAL
statements. Follow the same formatting and line continuation conventions for SQL
statements as you use for TAL statements. Here are a few specific guidelines to follow
when you embed SQL statements and directives in a TAL program:
• You can code longer statements or directives on more than one line. For example:
EXEC SQL
SELECT customer.custname
INTO :customer.custname
FROM sales.customer
WHERE custnum = :find^this^customer;
• Use either SQL or TAL comments in statements and directives.
An SQL comment statement begins with a double hyphen (--) and ends with the
end of the line.
A TAL comment statement can also begin with a double hyphen (--) and end with
the end of the line, or it can begin with an exclamation point (!) and end with
another exclamation point or the end of the line.
• Use either a single quotation mark (') or double quotation marks (") to delimit string
literal statements; however, you must use the same character at both ends of the
string.
• Do not use an SQL statement as part of a compound TAL statement.
• Do not use a TAL DEFINE declaration in an SQL statement.

Placing Statements and Directives in a Program


Place SQL statements and directives in a TAL source file as described next:

SQL Directive
To embed SQL statements and directives in a TAL program, specify the SQL directive
before any SQL or TAL declarations and source code statements (including comment
statements). The SQL directive enables the TAL compiler to process subsequent SQL
statements and directives.
Specify the SQL directive either in your source code file or as a compiler option in the
implicit TACL RUN command for the TAL compiler. An example of the SQL directive in
a source code file is:
?SQL
An example of the SQL directive as a compiler option is:
TAL /IN tsrc, OUT $s.#tlst, NOWAIT/ tobj; SQL

HP NonStop SQL Programming Manual for TAL—527887-001


3-2
NonStop SQL Statements and Directives Placing Statements and Directives in a Program

SYMBOLPAGES Directive
To use the SYMBOLPAGES directive, specify it as a compiler option in the RUN
command line for the TAL compiler when you compile the program:
TAL /IN tsrc, OUT $s.#tlst, NOWAIT / tobj; SYMBOLPAGES 2048

Data Declarations
With TAL variable declarations, you can use the:
• BEGIN DECLARE SECTION and END DECLARE SECTION directives
• DECLARE CURSOR statement (static cursor only, global declarations only)
• INCLUDE SQLCA, INCLUDE SQLSA, and INCLUDE SQLDA directives
• INVOKE directive
• CONTROL directives

Executable Statements
With TAL executable statements, you can use the:
• Data Control Language (DCL) statements and CONTROL directives
• Data definition language (DDL) statements
• Data manipulation language (DML) statements
• Dynamic SQL statements (including DECLARE CURSOR)
• Transaction control statements

Data Declarations and Executable Statements


Use these directives anywhere in a TAL program:
• TAL SOURCE and SEARCH directives
• SQL SQLMEM directive (however, you cannot use SQLMEM with the STACK
option in a subprocedure)
• SQL WHENEVER directive

HP NonStop SQL Programming Manual for TAL—527887-001


3-3
NonStop SQL Statements and Directives Locating Information About SQL Statements and
Directives

Locating Information About SQL Statements


and Directives
Table 3-1 summarizes the NonStop SQL statements and directives by type and the
manual that documents each statement or directive.
The remainder of this section describes the NonStop SQL statements and directives in
alphabetic order. Only the SQL, SQLMEM, and SYMBOLPAGES directive descriptions
show the complete syntax. For the syntax, general description, and guidelines for other
SQL statements and directives, see the SQL/MP Reference Manual.

Table 3-1. Summary of NonStop SQL Statements and Directives (page 1 of 3)


Statement or Directive Manual * Description
Data Control Language (DCL) Statements
FREE RESOURCES SQLRM Closes cursors and releases locks held by
the program.
LOCK TABLE SQLRM Locks a table or underlying tables of a view
and associated indexes.
UNLOCK TABLE SQLRM Releases locks held on nonaudited tables
or views.
Data Definition Language (DDL) Statements
ALTER SQLRM Alters the definition of a table; changes
attributes of an index or table; alters
security attributes of a catalog, index,
program, table, or view; renames a table,
index, program, or view; or adds, drops, or
moves a partition of a table or index.
COMMENT SQLRM Adds comments to an object definition.
CREATE SQLRM Creates a constraint, catalog, index, table,
or view.
DROP SQLRM Drops a constraint, catalog, index,
program, table, or view.
HELP TEXT SQLRM Specifies help text for a column of a table
or view.
UPDATE STATISTICS SQLRM Updates information about the contents of
a table and its indexes.
Data Manipulation Language (DML) Statements
CLOSE SQLRM+SQL/TAL Terminates a cursor.
DECLARE CURSOR SQLRM+SQL/TAL Defines a cursor
(static)
DELETE SQLRM+SQL/TAL Deletes rows from a table or view.
FETCH SQLRM+SQL/TAL Retrieves a row from a cursor.

HP NonStop SQL Programming Manual for TAL—527887-001


3-4
NonStop SQL Statements and Directives Locating Information About SQL Statements and
Directives

Table 3-1. Summary of NonStop SQL Statements and Directives (page 2 of 3)


Statement or Directive Manual * Description
INSERT SQLRM+SQL/TAL Inserts rows into a table or view.
OPEN SQLRM+SQL/TAL Opens a cursor.
SELECT SQLRM+SQL/TAL Retrieves data from tables and views.
UPDATE SQLRM+SQL/TAL Updates values in columns of a table or
view.
Dynamic NonStop SQLRM Statements
DECLARE CURSOR SQLRM+TAL Defines a cursor.
DESCRIBE SQLRM+TAL Returns information about output variables
for a prepared statement.
DESCRIBE INPUT SQLRM+TAL Returns information about input variables
for a prepared statement.
EXECUTE SQLRM+TAL Executes a prepared SQL statement.
EXECUTE IMMEDIATE SQLRM+TAL Executes an SQL statement contained in a
host variable.
PREPARE SQLRM+TAL Compiles a DDL, DML, or DCL statement.
RELEASE SQLRM+TAL Deallocates memory for a dynamic SQL
statement referred to through a host
variable.
* SQLRM Described only in the SQL/MP Reference Manual
SQL/TAL Described only in this manual
SQLRM+SQL/TAL Described in both, this manual and the SQL/MP Reference Manual
Transaction Control Statements
BEGIN WORK SQLRM Starts a TMF transaction.
COMMIT WORK SQLRM Commits all database changes made
during the current TMF transaction and
frees resources.
ROLLBACK WORK SQLRM Backs out the current TMF transaction and
frees resources.
Data Declaration Directives
BEGIN DECLARE SQLRM+TAL Designates the beginning of host variable
SECTION declarations.
END DECLARE SQLRM+TAL Designates the end of host variable
SECTION declarations.
INCLUDE SQLCA SQLRM+TAL= Declares the SQLRM communication area
to receive run-time status information.
INCLUDE SQLDA SQLRM+TAL= Declares the SQL descriptor area to hold
information about input and output
variables for dynamic SQL statements.

HP NonStop SQL Programming Manual for TAL—527887-001


3-5
NonStop SQL Statements and Directives BEGIN DECLARE SECTION and END DECLARE
SECTION

Table 3-1. Summary of NonStop SQL Statements and Directives (page 3 of 3)


Statement or Directive Manual * Description
INCLUDE SQLSA SQLRM+TAL= Declares the SQL statistics area to receive
execution statistics on DML or PREPARE
statements.
INVOKE SQLRM+TAL Generates a TAL structure description of a
table or view.
Data Control Directives
CONTROL EXECUTOR SQLRM+TAL Specifies whether to process data using a
single executor or multiple executors
working in parallel.
CONTROL QUERY SQLRM+TAL Specifies whether to optimize queries for
time to return first row or for total query
execution time.
CONTROL TABLE SQLRM+TAL Specifies parameters that control locks on
tables and how tables are opened.
Error Checking Directives
WHENEVER SQLRM+TAL= Generates code that checks SQL
statement execution for errors, warnings,
and no-row-found condition.
TAL Compiler Directives
SQL TAL Directs the TAL compiler to prepare for
processing SQL statements.
SQLMEM TAL Controls the placement of internal SQL
structures in run-time memory.
SYMBOLPAGES TAL Controls the size of the symbol table.
* SQLRM Described only in the SQL/MP Reference Manual
SQL/TAL Described only in this manual
SQLRM+SQL/TAL Described in both manuals =
Described in Section 6, Error and Status Processing of this manual.

BEGIN DECLARE SECTION and END DECLARE SECTION


The BEGIN DECLARE SECTION and END DECLARE SECTION directives designate
the beginning and ending of a Declare Section that contains host variable declarations.
A Declare Section is a part of a program that contains host variable declarations.
Follow these guidelines when you use the BEGIN DECLARE SECTION and END
DECLARE SECTION directives:
• You can use any variable declared in the Declare Section as a host variable. For
more information see Section 2, Host Variables and Parameters
• Do not put a Declare Section in a structure declaration.

HP NonStop SQL Programming Manual for TAL—527887-001


3-6
NonStop SQL Statements and Directives CLOSE

• A program or compilation unit can contain several Declare Sections; however, you
cannot nest Declare Sections (that is, put a Declare Section in another Declare
Section).
• The TAL compiler does not recognize the SQL SOURCE directive. Use the TAL
SOURCE directive instead.
• You can use TAL comment lines in a Declare Section.
The following declarations contain a Declare Section. You can use the variables
custnum and city as host variables in SQL statements; however, you cannot use the
variables SUPPLIER, ORDERS, ORDERNUM, DATE, or PARTCOST as host variables
because they are not declared in the Declare Section.
INT supplier;
STRUCT .orders;
BEGIN
INT ordernum;
STRING date[0:5];
END;
EXEC SQL BEGIN DECLARE SECTION;
INT custnum;
STRING city[0:14];
EXEC SQL END DECLARE SECTION;
INT partcost;
...

CLOSE
The CLOSE statement closes a cursor. After the CLOSE statement executes, the
result table established by the cursor no longer exists.
At run time, the OPEN statement for a cursor must execute before the CLOSE
statement (and all FETCH statements) for the cursor.

Determining the Scope of a Cursor for a CLOSE Statement


A static SQL cursor can only be used in the procedures in the compilation unit where
the cursor is declared. Thus, for static SQL operations, the DECLARE CURSOR,
OPEN, FETCH, DELETE, UPDATE, and CLOSE statements that refer to the cursor
must be in the same compilation unit.
If the program exits a procedure with an open cursor, procedures that execute later can
still refer to the cursor, provided the procedures are in the same compilation unit.
For a dynamic SQL cursor, all statements referring to the cursor must appear in the
procedure where the cursor is declared; however, if you open the cursor and use it in
one call to the procedure where it is declared, you can still use the cursor in
subsequent calls without opening the cursor again.

HP NonStop SQL Programming Manual for TAL—527887-001


3-7
NonStop SQL Statements and Directives CONTROL Directives

This example shows the CLOSE statement in a typical sequence of statements that
use a cursor.
EXEC SQL
DECLARE check_emp CURSOR FOR ! Declare the cursor.
SELECT deptnum
FROM employee
WHERE deptnum = :deptnum^del
FOR UPDATE OF deptnum ;
...
! get a value for :deptnum^del.
EXEC SQL
OPEN check_emp ; ! Open the cursor.
! FETCH rows until the NOT FOUND condition is met.
WHILE SQLCODE >= 100 DO
BEGIN
EXEC SQL
FETCH check_emp ! FETCH a value.
INTO :deptnum ;
! Delete a row that matches the criteria.
...
END
EXEC SQL
CLOSE check_emp ; ! Close the cursor.

CONTROL Directives
The CONTROL directives and their functions are:

CONTROL EXECUTOR
Allows or prohibits parallel evaluation of a query by multiple SQL executors

CONTROL QUERY
Specifies whether NonStop SQL should optimize the query time for either returning
the first few rows found or for returning all the rows found

CONTROL TABLE
Specifies options that control locks and opens on tables and views, and whether to
buffer INSERT and UPDATE operations
You can use CONTROL directives with either static SQL or dynamic SQL statements.
CONTROL directives do not affect SQL DDL statements. The SQL/MP Reference
Manual contains general information and syntax for the CONTROL directives. The
following paragraphs provide information for using the directives in a TAL program.

HP NonStop SQL Programming Manual for TAL—527887-001


3-8
NonStop SQL Statements and Directives CONTROL Directives

Using the CONTROL EXECUTOR Directive


Follow these guidelines when you use the CONTROL EXECUTOR directive:
Execution Plan. The CONTROL EXECUTOR directive affects the execution plan for
subsequent DML statements in the source program in listing order (rather than
execution order) until:
• Another CONTROL EXECUTOR directive resets the option.
• The end of the procedure occurs.
Scope. The scope of a CONTROL EXECUTOR directive is as follows.
• A directive affects SQL statements in the program's listing order, regardless of the
execution order.
• If a CONTROL EXECUTOR directive coded with the global declarations, it affects
only global cursors.
• If a CONTROL EXECUTOR directive coded in a procedure, it affects only the DML
statements in the procedure.
• A CONTROL directive coded in a subprocedure affects all static SQL statements
that follow in listing order until the end of the procedure in which the subprocedure
is embedded.
Flow-Control Statements. A CONTROL EXECUTOR directive coded within flow-
control statements (for example, IF, THEN, and ELSE) applies to static SQL
statements in the program's listing order, regardless of the execution order.
Dynamic SQL Statements. A static CONTROL EXECUTOR directive has no effect on
dynamic SQL statements. To use a CONTROL EXECUTOR directive with dynamic
SQL statements, specify a dynamic CONTROL directive using the PREPARE and
EXECUTE (or EXECUTE IMMEDIATE) statements.
For dynamic SQL cursors, the CONTROL EXECUTOR directive and the DECLARE
CURSOR statement must appear in the same procedure.
In this example, the cursor definition undergoes parallel evaluation as an equijoin
operation when the program issues the first fetch operation on the cursor. The common
column is CUSTNUM. The TACL DEFINEs =CUSTOMER and =ORDERS refer to the
CUSTOMER and ORDERS tables.
EXEC SQL CONTROL EXECUTOR PARALLEL EXECUTION ON ;
EXEC SQL DECLARE list_customers_with_orders CURSOR FOR
SELECT customer.custnum,
customer.custname
FROM =customer, =orders
WHERE customer.custnum = orders.custnum
STABLE ACCESS ;

HP NonStop SQL Programming Manual for TAL—527887-001


3-9
NonStop SQL Statements and Directives CONTROL Directives

Using the CONTROL QUERY Directive


Follow these guidelines when you use the CONTROL QUERY directive:
Optimization. The CONTROL QUERY directive affects the optimization for
subsequent DML statements in listing order (rather than execution order) until:
• Another CONTROL QUERY directive resets the option.
• The end of the procedure occurs.
Scope. The scope of a CONTROL QUERY directive is as follows.
• A directive affects SQL statements in the program's listing order, regardless of the
execution order.
• A directive coded with the global declarations affects only global cursors.
• A directive coded in a procedure affects only the DML statements in the procedure.
• A directive coded in a subprocedure affects all statements that follow in listing
order until the end of the procedure in which the subprocedure is embedded.
Flow-Control Statements. A CONTROL QUERY directive coded within flow-control
statements (for example, IF, THEN, and ELSE) applies to static SQL statements in the
program's listing order regardless of the execution order.
This example shows two CONTROL directives with dynamic SQL statements. The
EXECUTE statement is affected by the CONTROL TABLE directive with the TIMEOUT
option but not by the CONTROL QUERY directive. The TACL DEFINE =EMPLOYEE
refers to the employee table.
EXEC SQL PREPARE statement FROM "SELECT * FROM =EMPLOYEE";
EXEC SQL CONTROL QUERY INTERACTIVE ACCESS ON;
EXEC SQL CONTROL TABLE =employee TIMEOUT 120 SECONDS;
EXEC SQL EXECUTE statement;
Dynamic SQL Statements. A static CONTROL QUERY directive has no effect on
dynamic SQL statements. To use a CONTROL QUERY directive with dynamic SQL
statements, specify a dynamic CONTROL directive using the PREPARE and
EXECUTE (or EXECUTE IMMEDIATE) statements. For dynamic SQL cursors, the
CONTROL QUERY directive and the DECLARE CURSOR statement must be in the
same procedure.

Using the CONTROL TABLE Directive


Follow these guidelines when you use the CONTROL TABLE directive:
Access to Tables and Views. The CONTROL TABLE directive affects access to
tables and views referenced by SQL statements until:
• Another CONTROL TABLE directive resets the options.
• The end of the procedure occurs.

HP NonStop SQL Programming Manual for TAL—527887-001


3- 10
NonStop SQL Statements and Directives DECLARE CURSOR

Scope. The scope of a CONTROL TABLE directive is as follows.


• A directive affects SQL statements in the program's listing order, regardless of the
execution order.
• A directive with the global declarations affects only statements at the global level
(statements that are outside of procedures).
• A directive in a procedure affects only the statements in the procedure.
• A directive in a subprocedure affects all statements that follow in listing order until
the end of the procedure in which the subprocedure is embedded.
• To affect tables or views referenced in a cursor, the CONTROL TABLE directive
must precede the DECLARE CURSOR statement. For static SQL cursors, the
CONTROL TABLE directive and the DECLARE CURSOR statement must be with
the global declarations. For dynamic SQL cursors, the statements must be in the
same procedure.
Flow-Control Statements. A CONTROL TABLE directive coded within flow-control
statements (for example, IF, THEN, and ELSE) applies to static SQL statements in the
program's listing order, regardless of the execution order.
Dynamic SQL Statements. A static CONTROL TABLE directive does not affect
dynamic SQL statements. To use a CONTROL TABLE directive with dynamic SQL
statements, specify a dynamic CONTROL TABLE directive using the PREPARE and
EXECUTE (or EXECUTE IMMEDIATE) statements.
A dynamic CONTROL TABLE directive does not affect static SQL statements, unless
you specify the TIMEOUT option. In this case, the CONTROL TABLE directive affects
all static and dynamic SQL statements that follow in execution order (rather than listing
order), until another CONTROL TABLE directive resets the option or the end of the
procedure occurs.

DECLARE CURSOR
The DECLARE CURSOR statement defines a cursor and associates the cursor with a
SELECT statement. Using the cursor, TAL program can process, one by one, the rows
retrieved by the SELECT statement.
Follow these guidelines when you use the DECLARE CURSOR statement:

Static SQL Cursors


A static DECLARE CURSOR statement can appear only in the global declarations part
of a TAL compilation unit.
All host variables referenced by the DECLARE CURSOR statement in the static SQL
program must have global scope and must be declared in listing order before the
DECLARE CURSOR statement that references them.

HP NonStop SQL Programming Manual for TAL—527887-001


3- 11
NonStop SQL Statements and Directives DECLARE CURSOR

A static SQL cursor can be accessed only from the compilation unit in which its
DECLARE CURSOR statement occurs. This means that for static SQL programs, the
DECLARE CURSOR, OPEN, FETCH, DELETE WHERE CURRENT, UPDATE
WHERE CURRENT, and CLOSE statements must be in the same compilation unit. If
the program exits a procedure with an open cursor, procedures that execute later and
are in the same compilation unit can still reference the cursor.

Dynamic SQL Cursors


For dynamic SQL cursors, all statements referencing the cursor must appear in the
procedure where the cursor is defined; however, if you open the cursor and use it in
one call to the procedure where it is defined, you can still use the cursor in subsequent
calls, without opening the cursor again.

All Cursors
At run time, the OPEN statement must execute before all FETCH statements. Any
FETCH statements must execute before the CLOSE statement executes.
In this example, the DECLARE CURSOR statement uses a cursor that initiates a
SELECT operation from the PARTS table by the part name (PARTDESC) and by part
number (PARTNUM) within the part name. The TACL DEFINE =PARTS refers to the
parts table.
! Host variable declaration. INVOKE produces a
! structure template named parts^type, which is
! then used to declare a structure named parts^rec:
EXEC SQL INVOKE =parts;
STRUCT .parts^rec(parts^type);
! DECLARE CURSOR statement:
EXEC SQL DECLARE order_by_partdesc_cursor CURSOR FOR
SELECT partnum,
partdesc,
price,
qty_available
FROM =parts
WHERE (partdesc, partnum) >
( :parts^rec.partdesc, :parts^rec.partnum )
ORDER BY partdesc, partnum
BROWSE ACCESS ;
! Procedure code:
EXEC SQL OPEN order_by_partdesc_cursor;
WHILE SQLCODE >= 100 DO
! FETCH rows into host variables created with INVOKE
! until NOT FOUND condition is met:
BEGIN
EXEC SQL FETCH order_by_partdesc_cursor INTO
:parts^rec.partnum,

HP NonStop SQL Programming Manual for TAL—527887-001


3- 12
NonStop SQL Statements and Directives DELETE

:parts^rec.partdesc,
:parts^rec.price,
:parts^rec.qty^available;
END;
EXEC SQL CLOSE order_by_partdesc_cursor;

DELETE
The DELETE statement deletes one or more rows from a table or protection view. The
number of rows deleted is determined by the WHERE clause. A DELETE statement
can delete:
• A single row
• A set of rows
• A set of rows, one row at a time using a cursor (a mechanism for dealing with a set
of rows returned in sequence to a program)
To execute a DELETE statement, a TAL program's process accessor ID (PAID) must
have read and write access to the table or view and any table or view in subqueries of
the search condition.
In general, specifying a delete operation programmatically in a TAL program is the
same as specifying a delete operation using SQLCI commands. With SQLCI, you
specify the new values in an DELETE statement, while in a program, you set one or
more host variables to the new values and then use the host variables in the DELETE
statement.
This table shows the SQLCODE values that NonStop SQL returns after a DELETE
statement:
SQLCODE Value Description
0 The DELETE statement was successful.
100 No rows were found on a search condition.
<0 An error occurred; SQLCODE contains the error number.
>0 (not 100) A warning occurred; SQLCODE contains the first warning
number.

After a successful delete operation, the SQLCA structure contains the exact number of
rows deleted. After an error on a delete operation, the SQLCA contains an
approximate number of rows deleted. To obtain the contents of the SQLCA, use the
SQLCADISPLAY or SQLCATOBUFFER procedure.
If you delete all rows from a table, the table still exists until it is deleted from the catalog
with a DROP TABLE statement.

HP NonStop SQL Programming Manual for TAL—527887-001


3- 13
NonStop SQL Statements and Directives DELETE

Executing a Single-Row DELETE Statement


To delete a single row, you move a key value to a host variable and then use the host
variable in the WHERE clause of the DELETE statement. The following DELETE
statement deletes only one row of the EMPLOYEE table because each value in
EMPNUM is unique. EMPNUM is the primary key of the EMPLOYEE table. A user
enter a value for the :HOSTVAR^KEY host variable.
EXEC SQL
DELETE FROM =employee
WHERE empnum = :hostvar^key ;

Executing a Multi-Row DELETE Statement


Multi-row operations (sometimes called set operations) are performed on one or more
rows by a single SQL statement. Set operations provide maximum efficiency in both
coding and execution. Use set operations wherever possible for deleting sets of rows.
However, sometimes, you must check a row before deleting it. In this case, you must
use cursors as described under Using a Cursor to Delete Rows on page 3-15.
In these examples, a user enters the values for all host variables.
The following DELETE statement deletes all rows from the EMPLOYEE table that
contain information for employees in the department identified by the host variable
:HOSTVAR^DEPTNUM.
EXEC SQL
DELETE FROM =employee
WHERE deptnum = hostvar^deptnum ;
The following DELETE statement deletes all rows that contain a department number
matching the DEPTNUM value that is assigned to the host variable :HOSTVAR^DEPT
(for example, all employees working in department 100). DEPTNUM is not a primary
key; therefore, more than one row for each value of DEPTNUM can exist
EXEC SQL
DELETE FROM =employee
WHERE deptnum = :hostvar^dept ;
The following DELETE statement deletes from the ORDERS table all orders that were
placed with the sales representative identified by the host variable :HOSTVAR^REP by
any customer except the customer whose number is identified by the host variable
:HOSTVAR^CUSTNUM.
EXEC SQL
DELETE FROM sales.orders
WHERE salesrep = hostvar^rep
AND custnum <> hostvar^custnum;

HP NonStop SQL Programming Manual for TAL—527887-001


3- 14
NonStop SQL Statements and Directives DELETE

This DELETE statement deletes from the PARTSUPP table all suppliers who charge
more than the host variable :HOSTVAR^MAX^COST for terminals. Terminals have part
numbers in the range of the host variables :HOSTVAR^MIN to :HOSTVAR^MAX.
EXEC SQL
DELETE FROM invent.partsupp
WHERE partnum BETWEEN :hostvar^min AND :hostvar^max
AND partcost > hostvar^max^cost ; .

Using a Cursor to Delete Rows


To read and test a value before you delete a row, you must use a cursor. A cursor
allows you to delete a set of rows one row at a time. You specify the set of rows with
the SELECT clause in the DECLARE CURSOR statement. You read each row using a
FETCH statement, test the data, and then ignore or delete the row depending on your
test logic. If you determine that you want to delete the data from the table, you use a
DELETE WHERE CURRENT OF statement.

Note. Do not use a stand-alone DELETE operation to delete a row that has been retrieved
using a cursor FETCH operation. This can invalidate the cursor's buffering for the table and
might degrade performance.

For audited tables and views, a TMF transaction must be in progress. The same TMF
transaction must include both fetching and deleting the row. If you want to ensure that
a lock is held on the row you are deleting until the transaction completes, you can
declare the cursor with a DELETE WHERE CURRENT OF statement that specifies a
column in the rows to be deleted.
This example declares a cursor, fetches and tests the data, and then deletes the row:
EXEC SQL
DECLARE check_emp CURSOR FOR
SELECT deptnum
FROM employee
WHERE deptnum = :deptnum^del
OR deptnum = :deptnum^upd
FOR UPDATE OF deptnum ;
EXEC SQL
OPEN check_emp ;
EXEC SQL
FETCH check_emp
INTO :deptnum ;
! Program logic to test the data
...
EXEC SQL
DELETE FROM employee ! Delete the current row
WHERE CURRENT OF check_emp ;
EXEC SQL
CLOSE check_emp ;

HP NonStop SQL Programming Manual for TAL—527887-001


3- 15
NonStop SQL Statements and Directives DESCRIBE and DESCRIBE INPUT

You can refer to a static SQL cursor only in the compilation unit where the cursor is
declared. Thus, for static SQL programs, the DELETE WHERE CURRENT, DECLARE
CURSOR, OPEN, FETCH, and CLOSE statements that refer to the cursor must be in
the same compilation unit. If a program exits a procedure with an open cursor,
procedures that execute later can still refer to the cursor, provided the procedures are
in the same compilation unit.
For a dynamic SQL cursor, all statements referring to the cursor must appear in the
procedure where the cursor is defined. However, if you open the cursor and use it in a
call to the procedure where it is defined, you can still use the cursor in subsequent
calls without opening the cursor again.

DESCRIBE and DESCRIBE INPUT


The DESCRIBE statement returns information about output variables (usually SELECT
columns) associated with a previously prepared dynamic SQL statement. DESCRIBE
fills in an SQLDA structure and the names buffer with the descriptions and names of
the columns.
The DESCRIBE INPUT statement returns information about the input parameters
associated with a previously prepared SQL statement.
Follow these guidelines when you use a DESCRIBE or DESCRIBE INPUT statement:
• A DESCRIBE or DESCRIBE INPUT statement must appear in the same procedure
as the PREPARE, EXECUTE, or cursor SQL statements (DECLARE CURSOR,
OPEN, FETCH, CLOSE) that process the dynamic SQL input statement.
• Both DESCRIBE and DESCRIBE INPUT set the SQLDA NULL^INFO field
depending on whether the prepared SQL statement includes a null indicator and
not whether the column actually allows a null value. To determine whether a
column allows a null value, check the NULLALLOWED column in the COLUMNS
table for the catalog where the particular table is registered. To determine the
catalog for a table, use the FILEINQUIRE procedure.
• If a program declares an SQLSA structure, the DESCRIBE and DESCRIBE INPUT
statements return the same compilation statistics that PREPARE returns for the
OUTPUT^NUM, OUTPUT^NAMES^LEN, INPUT^NUM, and INPUT^NAMES^LEN
fields. For more information see the description of the SQLSA structure in
Section 6, Error and Status Processing.
The following example dynamically executes a SELECT statement, but it does not
know the actual text of the statement. The example uses a SELECT statement in the
host variable :INTEXT and prepares the statement in DYNASTATEMENT. The
DESCRIBE statement uses the SQLDA structure and the names buffer generated by
the INCLUDE SQLDA directive.

HP NonStop SQL Programming Manual for TAL—527887-001


3- 16
NonStop SQL Statements and Directives DROP

The size depends on the expected size and number of columns in the SELECT
statement. This example uses the arbitrary values 5 and 39; you can use different
values, or you can declare a template and dynamically allocate the memory.
! Global declarations
EXEC SQL INCLUDE SQLDA (sqlda1, 5, namebuf, 39);
EXEC SQL BEGIN DECLARE SECTION;
STRING intext [0:200];
EXEC SQL END DECLARE SECTION;
...
EXEC SQL
PREPARE dynstatement FROM :intext;
EXEC SQL
DESCRIBE dynstatement INTO :sqlda1
NAMES INTO :namebuf;
...

DROP
The DROP statement deletes a catalog, constraint, index, program, table, or view. To
drop an object, a program's process accessor ID (PAID) must have read and write
access to all catalogs that describe the objects affected by the drop. For specific SQL
objects, a program's PAID must have access as follows:
Table, view, or program Purge access
Index or constraint Must be the local or remote owner of the underlying table
with purge access (or the local super ID user)
Catalog Read and purge access for the catalog tables
SQL.CATALOGS Read and write access

Examples
In this example, the statements drop an index for the PARTS table before dropping the
table. The last statement drops a program.
EXEC SQL
DROP INDEX $vol1.sales.xpartdes;
EXEC SQL
DROP TABLE $vol1.sales.parts;
EXEC SQL
DROP PROGRAM $vol3.subvol3.proga;

HP NonStop SQL Programming Manual for TAL—527887-001


3- 17
NonStop SQL Statements and Directives EXECUTE and EXECUTE IMMEDIATE

EXECUTE and EXECUTE IMMEDIATE


The EXECUTE statement executes a previously prepared dynamic SQL statement.
The EXECUTE IMMEDIATE statement compiles and executes an SQL statement that
is represented as text in a host variable.
Use an EXECUTE statement for any DDL, DML, or DCL statement except the
SELECT statement. Use an EXECUTE IMMEDIATE statement for any DDL, DML, or
DCL statement except the OPEN, CLOSE, and SELECT statements. Use a cursor to
process a SELECT statement.
The EXECUTE statement must appear in the same procedure as the PREPARE,
DESCRIBE INPUT, and DESCRIBE statements that are used to process the dynamic
SQL input statement.

FETCH
The FETCH statement positions a cursor at the next row of the result table defined by
the cursor and retrieves the column values. This statement returns each column value
in the row into the corresponding host variable.
To execute a FETCH statement, a program's process accessor ID (PAID) must have
read access to any tables or views associated with the cursor.
At run time, the OPEN statement must execute before all FETCH statements, and the
CLOSE statement must execute after all FETCH statements for the cursor. Any host
variable used in a DECLARE CURSOR statement must be in the same scope for each
OPEN or FETCH statement for the cursor.
This table shows the SQLCODE values that NonStop SQL returns after a FETCH
statement:
SQLCODE Value Description
0 The FETCH statement was successful.
100 The end of a table was encountered.
<0 An error occurred; SQLCODE contains the error number.
> 0 (not 100) A warning occurred; SQLCODE contains the first warning number.

Determining the Scope of a Cursor for a FETCH Statement


A static SQL cursor can only be used in the procedures in the compilation unit where
the cursor is declared. Thus, for static SQL operations, the DECLARE CURSOR,
OPEN, FETCH, DELETE WHERE CURRENT, UPDATE WHERE CURRENT, and
CLOSE statements that refer to the cursor must be in the same compilation unit.
If the program exits a procedure with an open cursor, procedures that execute later can
still refer to the cursor, provided the procedures are in the same compilation unit.

HP NonStop SQL Programming Manual for TAL—527887-001


3- 18
NonStop SQL Statements and Directives INCLUDE SQLCA, INCLUDE SQLDA, and
INCLUDE SQLSA

For a dynamic SQL cursor, all statements referring to the cursor must appear in the
procedure where the cursor is declared; however, if you open the cursor and use it in
one call to the procedure where it is declared, you can still use the cursor in
subsequent calls without opening the cursor again.

INCLUDE SQLCA, INCLUDE SQLDA, and INCLUDE SQLSA


The INCLUDE SQLCA, INCLUDE SQLDA, and INCLUDE SQLSA directives declare
the following data structures:

INCLUDE SQLCA
Declares the SQL communications area (SQLCA), which contains run-time
information including errors and warnings generated by the most recently executed
SQL statement

INCLUDE SQLDA
Declares the SQL descriptor area (SQLDA), which contains run-time information
about input parameters and output variables in dynamic SQL statements

INCLUDE SQLSA
Declares the SQL statistics area (SQLSA), which contains run-time information
about the statistics and performance of SQL statements
For more information on the description of each directive, see Section 6, Error and
Status Processing.

INSERT
The INSERT statement inserts one or more rows into a table or protection view.
To execute an INSERT statement, a program's process accessor ID (PAID) must have
read and write access to the table or view receiving the data and read access to tables
and views if you use a SELECT statement parameter.
In general, specifying an insert operation programmatically in a TAL program is the
same as specifying an insert operation using SQLCI commands. With SQLCI, you
specify the new values in an INSERT statement, while in a program, you set one or
more host variables to the new values and then use the host variables in the INSERT
statement.
In a program, you move the row data to a series of host variables and then use an
INSERT statement that specifies these host variables to write the row to the table. For
example, the following statement inserts a row into the table named TABLE1:

HP NonStop SQL Programming Manual for TAL—527887-001


3- 19
NonStop SQL Statements and Directives INSERT

EXEC SQL
INSERT INTO table1
(column1,
column2,
column3,
column4)
VALUES (:host^var1,
:host^var2,
:host^var3,
:host^var4)
ANYWHERE ;
The previous example assumes that the organization of the table is relative. The
INSERT statement supplies values for the four named columns. The system supplies
the value for the system key (SYSKEY). Any other columns in the table receive default
values (either specified defaults or the system default). If any columns are defined as
NO DEFAULT, the insert operation fails because the values were not supplied.
The INSERT statement contains the ANYWHERE clause because the table
organization is relative. ANYWHERE causes the row to be inserted wherever space is
available. If you specify APPEND instead of ANYWHERE, the row is added to the end
of the table.
For a dynamic SQL program, the INSERT statement must be in the same procedure
as all other dynamic SQL statements that refer to the SQL statement being processed.
This table shows s the SQLCODE values that NonStop SQL returns after an INSERT
statement:
SQLCODE Value Description
0 The INSERT statement was successful.
100 No rows qualified for an INSERT through a SELECT specification.
<0 An error occurred; SQLCODE contains the error number.
> 0 (not 100) A warning occurred; SQLCODE contains the first warning number.

After a successful insert operation, the SQLCA structure contains the exact number of
rows inserted. To obtain the contents of the SQLCA, use the SQLCADISPLAY or
SQLCATOBUFFER procedure.

Inserting Null Values


This example inserts an employee record into the EMPLOYEE table and sets the
SALARY column to a null value using an indicator variable. This example uses the
TACL DEFINE name =EMPLOYEE for the EMPLOYEE table.

HP NonStop SQL Programming Manual for TAL—527887-001


3- 20
NonStop SQL Statements and Directives INSERT

! Variable declarations:
EXEC SQL BEGIN DECLARE SECTION;
STRUCT employee^type(*);
BEGIN
INT empnum /SMALLINT UNSIGNED/;
STRING first^name[0:14];
STRING last^name[0:19];
INT deptnum /SMALLINT UNSIGNED/;
INT jobcode /SMALLINT UNSIGNED/;
INT(32) salary /INTEGER UNSIGNED/; ! scale is 2
... END;
STRUCT .emp(employee^type);
INT ind^1;
EXEC SQL END DECLARE SECTION;
...
! Executable statements:
ind^1 := -1; ! Set indicator variable
EXEC SQL
INSERT INTO =employee (first^name, last^name, salary)
VALUES (:emp.first^name,
:emp.last^name,
:emp.salary INDICATOR :ind^1);
To insert a value with scale (for example, a price or salary) into a database, use a host
variable of TAL FIXED or INT (32) data type and then use the SQL SETSCALE
function to specify the scale.
In this example uses the NULL keyword instead of an indicator variable:
EXEC SQL
INSERT INTO =employee (first^name, last^name, salary)
VALUES (:emp.first^name,
:emp.last^name,
NULL);

Inserting a Timestamp Value


This example inserts a timestamp value into COLUMN^A of TABLE^T. The
COLUMN^A definition specifies the data type TIMESTAMP DEFAULT CURRENT.
When the example inserts a row, NonStop SQL inserts the current timestamp but does
not know the timestamp value inserted.

HP NonStop SQL Programming Manual for TAL—527887-001


3- 21
NonStop SQL Statements and Directives INVOKE

The example uses the JULIANTIMESTAMP and CONVERTTIMESTAMP Guardian


procedures and the CONVERTTIMESTAMP SQL function. To call Guardian
procedures, include the declarations from the EXTDECS file.
?SOURCE $SYSTEM.SYSTEM.EXTDECS ( JULIANTIMESTAMP,
CONVERTTIMESTAMP)
EXEC SQL BEGIN DECLARE SECTION;
FIXED dtvar; ! Variable for storing the timestamp value
EXEC SQL END DECLARE SECTION;
INT SQLCODE;
...
PROC driver MAIN ;
BEGIN
! Get current Julian timestamp in Greenwich mean time:
dtvar := JULIANTIMESTAMP();
! Convert timestamp to local time:
dtvar := CONVERTTIMESTAMP(dtvar);
! Insert value into table using SQL CONVERTTIMESTAMP:
EXEC SQL BEGIN WORK;
EXEC SQL INSERT INTO table^t (column^a)
VALUES ( CONVERTTIMESTAMP (:dtvar) );
EXEC SQL COMMIT WORK;
END;

INVOKE
The INVOKE directive defines a TAL structure template with fields and data types that
correspond one to one with the columns in an SQL table or view. INVOKE writes a TAL
data description for each column in the table or view.
Use INVOKE to create:
Host variables in a Declare Section that correspond to the columns in a table Indicator
variables that indicate whether a column value contains (or can contain) a null value
Follow these guidelines when you use the INVOKE directive:
• Use the INVOKE directive only in the variable declarations; do not use it with
executable statements.
• To use the INVOKE directive on a table or view, you must have read access to the
table or view when you compile your program.
• For the best performance, use INVOKE to define host variables that serve as input
or output variables for database columns. INVOKE defines the host variables so
that data conversion is not required at run time. For more information see Creating
Host Variables With the INVOKE Directive on page 2-20, in Section 2, Host
Variables and Parameters.

HP NonStop SQL Programming Manual for TAL—527887-001


3- 22
NonStop SQL Statements and Directives INVOKE

• Use TACL DEFINEs only for table or view names; do not use them for structure
names.
Table 3-2 shows the override data type mapping generated by the INVOKE directive.

Table 3-2. INVOKE Directive Override Data Type Mapping


Host Variable Description Generated by the INVOKE
SQL Data Type Directive
SMALLINT UNSIGNED INT name / SMALLINT UNSIGNED /
INTEGER UNSIGNED INT(32) name / INTEGER UNSIGNED /
NUMERIC (1 - 4, s) UNSIGNED INT name / SMALLINT UNSIGNED /
NUMERIC (5 - 9, s) UNSIGNED INT(32) name / INTEGER UNSIGNED /
DECIMAL(1) STRING name / DECIMAL(1) /
DECIMAL(1) UNSIGNED STRING name / DECIMAL(1) UNSIGNED /
DECIMAL (n) STRING name [0 : n - 1] / DECIMAL(n) /
DECIMAL (n) UNSIGNED STRING name [0 : n - 1] / DECIMAL (n) UNSIGNED /
name is the name of the host variable.
n is a positive integer that represents the length.
s is a positive integer that represents the scale of the number.

Defining the Structure Template


The INVOKE directive defines a structure template with a default name as the table
name plus the suffix ^TYPE. For example, the following INVOKE directive defines a
structure template for the EMPLOYEE table:
EXEC SQL INVOKE employee;
The CREATE TABLE statement that defines the table is:
CREATE TABLE employee
(emp_id NUMERIC(4) NOT NULL,
dept_num NUMERIC(6) NOT NULL
);
The INVOKE directive causes the TAL compiler to generate the following structure
template:
! Record Definition for table \SYS.$DB.PERSNL.EMPLOYEE
! Definition current at 14:54:18 - 09/27/89
STRUCT employee^type (*);
BEGIN
INT emp^id;
INT(32) dept^num;
END;

HP NonStop SQL Programming Manual for TAL—527887-001


3- 23
NonStop SQL Statements and Directives INVOKE

To use the structure template in your program, declare an instance of the structure.
This example declares a structure named EMPLOYEE that has the layout of the
structure template EMPLOYEE^TYPE:
STRUCT .employee (employee^type);
You must qualify the host variables defined by INVOKE (for example,
EMPLOYEE.EMP^ID).
You cannot reference a structure name by itself as a host identifier. The only
exceptions are structures that conform to the definition of SQL type VARCHAR, and
the SQLDA structure.

Using VARCHAR Data Types


An SQL VARCHAR column corresponds to a single logical data element; however, for
TAL correspondence, a VARCHAR column is converted to a structure with two
elementary data items. The group item name is derived from the VARCHAR column
name. The data names of the subordinate data items are LEN, a numeric field for the
current length, and VAL, a fixed-length character field for the string. For example, a
column CUSTNAME defined as VARCHAR(26) is described with this structure
template:
STRUCT custname(*);
BEGIN
INT len;
STRING val[0:25];
END;

Using Scaled Data Types


When you invoke a column with a scaled numeric type, the SQL compiler generates a
comment that gives the scale of the column being declared. For example, if PRICE
with data type NUMERIC (8,2) is invoked in TAL, INVOKE generates this:
INT(32) price; ! scale is 2
To communicate a scale factor to SQL, either change the host variable price to TAL
data type FIXED(2), which is a larger number but allows you to represent the scale, or
use the SQL SETSCALE function.

Using Date-Time and INTERVAL Data Types


When you invoke a column with a date-time (DATETIME, DATE, TIME, or
TIMESTAMP) or INTERVAL data type, the data is represented as a character field. The
size of the field is determined by the range of the date-time or INTERVAL column. You
control the display format by inserting the value in the format you want and retrieving
the value using the DATEFORMAT function. If you use INVOKE to generate host
variables from an SQL table definition, you can specify the DATEFORMAT clause to
determine the size.

HP NonStop SQL Programming Manual for TAL—527887-001


3- 24
NonStop SQL Statements and Directives INVOKE

INTERVAL values are represented as character strings with a separator between the
values of the fields (year-month or day-time). An extra byte is generated at the
beginning of the INTERVAL string for a sign.
The default representations for date-time and INTERVAL values are shown in these
subsections.
Date-Time Representation. The column definitions in the SQL table are:
name CHAR(18)
birth_date DATETIME
The date represented is May 28, 1952:
Year Separator Month Separator Day Null
1 9 5 2 - 0 5 - 2 8

The structure definition in the TAL program is:


STRUCT employee^rec;
BEGIN
STRING name[0:17];
STRING birth^date[0:9];
END;
The host variable reference is:
:age TYPE AS INTERVAL YEAR(2) TO MONTH
These examples use host variables with date-time and INTERVAL values. Appendix B
also includes a program that uses date-time and INTERVAL values.
Selecting Date-Time and INTERVAL Values. In this example, a table named
PROJECTS is invoked from a database. The table has this SQL definition:
PROJECT_NAME PIC X(10)
START_DATE DATETIME YEAR TO MINUTE
END_DATE DATETIME YEAR TO MINUTE
WAIT_TIME INTERVAL DAY(2)
This example uses a TACL DEFINE named =PROJECTS for the table. The structure
that appears in the program is shown after the INVOKE directive.
EXEC SQL BEGIN DECLARE SECTION;
...
EXEC SQL INVOKE =projects;
! The following template is inserted at compile time:
! STRUCT projects^type(*);
! BEGIN
! STRING project^name[0:9];
! STRING start^date[0:15];
! STRING end^date[0:15];

HP NonStop SQL Programming Manual for TAL—527887-001


3- 25
NonStop SQL Statements and Directives INVOKE

! STRING wait^time[0:2]; ! An extra byte is generated


! for a possible sign
! END;
! Declare storage for the table:
STRUCT .projects^rec(projects^type);
! Procedure code:
EXEC SQL
SELECT project^name, start^date, end^date, wait^time
INTO
:projects^rec.project^name,
:projects^rec.start^date TYPE AS DATETIME YEAR TO MINUTE,
:projects^rec.end^date TYPE AS DATETIME YEAR TO MINUTE,
:projects^rec.wait^time TYPE AS INTERVAL DAY(2)
FROM =projects
WHERE project^name = "995";
...
Inserting Date-Time and INTERVAL Values. In this example, date-time (DATE) and
INTERVAL values are inserted into the BILLINGS table. The SQL definition is shown at
the beginning of the example.
The SQL definition for the billings table is:
! CUSTNUM CHAR (4) NOT NULL
! START_DATE DATE NOT NULL
! BILLING_DATE DATE NOT NULL
! TIME_BEFORE_PMT INTERVAL DAY(3) NOT NULL
! Variable declarations:
EXEC SQL BEGIN DECLARE SECTION;
...
STRUCT .billings;
BEGIN
STRING custnum[0:3];
STRING start^date[0:9];
STRING billing^date[0:9];
STRING time^before^pmt[0:3]; ! An extra byte is used
! for a possible sign
END;
EXEC SQL END DECLARE SECTION;
...

HP NonStop SQL Programming Manual for TAL—527887-001


3- 26
NonStop SQL Statements and Directives INVOKE

The statements to supply values for the columns are:


billings.billing^date ':='"1988-10-20";
billings.time^before^pmt ':=' "120";
...
EXEC SQL
INSERT INTO billings VALUES
("923", DATE "1985-10-15",
:billing^date TYPE AS DATE,
:time^before^pmt TYPE AS INTERVAL DAY(3) );
...

Using Indicator Variables for Null Values


INVOKE generates indicator variables of TAL type INT for each host variable that
corresponds to a column that can be null. The format of the indicator variable is the
name of the corresponding column, plus a prefix and or suffix, if you specify one.
For example, if the column name is RETIRE^DATE, the format of the indicator variable
is RETIRE^DATE^I. You can specify a suffix other than the ^I provided by SQL by
supplying a SUFFIX clause with the INVOKE statement. You can replace the suffix with
a prefix of your choosing by specifying the PREFIX clause. Examples appear on page
3-29.
If you specify NULL STRUCTURE, INVOKE produces a substructure that contains the
indicator variable and the column. For more information about the NULL STRUCTURE
clause, see Using the NULL STRUCTURE Clause on page 3-28.

Note. If a column name is 30 or 31 characters long and the default indicator suffix ^I is used,
the ^I is truncated, and the indicator variable name is identical to the corresponding host
variable name. To prevent this error, specify the PREFIX or NULL STRUCTURE clause when
column names are 30 or 31 characters long.

For a column allows a null value, the INVOKE directive generates an indicator variable
that your program can use to specify whether or not a column value is null. In this
example, INVOKE generates a structure for a table definition that allows null values in
the FIRST^NAME and RETIRE^DATE columns. The generated structure type includes
indicator variables with the default suffix ^I for FIRST^NAME and RETIRE^DATE.
The INVOKE directive as it appears in the TAL source program is:
EXEC SQL BEGIN DECLARE SECTION;
EXEC SQL INVOKE emptbl AS emptbl^rec;
EXEC SQL END DECLARE SECTION;
The CREATE TABLE statement that defines the table is:
CREATE TABLE emptbl
( empnum NUMERIC (4) UNSIGNED NO DEFAULT NOT NULL,
first^name CHARACTER(15),

HP NonStop SQL Programming Manual for TAL—527887-001


3- 27
NonStop SQL Statements and Directives INVOKE

last^name CHARACTER(20) NO DEFAULT NOT NULL,


retire^date DATETIME YEAR TO DAY,
PRIMARY KEY empnum
)
CATALOG \sys.$vol.testcat ;
The compiler generates this structure template:
! Record Definition for table \SYS.$VOL.SUBVOL.EMPTBL
! Definition current at 16:06:49 - 05/17/90
STRUCT emptbl^rec (*);
BEGIN
INT empnum /SMALLINT UNSIGNED/;
INT first^name^i;
STRING first^name[0:14];
STRING last^name[0:19];
INT retire^date^i;
STRING retire^date[0:9];
END;

Using the NULL STRUCTURE Clause


This example uses the NULL STRUCTURE clause, which causes columns that contain
null values to be defined as structures. The NULL STRUCTURE clause assigns the
name INDICATOR to all indicator variables in the structure template.
The INVOKE directive with the NULL STRUCTURE clause:
EXEC SQL BEGIN DECLARE SECTION;
EXEC SQL INVOKE emptbl AS emptbl^rec NULL STRUCTURE;
EXEC SQL END DECLARE SECTION;
NonStop SQL generates this structure template:
! Record Definition for table \SYS.$VOL.SUBVOL.EMPTBL
! Definition current at 16:07:00 - 05/17/90
STRUCT emptbl^rec (*);
BEGIN
INT empnum /SMALLINT UNSIGNED/;
STRUCT first^name;
BEGIN
INT indicator;
STRING valu[0:14];
END;
STRING last^name[0:19];
STRUCT retire^date;
BEGIN
INT indicator;
STRING valu[0:9];
END;
END;

HP NonStop SQL Programming Manual for TAL—527887-001


3- 28
NonStop SQL Statements and Directives OPEN

Using the PREFIX and SUFFIX Clauses


This example specifies both a prefix and a suffix for indicator variables. The indicator
variables generated are X^ZNUM^2 and X^ZCHAR^2.
The CREATE TABLE statement that defines table TAB is:
CREATE TABLE tab
( znum NUMERIC (6),
zchar CHARACTER(16),
PRIMARY KEY znum
)
CATALOG \sys.$vol.testcat ;
The INVOKE directive with the PREFIX and SUFFIX clauses is:
EXEC SQL BEGIN DECLARE SECTION;
EXEC SQL INVOKE tab PREFIX x^ SUFFIX ^2;
EXEC SQL END DECLARE SECTION;
NonStop SQL generates this structure template:
! Record Definition for table \SYS.$DB.XPERSNL.TAB
! Definition current at 15:32:39 - 09/22/89
STRUCT tab^type (*);
BEGIN
INT x^znum^2; ! indicator variable name
INT(32) znum;
INT x^zchar^2; ! indicator variable name
STRING zchar[0:15];
END;

OPEN
The OPEN statement opens a cursor.
At run time, the OPEN statement for a cursor must execute before all FETCH
statements for the cursor. Any host variables used in a DECLARE CURSOR statement
must be in the same scope for each OPEN statement for the cursor.

Determining the Scope of a Cursor After an OPEN Statement


A static SQL cursor can only be used in the procedures in the compilation unit where
the cursor is declared. Thus, for static SQL operations, the DECLARE CURSOR,
OPEN, FETCH, DELETE WHERE CURRENT, UPDATE WHERE CURRENT, and
CLOSE statements that refer to the cursor must be in the same compilation unit.
If the program exits a procedure with an open cursor, procedures that execute later can
still refer to the cursor, provided the procedures are in the same compilation unit.
For a dynamic SQL cursor, all statements referring to the cursor must appear in the
procedure where the cursor is declared; however, if you open the cursor and use it in

HP NonStop SQL Programming Manual for TAL—527887-001


3- 29
NonStop SQL Statements and Directives PREPARE

one call to the procedure where it is declared, you can still use the cursor in
subsequent calls without opening the cursor again.
This example shows the OPEN statement in a typical sequence of statements that use
a cursor.
EXEC SQL
DECLARE check_emp CURSOR FOR ! Declare the cursor.
SELECT deptnum
FROM employee
WHERE deptnum = :deptnum^del
FOR UPDATE OF deptnum ;
...
! get a value for :deptnum^del.
EXEC SQL
OPEN check_emp ; ! Open the cursor.
! FETCH rows until the NOT FOUND condition is met.
WHILE SQLCODE >= 100 DO
BEGIN
EXEC SQL
FETCH check_emp ! FETCH a value.
INTO :deptnum ;
! Delete a row that matches the criteria.
...
END
EXEC SQL
CLOSE check_emp ; ! Close the cursor.

PREPARE
The PREPARE statement dynamically compiles an SQL statement. PREPARE
associates a statement name or host variable name with an SQL statement, which
resides as a string literal in the host variable.
If the PREPARE statement completes without an error, you can execute the statement
by specifying the statement or host variable name in an EXECUTE (or EXECUTE
IMMEDIATE) statement. After a successful completion, the SQL statement is called a
prepared statement. If the PREPARE statement fails, an attempt to execute the
statement fails.
For a prepared SELECT statement, a program defines a cursor with a dynamic
DECLARE CURSOR statement, and then uses dynamic OPEN, FETCH, and CLOSE
statements to retrieve rows.

HP NonStop SQL Programming Manual for TAL—527887-001


3- 30
NonStop SQL Statements and Directives RELEASE

Follow these guidelines when you use the PREPARE statement:


• A prepared statement is associated only with the program that executes the
PREPARE statement. Only that program can execute the prepared statement.
• The prepared statement remains available for execution until one of the following
events occur:

° The current process terminates

° A statement with the same name (either specified as a literal or with a

° statement host variable) is prepared again

° The statement name is successfully released with a RELEASE statement


• If a statement is prepared again, the previously compiled statement is released at
the beginning of the second prepare operation and the original statement is not
available if the second prepare operation fails.
The PREPARE statement must appear in the same procedure as the DESCRIBE
INPUT and DESCRIBE statements, the RELEASE statement, and the EXECUTE or
cursor statements (DECLARE CURSOR, OPEN, FETCH, DELETE WHERE
CURRENT, UPDATE WHERE CURRENT, and CLOSE) that are used to execute the
SQL input statement.

Using Statistics Information


If a program declares an SQLSA structure and the PREPARE statement completes
without any errors, NonStop SQL returns compilation statistics to the SQLSA structure.
These statistics include information needed by the program to build the SQLDA
structures for subsequent DESCRIBE and EXECUTE statements. For more
information about the SQLSA and SQLDA structures, see Section 6, Error and Status
Processing.

RELEASE
The RELEASE statement deallocates space for a dynamic SQL statement that is
prepared from a host variable.
The RELEASE statement must appear in the same procedure as the PREPARE
statement, the DESCRIBE INPUT and DESCRIBE statements, and the EXECUTE or
cursor statements (DECLARE CURSOR, OPEN, FETCH, CLOSE) that are used to
execute the SQL statement.

SELECT
The SELECT statement typically retrieves data from one or more tables and views into
host variables. There are two types of SELECT statements that you can use in a
program:

HP NonStop SQL Programming Manual for TAL—527887-001


3- 31
NonStop SQL Statements and Directives SELECT

• A single-row SELECT returns a single row or value.


• A multi-row SELECT returns multiple rows one row at a time.
To execute a SELECT statement, a TAL program's process accessor ID (PAID) must
have read access to all protection views, tables, and underlying tables of all shorthand
views referred to in the statement.
In general, specifying a select operation programmatically in a TAL program is the
same as specifying an select operation using SQLCI commands. With SQLCI, you
specify the desired values in an SELECT statement, while in a program, you set one or
more host variables to the desired values and then use the host variables in the
SELECT statement.

Executing a Single-Row SELECT Statement


A single-row select statement returns a single row to the program. The INTO clause
returns the single-row to one or more host variables. The row is identified in a WHERE
clause by a unique key value or a unique value of a column in the row.
Using a Value of a Column. This example shows a SELECT statement that returns
only one row based on unique value of a column in the row (a non-key value). This
example retrieves a customer’s name and address. Each customer is identified by a
unique number so that only one customer can satisfy this query. This example:
• Assumes that a user enters a customer number to retrieve the customer’s name
and address.
• Declares the host variable :FIND^THIS^CUSTOMER to hold the value of the
customer number whose address is requested (set to 5635 in the example, but
would be entered by a user in an actual program).
• Declares other host variables for the returned column values.
• Uses a WHERE clause to specify that the column CUSTOMER.CUSTNUM
contains a unique value that is equal to the value of a host variable
:FIND^THIS^CUSTOMER.
• Uses an INTO clause to return the single-row to the host variables.
• Uses BROWSE ACCESS because it does not modify the data, does not want to
wait for locked data, and does not care if it reads uncommitted data.
• Uses the NOT FOUND condition of the WHENEVER directive to direct control to a
recovery routine (not shown here) if the customer number is not found.
When the SELECT statement is executed, the system scans the database to find the
first row with the specified value in CUSTOMER.CUSTNUM. When found, this specific
row is returned to the program. Because CUSTOMER.CUSTNUM is not a primary key,
the program then reads the rest of the table to make sure the row it found is the only
qualifying row; if it is not, the program returns an error.

HP NonStop SQL Programming Manual for TAL—527887-001


3- 32
NonStop SQL Statements and Directives SELECT

EXEC SQL BEGIN DECLARE SECTION; ! Variable declarations


STRUCT customer^type;
BEGIN
INT custnum;
STRING custname[0:17];
STRING street[0:21];
STRING city[0:13];
STRING state[0:11];
STRING postcode[0:9];
END;
STRUCT .customer(customer^type);
INT find^this^customer;
EXEC SQL END DECLARE SECTION;
PROC handle^not^found; FORWARD;
EXEC SQL WHENEVER NOT FOUND CALL :handle^not^found;
...
PROC find^record;
BEGIN
find^this^customer := 5635;
EXEC SQL
SELECT custname, street, city, state, postcode
INTO :customer.custname,:customer.street,:customer.city,
:customer.state, :customer.postcode
FROM sales.customer
WHERE customer.custnum = :find^this^customer
BROWSE ACCESS;
... ! Print values in host variables
END; ! end of find^record
PROC driver MAIN;
BEGIN
CALL find^record;
END;
...
Using a Primary Key Value. This example shows a SELECT statement that selects a
row using a primary key column.
EXEC SQL
SELECT column2,
column3,
column4
INTO :host^var2,
:host^var3,
:host^var4
FROM mytable
WHERE column1 = :host^varkey ;
In this example, the WHERE clause specifies that the selected row contains a primary
key, COLUMN1, whose value is equal to the value of a specified host variable. Only
one row is retrieved from the table because a unique primary key value is used for the
selection.

HP NonStop SQL Programming Manual for TAL—527887-001


3- 33
NonStop SQL Statements and Directives SELECT

Executing a Multi-Row SELECT Statement


A multi-row SELECT statement returns multiple rows one row at a time. Because host
variables cannot hold more than the first row, you must declare this type of SELECT
statement as a cursor.
A cursor is the mechanism for dealing with a set of rows returned in sequence to a
program. To use a cursor, you use the DECLARE CURSOR, OPEN, FETCH, and
CLOSE statements as shown in these steps. These steps are required even when only
the next single row is needed and only one FETCH is done.
1. Name and define a cursor in a DECLARE CURSOR statement. The DECLARE
CURSOR statement includes a SELECT statement to describe the rows to be
returned.
Initialize any host variables used in the WHERE clause of the cursor declaration.
Once the cursor is declared and the values initialized, you can open the cursor and
fetch each selected row sequentially.
2. Open the cursor using the OPEN statement.
3. Fetch each selected row into the program with the FETCH statement.
4. Close the cursor with the CLOSE statement.
This example shows a cursor SELECT for a cursor named LISTNEXT:
EXEC SQL
DECLARE listnext CURSOR FOR
SELECT column1,
column2,
column3
FROM table
WHERE column1 > :host^var^key ;
...
! Move the initial value to :host^var^key
EXEC SQL
OPEN listnext ;
EXEC SQL
FETCH listnext
INTO :host^var1,
:host^var2,
:host^var3 ;
EXEC SQL
CLOSE listnext ;
A row is returned each time the FETCH statement is executed. This example retrieves
all the rows with COLUMN1 values greater than the :HOST^VAR^VKEY value.

HP NonStop SQL Programming Manual for TAL—527887-001


3- 34
NonStop SQL Statements and Directives SQL

When to Initialize a Cursor. Opening a cursor causes the set of rows in the query
result to be defined and ordered. If a cursor SELECT statement contains host variables
in its WHERE clause, you must initialize the values of the host variables either before
you open the cursor with an OPEN statement or else in the USING clause of the
OPEN statement.
The SQL executor places the input variables into its buffers when it opens the cursor. If
you do not initialize the variables before the OPEN statement, several things can
happen:
• If the variables contain values that do not conform to the data type expected,
overflow or truncation errors can result when the cursor is opened.
• If the variables are of the expected type but they contain values left from a previous
usage of the program, these bad values are used as a starting point for
subsequent FETCH operations. As a result, the returned rows do not begin at the
expected location.
When to Close a Cursor. Only an explicit CLOSE statement or a FREE RESOURCES
statement closes an open cursor. As a general rule, you can leave cursors open to
save the overhead of reopening a cursor you plan to use again. In some cases,
however, you should explicitly close open cursors. In particular, when you use cursors
in PATHWAY applications, you should follow these rules:
1. Close any open cursors before returning control to a requester.
2. If your program is a server and a TMF transaction was started in a requester, close
any cursors to release space used by the cursors and to free locks before returning
control to the requester.

SQL
The SQL TAL compiler directive causes the TAL compiler to process subsequent SQL
statements and directives. Put the SQL directive in the first line of the primary source
file or in the command line when you run the TAL compiler.

SQL [ option ]
[ ( option [ , option ] ... ) ]

option is:

[ PAGES num-pages ]

[ WHENEVERLIST | NOWHENEVERLIST ]

[ RELEASE1 | RELEASE2 ]

[ SQLMAP | NOSQLMAP ]

HP NonStop SQL Programming Manual for TAL—527887-001


3- 35
NonStop SQL Statements and Directives SQL

PAGES num-pages
specifies the number of 2048-byte pages of memory available to the TAL compiler
to process SQL statements. The default is 384 pages, which is the minimum
number required and a usable value for most programs.
A recommended upper limit is 32,000. The actual upper limit depends on space
allocated by the compiler and a value specified by the SYMBOLPAGES directive.
By increasing the value, you increase the number of lines allowed in an SQL
statement.

WHENEVERLIST | NOWHENEVERLIST
controls writing active WHENEVER options to the listing file after each SQL
statement is processed.

WHENEVERLIST
specifies writing the options.

NOWHENEVERLIST
WHENEVER options are not written. NOWHENEVERLIST is the default.

RELEASE1 | RELEASE2
specifies the NonStop SQL release version that supports the program. This release
option affects the version of the SQLDA structures generated for the application
and internally marks the object program as RELEASE1 or RELEASE2.

RELEASE1
specifies object code and SQLDA structures that are compatible with the
NonStop SQL C10 compiler. If you specify RELEASE1, the program can be
SQL compiled and run on a C10 or C30 system. You can use RELEASE1 to
develop programs on a C30 system that will run on a C10 system.
The SQLDA structure, however, does not support null values or the C30 SQL
data types: FLOAT, DOUBLE PRECISION, REAL, DATETIME, DATE, TIME,
TIMESTAMP, and INTERVAL.
If you compile the program with a NonStop SQL C10 compiler, the SQL
compiler rejects C30 features. For detailed information on RELEASE2 features
and using the release version options, see Appendix D, NonStop SQL Version
Issues.

RELEASE2
specifies object code and SQLDA structures that are compatible with the
NonStop SQL C30 compiler. A program compiled with RELEASE2 cannot be
SQL compiled or run on a NonStop SQL C10 system. RELEASE2 is the
default.

HP NonStop SQL Programming Manual for TAL—527887-001


3- 36
NonStop SQL Statements and Directives SQLMEM

SQLMAP | NOSQLMAP
specifies whether the compiler listing includes an SQL map. This map enables you
to determine SQL statements using output from the Measure program.

SQLMAP
causes an SQL map to be added at the end of the compiler listing. An SQL
map is a table that contains the:
• Run-time data unit (RTDU) name in the format:
• _SQLRTDU_ julian-timestamp
• Section location table (SLT) index number
• Source file name
• Source file line number
The table is sorted first by RTDU name and then by SLT index number. You
can use this table to correlate Measure output with the SQL statement.
The global RTDU contains the cursors and CONTROL directives that are
declared in the global declarations.

NOSQLMAP
causes the SQL map not to be added. NOSQLMAP is the default.

SQLMEM
The SQLMEM TAL compiler directive specifies where in memory the TAL compiler
places the SQLIN, SQLIVARS, and SQLOVARS SQL data structures. These data
structures, which describe SQL statements and host variables, are passed to the SQL
executor at run time. Although your program does not explicitly declare these
structures and cannot directly access them, you can control their placement in
memory.
Table 3-3 shows the internal data structures and when each structure is generated.

HP NonStop SQL Programming Manual for TAL—527887-001


3- 37
NonStop SQL Statements and Directives SQLMEM

Table 3-3. NonStop SQL Data Structures


SQL Data Structure Generated For Each:
SQLIN SQL statement or directive except::

• BEGIN DECLARE SECTION and END DECLARE


SECTION directives
• CONTROL directives
• INCLUDE directive
• INVOKE directive
• WHENEVER directive
• DECLARE CURSOR statement for static cursors
• DECLARE CURSOR statement for dynamic cursors
that do not use cursor or statement host variables
SQLIVARS SQL statement that has input host variables
SQLOVARS SQL statement that has output host variables

The SQLMEM directive has this syntax:

SQLMEM { USER }
{ EXT }
{ STACK }
{ MAPPED address length }

USER
causes the TAL compiler to place the SQL data structures in the global area, which
is addressable with 16 bits. Specify USER only if the global area can hold all of the
SQL data structures.

EXT
causes the TAL compiler to place the SQL data structures in the automatic
extended segment. The extended segment is the default if you do not specify the
SQLMEM directive.
If your program uses the EXT option, SQL statements can access data only in the
default extended segment. If your program uses the EXT option and manages
extended segments with the USESEGMENT procedure, you must ensure that the
default extended segment is always visible when SQL statements are executed.
If you need to access data in another extended segment, you can copy the data
needed by the SQL statements to the global area of the user data stack or to the
default extended segment before executing the SQL statement. However, use this
technique carefully, because data is not always accessed when you might expect.

HP NonStop SQL Programming Manual for TAL—527887-001


3- 38
NonStop SQL Statements and Directives SQLMEM

For example, a host variable used in a DECLARE CURSOR statement is not


accessed when the DECLARE CURSOR statement is processed; it is accessed
when the cursor is opened.

STACK
places the SQL data structures in the default extended segment only initially. Before an
SQL statement executes, the system allocates space at the top of the stack and issues
a MOVEX procedure call to copy the SQL data structures needed for that statement to
the top of the stack. After each SQL statement executes, the system deallocates the
top of the stack.
The STACK option allows you to have any extended segment active at the time an
SQL statement executes, because the MOVEX procedure can copy data from inactive
segments. In programs that are close to using all their stack space, however, using the
STACK option can cause a stack overflow because extra stack space must be used to
temporarily hold the SQL data structures.
When an error is returned from a generated call to the MOVEX procedure, the TAL
compiler sets SQLCODE to 254. If an SQLCA structure is present, NonStop SQL also
sets this error in the SQLCA.
The STACK option cannot appear in a subprocedure.

MAPPED address length


places the SQL data structures in the default extended segment only initially. Before
each SQL statement, the system calls the MOVEX procedure to copy the SQL data
structures to a location in memory you specify in the currently active extended
segment. Because moving data between segments is slower than moving data to the
stack, the MAPPED option can degrade system performance.
To use the MAPPED option, your SOURCE directive for
$SYSTEM.SYSTEM.EXTDECS must specify the MOVEX and USESEGMENT
procedures.
Use the MAPPED option if your program manages extended segments with the
USESEGMENT procedure and does one of these:
• Does not use the default extended segment
• Contains SQL statements that refer to host variables located in a segment other
than the default extended segment and you do not have enough memory available
in the data stack to select the USER or STACK option.

address
is the address in the current extended segment where you want the compiler to
place the data structures. This address can be a constant, literal, or variable
string (data type STRING .EXT). When you use a variable or literal, the
compiler evaluates the name in the same scope as the SQL statement being
compiled, and not where the SQLMEM directive appears.

HP NonStop SQL Programming Manual for TAL—527887-001


3- 39
NonStop SQL Statements and Directives SQLMEM

length
is the number of bytes that are available at address for the data structures.
This length should be large enough to hold the largest SQL statement
description expected in your program (that is, the sum in bytes of the SQLIN,
SQLIVARS, and SQLOVARS structures).
The value cannot exceed 65,536.
You can use a constant or a literal for length. When you use a literal, the
compiler evaluates the name as for address, in the same scope as the SQL
statement being compiled.
Follow these steps to estimate a value for length:
1. Compile the program with a high value. Use the information under
Estimating Sizes for SQLIN and SQLVARS on page 3-41 to estimate the
value.
2. Check the compiler listing. When SQLMEM MAPPED is specified, the
listing shows the total size needed to store the SQL data structures for
each SQL statement by printing the this message after each SQL
statement:
SQLMEM: MOVEX length = movex-length.
The maximum size needed is also computed and printed at the end of the
listing with the message:
SQLMEM: Maximum MOVEX length = maximum-length.
If length is too small, the compiler generates an error.
3. If necessary, change the length to a value at least equal to the maximum
MOVEX length as shown at the end of the listing.

Ensuring That SQL Data Structures Are Accessible


The following data structures must be accessible in the active extended segment
whenever your program executes an SQL statement:
• SQLIN for the specific statement
• SQLIVARS and SQLOVARS (together called SQLVARS) for the input and output
host variables in the statement. The host variables themselves must also be
accessible. For a static OPEN, any host variables referenced in the DECLARE
CURSOR statement must also be accessible.
• SQLCA structure for error handling
• SQLSA structure for statistics and dynamic SQL
The SQLCA and SQLSA structures are always allocated on the standard data stack.
SQLIN and SQLVARS are allocated by default in the default extended segment, or by
the programmer using SQLMEM.
HP NonStop SQL Programming Manual for TAL—527887-001
3- 40
NonStop SQL Statements and Directives SQLMEM

Estimating Sizes for SQLIN and SQLVARS


The size estimates for the SQL data structures are:
Structure Size, Bytes
SQLCA 430 (approximate)
SQLSA 838 (approximate)
SQLIN 72

To estimate the size of the SQLIVARS and SQLOVARS structures, use this formula:
size = (4 + 24 * n ) bytes
where n is the number of host variables. For example, for the statement:
SELECT * FROM table WHERE col1 = :a AND col2 = :b ;
where TABLE has 200 columns, you would need 4804 bytes to store the SQLOVARS
structure for the host variables to receive the column values, plus 52 bytes to store the
SQLIVARS structure for the host variables to supply values for the WHERE clause.

Using Shared Memory


If you are using shared memory, consider these items, which apply to any shared
memory situation in TAL:
• If two or more programs use the same data area for SQL data structures, you must
protect each SQL statement from concurrent execution of other SQL statements.
To avoid this situation, use different areas of memory for each program or
synchronize access to the shared segment.
• If you place the SQL data structures in a read-only data segment, obscure errors
can occur as a result of interactions with the operating system.

Recommendations
For various programming environments follow these general guidelines. Specific
programs, however, might require different analysis and methods.
• If your program does not need to manage extended segments, omit SQLMEM and
allow the compiler to place the SQLIN and SQLVARS structures in the default
extended segment. If your program has few SQL statements, the statements are
small, and you do not expect to add statements, use SQLMEM USER.
• If your program was written before the availability of the default extended segment
and the program manages its own extended segments with the
ALLOCATESEGMENT and USESEGMENT procedures, use one of these choices
(listed in order of preference):
° Specify the USER option if your program has a small number of SQL
statements, the statements reference a small number of host variables, and
you do not expect to add statements.
HP NonStop SQL Programming Manual for TAL—527887-001
3- 41
NonStop SQL Statements and Directives SYMBOLPAGES

° Specify the STACK option to allow TAL to create a default extended segment
for initial placement of the data structures.

° Convert the program to use the default extended segment and specify the EXT
option (or allow EXT to be the default). For some programs, the MAPPED
option might be simpler to implement than to convert the program.

° Specify the MAPPED option. As for the STACK option, TAL creates a default
extended segment to store the data structures initially.
• If your program uses the default extended segment and also manages additional
extended segments, use SQLMEM based on your specific environment and the
guidelines in this section.
• Because memory allocation can change in various parts of a program, you might
need to specify SQLMEM more than once.

SYMBOLPAGES
The SYMBOLPAGES TAL compiler directive specifies the number of 2048-byte pages
that the TAL compiler allocates for the symbol table. The TAL compiler uses the symbol
table as a temporary storage area in memory for processing variables.
The syntax for SYMBOLPAGES is:

SYMBOLPAGES num-pages

num-pages
specifies the number of pages that the TAL compiler should allocate for the symbol
table in the automatic extended data segment. The range is 512 through 32767
pages. The default is 512 pages.
If a symbol table overflow occurs, the TAL compiler displays error 57 (symbol table
overflow). Use SYMBOLPAGES to enlarge the size of the table.
To specify the SYMBOLPAGES directive, you must issue the directive on the
command line for the TAL compiler when you compile a program. For example:
TAL /IN tsrc, OUT $s.#tlst, NOWAIT/ tobj; SYMBOLPAGES 4096

UPDATE
The UPDATE statement updates values in one or more columns in a row or set of rows
of a table or a protection view. The number of rows is determined by the WHERE
clause. An UPDATE statement can update:
• A single row
• A set of rows

HP NonStop SQL Programming Manual for TAL—527887-001


3- 42
NonStop SQL Statements and Directives UPDATE

• A set of rows, one row at a time using a cursor (a mechanism for dealing with a set
of rows returned in sequence to a program)
A lock on an updated row is held until the TMF transaction is committed or rolled back
(audited table) or until the program releases the lock (nonaudited table).
To execute an UPDATE statement, a program's process accessor ID (PAID) must have
read and write access to the table or view being updated. A program's PAID must also
have read access to any table or view specified in subqueries of the search condition.
In general, specifying an update operation programmatically in a TAL program is the
same as specifying an update operation using SQLCI commands. With SQLCI, you
specify the new values in an UPDATE statement, while in a program, you set one or
more host variables to the new values and then use the host variables in the UPDATE
statement.
The UPDATE statement updates rows in sequence. If an error occurs, NonStop SQL
returns an error code to the SQLCODE variable and terminates the operation. This
table shows the SQLCODE values that NonStop SQL returns after an UPDATE
statement.
SQLCODE Value Description
0 The UPDATE statement was successful.
100 No rows were found for a search condition.
<0 An error occurred; SQLCODE contains the error number.
>0 (not 100) A warning occurred; SQLCODE contains the first warning number.

The SQLCA structure contains the number of rows updated. To obtain the contents of
the SQLCA, use the SQLCADISPLAY or SQLCATOBUFFER procedure.

Updating a Single Row


A single-row update operation updates a single row in a table. This example updates a
single row of the ORDERS table that contains information about order number 200038.
This example declares the host variables :ORDERS and :NEWDATE, which serve as
input variables in the UPDATE statement. (In a program, a user enters values for
:ORDERS and :NEWDATE; in the example, they are set using assignment
statements.)
! Variable declarations:
EXEC SQL BEGIN DECLARE SECTION;
STRUCT .orders;
BEGIN
INT(32) ordernum;
STRING orderdate[0:9];
STRING deliv^date[0:9];
INT salesrep;
INT custnum;
END;
string newdate[0:9];

HP NonStop SQL Programming Manual for TAL—527887-001


3- 43
NonStop SQL Statements and Directives UPDATE

EXEC SQL END DECLARE SECTION;


...
! Procedure code:
PROC update^orders;
BEGIN ...
newdate ':=' "1987-05-22";
orders.ordernum := 200038;
EXEC SQL
UPDATE orders
SET deliv^date = :newdate TYPE AS DATE
WHERE ordernum = :orders.ordernum
STABLE ACCESS;
END;
...

Updating Multiple Rows Using a Single UPDATE Statement


Multi-row operations (sometimes called set operations) are performed on one or more
rows by a single SQL statement. These operations provide maximum efficiency in both
coding and execution. Use set operations wherever possible for updating sets of rows.
However, sometimes, you must check a row before updating it. In this case, you must
use cursors as described under Using a Cursor to Update Multiple Rows on page 3-44.
The following single statement updates the SALARY column of every row in the
EMPLOYEE table where the current value of the SALARY column is less than the
value of the host variable :HOSTVAR^MIN^SALARY. (A user enters values for
:HOSTVAR^INC and :HOSTVAR^MIN^SALARY.)
EXEC SQL
UPDATE employee
SET salary = salary * :hostvar^inc
WHERE salary < :hostvar^min^salary ;
This example updates all rows in the DEPTNUM column that contain the value in the
:HOSTVAR^OLD^DEPTNUM host variable. Effectively, all employees who were
previously in department 100 are now in department 200. (A user enters values for
:HOSTVAR^OLD^DEPTNUM and :HOSTVAR^NEW^DEPTNUM.)
EXEC SQL
UPDATE employee
SET deptnum = :hostvar^new^deptnum
WHERE deptnum = :hostvar^old^deptnum ;

Using a Cursor to Update Multiple Rows


To read and test each value before you update it, you must use a cursor. A cursor
allows you to update a set of rows one row at a time. You specify the set of rows with
the SELECT clause in the DECLARE CURSOR statement. You read each row using a
FETCH statement, test the data, and then ignore or update the row depending on your
test logic.

HP NonStop SQL Programming Manual for TAL—527887-001


3- 44
NonStop SQL Statements and Directives UPDATE

When you use a cursor to select rows for subsequent update, you must use the FOR
UPDATE OF clause in the cursor declaration. If you determine you want to update the
data, you use a WHERE CURRENT OF clause to update the row from the table.

Note. Do not use a stand-alone UPDATE operation to update a row that has been retrieved
using a cursor FETCH operation. This can invalidate the cursor's buffering for the table and
might degrade performance.

For audited tables and views, a TMF transaction must be in progress. The same TMF
transaction must include the OPEN, FETCH, and UPDATE operations.
This example declares a cursor, fetches and tests the data, then updates the row:
EXEC SQL
DECLARE check_emp CURSOR FOR
SELECT deptnum
FROM employee
WHERE deptnum = :deptnum^del
OR deptnum = :deptnum^upd
FOR UPDATE OF deptnum ;
EXEC SQL
FETCH check_emp
INTO :deptnum ;
! Program logic to test the data
...
EXEC SQL
UPDATE employee ! Update deptnum in current row
SET deptnum = :newdept
WHERE CURRENT OF check_emp ;
You can refer to a static SQL cursor only in the compilation unit where the cursor is
declared. Thus, for static SQL programs, the UPDATE WHERE CURRENT, DECLARE
CURSOR, OPEN, FETCH, and CLOSE statements that refer to the cursor must be in
the same compilation unit. If a program exits a procedure with an open cursor,
procedures that execute later can still refer to the cursor, provided the procedures are
in the same compilation unit.
For a dynamic SQL cursor, all statements referring to the cursor must appear in the
procedure where the cursor is defined. However, if you open the cursor and use it in a
call to the procedure where it is defined, you can still use the cursor in subsequent
calls without opening the cursor again.
This example uses a cursor to position in the PARTS table on the part number
specified by host variable STARTING^PARTNUM. The example can then fetch rows
and determine whether to update data in the columns. The row updated is at the
current position of the cursor GET_BY_PARTNUM_CURSOR.

HP NonStop SQL Programming Manual for TAL—527887-001


3- 45
NonStop SQL Statements and Directives UPDATE

The example uses the host variables :NEW^PARTDESC, :NEW^PRICE, and


:NEW^QTY and sets them to new values (entered by a user) for the columns before
executing the UPDATE statement.
EXEC SQL DECLARE get_by_partnum_cursor CURSOR FOR
SELECT partnum,
partdesc,
price,
qty_available
FROM sales.parts
WHERE (partnum >= :starting^partnum )
STABLE ACCESS
FOR UPDATE OF partdesc,
price,
qty_available;
...
! Declare host variables new^partdesc, new^price,and new^qty.
...
! Get one row from the PARTS table:
EXEC SQL FETCH get_by_partnum_cursor .... ;
...
! Determine whether this is a row to be updated
...
! If the row is to be updated, assign update values to
! new^partdesc, new^price, and new^qty. If necessary,
! update the row at the current cursor position.
EXEC SQL UPDATE sales.parts
SET partdesc = :new^partdesc,
price = :new^price,
qty_available = :new^qty
WHERE CURRENT OF get_by_partnum_cursor;

HP NonStop SQL Programming Manual for TAL—527887-001


3- 46
NonStop SQL Statements and Directives WHENEVER

Updating a Column With a Null Value


This example updates a column by setting the column to a null value using an indicator
variable. This example uses the TACL DEFINE name =EMPLOYEE for the
EMPLOYEE table.
! Variable declarations:
EXEC SQL BEGIN DECLARE SECTION;
EXEC SQL INVOKE =employee AS emp^tbl;
STRUCT .emp(emp^tbl);
INT ind^1;
EXEC SQL END DECLARE SECTION;
...
! Executable statements:
ind^1 := -1;
EXEC SQL
UPDATE =employee
SET salary =:emp.salary INDICATOR :ind^1
WHERE jobcode = :hostvar^jobcode;
This example uses the NULL keyword instead of an indicator variable:
EXEC SQL
UPDATE =employee SET salary = NULL
WHERE jobcode = :hostvar^jobcode;

WHENEVER
The WHENEVER directive specifies an action that a program takes depending on the
outcome of subsequent statements DML, DCL, and DDL SQL statements. For a
description of the WHENEVER directive, see Section 6, Error and Status Processing.

HP NonStop SQL Programming Manual for TAL—527887-001


3- 47
NonStop SQL Statements and Directives WHENEVER

HP NonStop SQL Programming Manual for TAL—527887-001


3- 48
4 System Procedures
Use the provided system library procedures, written in TAL, to perform various SQL
functions. The EXTDECS file contains source declarations for these procedures. Use
the SOURCE directive to specify the declarations in the EXTDECS file for the
procedures that you want to call in your program. For example, this directive specifies
declarations for the SQLCADISPLAY and SQLCAFSCODE procedures:
?SOURCE $SYSTEM.SYSTEM.EXTDECS ( SQLCADISPLAY,
? SQLCAFSCODE )
Table 4-1 describes the SQL system procedures by function. The procedures
beginning with SQL are described in this section. The FILEINQUIRE procedure is
described in the Guardian Procedure Calls Reference Manual.

Table 4-1. System Procedures for NonStop SQL Operations


Procedure Description
Displaying Errors and Warnings
SQLCADISPLAY Writes to a file or terminal the error and warning messages
that NonStop SQL returns to the program.
SQLCAFSCODE Returns information about file-system, disk-process, or
NonStop Kernel operating system errors returned to the
program.
SQLCAGETINFOLIST Writes to a record area in a program a subset (which you
specify) of the error or warning information in the SQLCA.
SQLCATOBUFFER Writes to a record area in the program the error or warning
messages that NonStop SQL returns to the program.
Displaying Execution Statistics
SQLSADISPLAY Writes to a file or terminal the execution statistics that
NonStop SQL returns to the program.
Retrieving Version Information
SQLGETCATALOGVERSION Returns a value that indicates the version of an SQL
catalog.
SQLGETOBJECTVERSION Returns a value that indicates the version of an SQL
objects (represents the oldest NonStop SQL release that
can perform all DML and most DDL operations for a given
SQL table, index, or view.)
SQLGETSYSTEMVERSION Returns a value that indicates the version of the NonStop
SQL file-system and disk-process components on a given
system.
Determining the Catalog for a Table, Index, or View
FILEINQUIRE (Guardian Returns information about a file. The input codes 13 and
procedure) 14 apply specifically to SQL objects.

HP NonStop SQL Programming Manual for TAL—527887-001


4-1
System Procedures Procedure Descriptions

Procedure Descriptions
The following SQL procedures are described in alphabetical order on subsequent
pages. Each description includes the syntax, parameter definitions, and guidelines.
• SQLCADISPLAY
• SQLCAFSCODE
• SQLCAGETINFOLIST
• SQLCATOBUFFER
• SQLGETCATALOGVERSION
• SQLGETOBJECTVERSION
• SQLGETSYSTEMVERSION
• SQLSADISPLAY

SQLCADISPLAY
The SQLCADISPLAY procedure displays information that NonStop SQL returns to the
SQLCA data structure. SQLCADISPLAY writes this information to a file or terminal.
NonStop SQL communicates errors, warnings, and statistics to a program through the
SQLCA. However, because the SQLCA contains information in a format that is not
suitable to display, you must call the SQLCADISPLAY procedure to convert this
information to a suitable format.
The SQLCA information can be from these subsystems or system components:
• NonStop SQL
• FASTSORT program (SORTPROG process)
• Sequential I/O (SIO) procedures
• File system
• NonStop Kernel operating system

HP NonStop SQL Programming Manual for TAL—527887-001


4-2
System Procedures SQLCADISPLAY

• Disk process (DP2)

CALL SQLCADISPLAY ( sqlca^ ! i


, [ output^file number ] ! i
, [ output^record^length ] ! i
, [ sql^msg^file^number ] ! i,o
, [ errors ] ! i
, [ warnings ] ! i
, [ statistics ] ! i
, [ caller^error^loc ] ! i
, [ internal^error^loc ] ! i
, [ prefix ] ! i
, [ prefix^length ] ! i
, [ suffix ] ! i
, [ suffix^length ] ! i
, [ detail^params ] ) ; ! i

sqlca^ input

INT .EXT
is a pointer to the SQLCA structure. The TAL compiler automatically declares the
SQLCA structure when you specify the INCLUDE SQLCA directive.

output^file^number input

INT
is the output file number. If you omit this value or set it to a negative value,
SQLCADISPLAY displays information at your home terminal. In this case,
SQLCADISPLAY opens your home terminal, displays the message, and then
closes your terminal. NonStop ignores this parameter if detail^params specifies
sequential I/O (SIO).

output^record^length input

INT
defines the length in bytes of records to be written to the output file. The length
must be an integer value from 60 through 600. The default length is 79 bytes.

sql^msg^file^number input/output

INT
is the file number of the SQLMSG file. If you specify –1 on input, the system opens
the SQLMSG file and returns the resulting file number. If you specify a value other
than –1, the system uses that value as the file number of the SQLMSG file.
To improve the performance of a program that makes multiple calls to the
SQLCADISPLAY (or SQLCATOBUFFER) procedure, specify a variable containing
–1 on the first call, and then use the returned file number for subsequent calls. By

HP NonStop SQL Programming Manual for TAL—527887-001


4-3
System Procedures SQLCADISPLAY

using the file number, the system opens the file only once and uses the file number
for subsequent calls; otherwise, the system opens the file for each call.

errors input

INT
controls the display of error messages. The values you can specify and their
meanings are:
N Display only the first error.
Y Display all errors.
B Display all errors but suppress this prefix:
ERROR from subsystem [nn]:
The default is Y.

warnings input

INT
controls the display of warning messages. The values you can specify and their
meanings are:
N Display no warning messages.
Y Display all warning messages.
B Display all warnings but suppress the prefix:
WARNING from subsytem [nn]:
The default is Y.

statistics input

INT
controls the display of statistics. The values you can specify and their meanings
are:
Y Display row and cost statistics if the value returned to the SQLCA in the ROW or
COST field is greater than or equal to 0.
R Display rows only.
C Display cost only.
N Display no statistics.
The default is Y.

HP NonStop SQL Programming Manual for TAL—527887-001


4-4
System Procedures SQLCADISPLAY

caller^error^loc input

INT
controls displaying the program name and line number of the SQL statement that
received the error. The values you can specify and their meanings are:
Y Enable the display of the information.
N Suppress the display of the information.
The default is Y.

internal^error^loc input

INT
controls displaying the location in system code where the first error in the SQLCA
structure occurred. The values you can specify and their meanings are:
Y Enable the display of the information.
N Suppress the display of the information.
The default is Y.

prefix input

STRING .EXT
specifies a string that the program uses to precede each output line.
The default is three asterisks and a space (*** ).

prefix^len input

INT
specifies the length of the prefix string to precede each output line. The length can
be an integer value from 1 through 15. If you include the prefix parameter, you
must also include this parameter. If you omit the prefix parameter, you must also
omit this parameter.

suffix input

STRING .EXT
specifies a string to be appended to each output line.
The default is a null string.

HP NonStop SQL Programming Manual for TAL—527887-001


4-5
System Procedures SQLCADISPLAY

suffix^len input

INT
specifies the length of the suffix string to append to each output line; the length can be
an integer value from 1 through 15. If you include the suffix parameter, you must also
include this parameter. If you omit the suffix parameter, you must also omit this
parameter.

detail^params input

INT .EXT
determines whether the program uses sequential SIO (SIO) or Enscribe I/O (which
is the default) for writing to the output file. The parameter DETAIL^PARAMS points
to a structure with this declaration:
STRUCT detail^params;
BEGIN
STRING sio;
INT .EXT out^fcb^1;
INT .EXT out^fcb^2 ;
END;

sio
specifies whether sequential I/O is used; sio can have these values:
Y Use sequential I/O; ignore output^file^number.
N Do not use sequential I/O; write to output^file^number.

outfcb1
specifies the first output file control block if sio is enabled.

outfcb2
specifies the second output file control block if sio is enabled. To use outfcb2,
assign it a value greater than 0.

Guidelines
Follow these guidelines when you call the SQLCADISPLAY procedure:
• NonStop SQL returns errors as negative numbers and warnings as positive
numbers.
• If there is no text for an error number, NonStop SQL displays:
No error text found.
The $SYSTEM.SYSTEM.SQLMSG file contains the error text for SQL messages. If
you receive this message, your version of the SQLMSG file might not match the
version of the SQL executor.

HP NonStop SQL Programming Manual for TAL—527887-001


4-6
System Procedures SQLCAFSCODE

• If the error text exceeds output^record^length, the output is wrapped at word


boundaries producing subsequent lines that are indented 5 spaces.
• The SQLCA can contain a maximum of 7 errors and 180 bytes of text of the actual
parameters returned to the program. Any information that exceeds these limits is
lost. SQLCADISPLAY prints a warning message that indicates when information is
lost.
A call statement to the SQLCADISPLAY procedure using all default parameters is:
CALL SQLCADISPLAY (SQLCA);
An example of diagnostic messages that SQLCADISPLAY might generate is:
*** WARNING from SQL [100]: Record not found or end of file
*** encountered on table \SYS1.$VOL1.SALES.ODETAIL.
*** SQLCA display of SQL statement at: SCAN.#201.1 process
\SYS1.$B
*** Error detected within SQL executor at: EXE^EXEC.#450
*** ERROR from SQL [-8408]: Division by zero occurred.
*** Statistics: Rows accessed/affected: 10
*** Estimated cost: 100

SQLCAFSCODE
The SQLCAFSCODE procedure returns either the first or the last error in the SQLCA
structure that was set by the file system, disk process, or NonStop Kernel operating
system. SQLCAFSCODE returns 0 if the requested error does not exist.

error := SQLCAFSCODE ( sqlca^ ! i


, [ first^flg ] ) ; ! i

error returned value

INT
returns the requested error. Zero (0) indicates this error does not exist.

sqlca^ input

INT .EXT
is a pointer to the SQLCA structure. The TAL compiler automatically declares the
SQLCA structure when you specify the INCLUDE SQLCA directive.

HP NonStop SQL Programming Manual for TAL—527887-001


4-7
System Procedures SQLCAGETINFOLIST

first^flg input

INT
specifies whether the first or the last error is set in the SQLCA. You can set first^flg
as follows:
Nonzero value (or omitted) First error
0 Last error

Guidelines
Follow these guidelines when you call the SQLCAFSCODE procedure:
• If the SQLCA is full when a file-system error occurs, the error is lost and cannot be
returned by SQLCAFSCODE.
• Use SQLCAFSCODE to get the Guardian or file-system error code that occurs for
an SQL operation. You can then determine the action your program should take,
depending on this error rather than on the SQL error.
This example shows a call to the SQLCAFSCODE procedure:
INT fserr; !Guardian 90 or file-system error
EXEC SQL INCLUDE SQLCA;
...
fserr := SQLCAFSCODE (sqlca);
! Check fserr to determine the error
...

SQLCAGETINFOLIST
The SQLCAGETINFOLIST procedure returns error or warning information that
NonStop SQL sets in the SQLCA structure. You specify a list of numbers, called item
codes, to select this information, and then SQLCAGETINFOLIST returns the
information to a structure you define. By using item codes, you can specify the exact
information you want SQLCAGETINFOLIST to return.
This information can be from these subsystems or system components:
• NonStop SQL
• FASTSORT program (SORTPROG process)
• Sequential I/O (SIO) procedures
• File system
• NonStop Kernel operating system

HP NonStop SQL Programming Manual for TAL—527887-001


4-8
System Procedures SQLCAGETINFOLIST

• Disk process (DP2)

error := SQLCAGETINFOLIST ( sqlca^ ! i


, itemlist ! i
, numberitems ! i
, result ! o
, resultmax ! i
, [ errorindex ] ! i
, [ namesmax ] ! i
, [ paramsmax ] ! i
, [ resultlen ] ! o
, [ erroritem ] ) ; ! o

error returned value

INT
returns the outcome of the operation. Zero (0) indicates a successful operation.
For more information on the description of other return values, see Table 4-3 on
page 4-12.

sqlca^ input

INT .EXT
is a pointer to the SQLCA structure. The TAL compiler automatically declares the
SQLCA structure when you specify the INCLUDE SQLCA directive.

itemlist input

INT .EXT
is an array of item codes that describes the information you want returned in the
result structure. For more information on the list of these codes, see Table 4-2 on
page 4-11.

numberitems input

INT
is the number of items you specified in the itemlist array.

result output

INT .EXT
is a structure you define to receive the requested information. The items are
returned in the order you specified in itemlist. Each item is aligned on a word
boundary.

HP NonStop SQL Programming Manual for TAL—527887-001


4-9
System Procedures SQLCAGETINFOLIST

resultmax input

INT
is the maximum size, in bytes, of the result structure.

errorindex input

INT
is the index of the SQLCA error or warning entry.
The SQLCA has a fixed set of fields (item codes 1–21) that pertain to all errors and
warnings. In addition, SQLCA has a table of records (item codes 22–29) with each
record describing one error or warning. NonStop SQL uses errorindex to access
this table to determine the error or warning
If errorindex is omitted, NonStop SQL returns the first error record.

namesmax input

INT
is the maximum length your program allows for procedure names or file names
(item codes 9, 13, and 19). Longer names are truncated (and no error results from
the truncation).

paramsmax input

INT
is the maximum length your program allows for parameter information (item codes
16 and 29). Parameter information that exceeds this length is truncated (no error
results from the truncation).

resultlen output

INT .EXT
returns the total number of bytes used in the result structure.

erroritem output

INT .EXT
returns the index of the item being processed when the error occurred. The index
starts at 0.
Table 4-2 lists the codes you can specify in the itemlist array.

HP NonStop SQL Programming Manual for TAL—527887-001


4- 10
System Procedures SQLCAGETINFOLIST

Table 4-2. SQLCAGETINFOLIST Procedure Item Codes (page 1 of 2)


Item Size (in
Code bytes) Description
1 2 SQLCA version.
2 2 Maximum number of errors or warnings the SQLCA can represent.
3 2 Actual number of errors or warnings.
4 2 Whether there were more errors or warnings than the SQLCA had
space to store:
• 0 There were no more errors or warnings.
• Nonzero There were more errors or warnings.
5 2 Whether there were more parameters than the SQLCA had space
to store:
• 0 There were no more parameters.
• Nonzero There were more parameters.
6 2 Maximum byte length of the name of the function in which the SQL
statement appears.
7 2 Actual byte length of the name of the function in which the SQL
statement appears.
8 (in item Name of the function in which the SQL statement appears.
code 7)
9 4 Source code line number of the SQL statement that caused an
error.
10 2 Syntax error location; if there was no syntax error, SQL returns –1.
11 2 Maximum byte length of the system procedure that sets the first
error or warning.
12 2 Actual byte length of the system procedure that sets the first error
or warning.
13 (in item Name of the system procedure that sets the first error or warning.
code 12)
14 2 Maximum byte length of the parameter buffer.
15 2 Used bytes in the parameter buffer.
16 (in item Parameter buffer.
code 15)
17 2 Maximum byte length of the source name buffer.
18 2 Used bytes in the source name buffer.
19 (in item Source name buffer.
code 18)
20 4 Number of processed rows.
21 8 Estimated query cost.

HP NonStop SQL Programming Manual for TAL—527887-001


4- 11
System Procedures SQLCAGETINFOLIST

Table 4-2. SQLCAGETINFOLIST Procedure Item Codes (page 2 of 2)


Item Size (in
Code bytes) Description
22 2 SQL error or warning number
23 2 Subsystem ID: First byte is 0; second byte can be one of these
letters:
S Compiler, catalog manager, executor, SQLUTIL, SQLCI
F SQL file system
D DP2 disk process
G NonStop Kernel operating system
R FASTSORT program (SORTPROG process)
L Load routines
I Sequential I/O (SIO) procedures
24 2 Suppress printing this error (0 = False, nonzero = True)
25 2 Offset into the parameters buffer for parameters associated with
the call. SQL returns –1 if there are no parameters.
26 2 Number of parameters for this error.
27 2 Sequence in which the error or warning was set.
28 2 Size of the buffer that contains parameters.
29 (in item Buffer that contains parameters, delimited by zero. Each parameter
code 28) begins on an even word boundary and is preceded by 2 bytes.

Table 4-3 lists the SQLCAGETINFOLIST error codes.

Table 4-3. SQLCAGETINFOLIST Procedure Error Codes


Error Code Description
8510 A required parameter is missing.
8511 The program specified an invalid item code.
8512 The program specified an invalid SQLCA structure.
8513 The program specified an SQLCA structure with a version that is more
recent than the version of the SQLCAGETINFOLIST procedure.
8514 Insufficient buffer space is available.
8515 The program specified an error entry index that is less than zero or
greater than the number of errors.
8516 The program specified a namesmax parameter that is less than or equal
to zero.
8517 The program specified a paramsmax parameter that is less than or
equal to zero.

HP NonStop SQL Programming Manual for TAL—527887-001


4- 12
System Procedures SQLCATOBUFFER

In the example below, SQLCAGETINFOLIST returns the:


• Name of the function containing the SQL statement that produced one or more
errors or warnings
• Name length of the function
• Number of errors or warnings that occurred
To avoid coding the maximum length for the function name (NAME[0:29] in this
example):
1. Call SQLCAGETINFOLIST passing item code 7 (ERR^WARN.NAMELEN).
2. Call SQLCAGETINFOLIST again passing a buffer of the appropriate size.
! Declare a structure to hold the error information
STRUCT .err^warn;
BEGIN
INT namelen;
INT numerrs;
STRING name[0:29];
END;
! Include the SQLCA structure
EXEC SQL INCLUDE SQLCA;
! Declare a variable to hold the return code for the call
INT errcode;
! Declare and initialize the itemlist array
INT itemlist[0:2] := [ 7, 3, 8 ];
! 7 code for name length
! 3 code for number of errors/warnings
! 8 code for procedure id
! Call SQLCAGETINFOLIST
errcode := SQLCAGETINFOLIST (
sqlca, ! SQLCA structure
itemlist, ! List of item codes
3, ! Number of items
err^warn, ! Result goes here
$LEN(err^warn), ! Size of result area
, ! No error index needed
30 ); ! Truncate names greater
! than 30 characters

SQLCATOBUFFER
The SQLCATOBUFFER procedure writes to a buffer the error or warning messages
that NonStop SQL returns to the application program. The buffer is a record area
declared in the variable declarations in the TAL program. The messages can be from
these subsystems or system components:

HP NonStop SQL Programming Manual for TAL—527887-001


4- 13
System Procedures SQLCATOBUFFER

• NonStop SQL
• FASTSORT program (SORTPROG process)
• Sequential I/O (SIO) procedures
• File system
• NonStop Kernel operating system
• Disk process (DP2)

CALL SQLCATOBUFFER ( sqlca ! i


, output^buffer ! i,o
, output^buffer^length ! i
, [ first^output^record ] ! i
, [ output^records ] ! o
, [ more ] ! o
, [ output^record^length ] ! i
, [ sql^msg^file^number ] ! i,o
, [ errors ] ! i
, [ warnings ] ! i
, [ statistics ] ! i
, [ caller^error^loc ] ! i
, [ internal^error^loc ] ! i
, [ prefix ] ! i
, [ prefix^length ] ! i
, [ suffix ] ! i
, [ suffix^length ] ) ; ! i

sqlca input

INT .EXT
is a pointer to the SQLCA structure. The TAL compiler automatically declares the
SQLCA structure when you specify the INCLUDE SQLCA directive.

output^buffer input/output

STRING .EXT
specifies the buffer name where SQLCATOBUFFER writes the error information.

output^buffer^length input

INT
specifies the length of output^buffer in bytes. This length must be:
• An integer value from output^record^length through 600
• A multiple of output^record^length
The recommended minimum length is 300 bytes.

HP NonStop SQL Programming Manual for TAL—527887-001


4- 14
System Procedures SQLCATOBUFFER

first^output^record input

INT
is the ordinal number of the first error record (line) to be written to the output buffer.
The procedure discards any error records with a lower number. The default is 1.
The count of lines begins with 1. To obtain more than one error record, you must
increment the value in first^output^record.

output^records output

INT
is the number of records (lines) written by SQLCATOBUFFER to output^buffer.

more output

.INT
returns a flag that indicates whether all the desired lines fit into the output^buffer.
The values SQLCATOBUFFER can return and their meanings are:
Y There were additional records; the buffer overflowed.
N There were no additional records.

output^record^length input

INT
defines the length of records to be written to the output^buffer; the length must be
an integer value from 60 through 600. The default is 79 bytes.
The procedure pads each line with blanks and adds the suffix and prefix strings if
the call specifies them.

sql^msg^file^number input/output

INT
contains the file number of the SQLMSG file. If you pass –1 on input, the system
opens the SQLMSG file and returns the resulting file number. If you pass a value
other than –1, the system uses that value as the file number of the SQLMSG file.
You can improve performance when your program makes multiple calls to the
SQLCATOBUFFER (or SQLCADISPLAY procedure) by specifying a variable
containing –1 on the first call and then including the returned file number on
subsequent call statements. By including the file number, the system opens the file
only for the first call and uses the file number for subsequent calls; otherwise, the
system must open the file for every call.

HP NonStop SQL Programming Manual for TAL—527887-001


4- 15
System Procedures SQLCATOBUFFER

errors input

INT
controls the error messages that are written to the buffer. The values you can
specify and their meanings are:
N Write only the first error.
Y Write all errors.
B Write all errors but suppress the prefix:
ERROR from subsystem [nn]:
The default is Y.

warnings input

INT
controls the warning messages that are written to the buffer. The values you can
specify and their meanings are:
N Write no warning messages.
Y Write all warning messages.
B Write all warnings but suppress the prefix:
WARNING from subsystem [nn]:
The default is Y.

statistics input

INT
controls the statistics that are written to the buffer. The values you can specify and
their meanings are:
Y Write row and cost statistics if the value returned to the SQLCA in the ROW or
COST data item is greater than or equal to 0.
R Write rows only.
C Write cost only.
N Write no statistics.
The default is Y.

HP NonStop SQL Programming Manual for TAL—527887-001


4- 16
System Procedures SQLCATOBUFFER

caller^error^loc input

INT
controls writing the program name and line number of the SQL statement that
received the error. The values you can specify and their meanings are:
Y Enable writing of the information.
N Suppress writing of the information.
The default is Y.

internal^error^loc input

INT
controls writing the location in system code where the first error in the SQLCA
occurred. The values you can specify and their meanings are:
Y Enable writing the information.
N Suppress writing the information.
The default is Y.

prefix input

STRING .EXT
specifies a string to precede each output line. The default is three asterisks and a
space (*** ).

prefix^len input

INT
specifies the length of the prefix string precede each output line; the length can be
an integer value from 1 through 15. If you include the prefix parameter, you must
also include this parameter. If you omit the prefix parameter, you must also omit
this parameter.

suffix input

STRING .EXT
specifies a string to be appended to each output line. The default is a null string.

HP NonStop SQL Programming Manual for TAL—527887-001


4- 17
System Procedures SQLCATOBUFFER

suffix^len input

INT
specifies the length of the suffix string to append to each output line; the length can
be an integer value from 1 through 15. If you include the suffix parameter, you
must also include this parameter. If you omit the suffix parameter, you must also
omit this parameter.

Guidelines
Follow these guidelines when you call the SQLCATOBUFFER procedure:
• NonStop SQL returns errors as negative numbers and warnings as positive
numbers.
• If there is no text for an error number, NonStop SQL displays:
No error text found.
The $SYSTEM.SYSTEM.SQLMSG file contains the error text for SQL messages.
If you receive this message, your version of the SQLMSG file might not match the
version of the SQL executor.
• SQLCATOBUFFER works by starting with the first^record^number indicated to
move output lines to the record area until all error messages are moved or until the
text fills the record area. SQLCATOBUFFER returns to output^records a count of
the lines moved to the buffer. If an overflow occurs, the procedure sets the more
flag to Y.
• On an overflow condition, your program can retrieve the rest of the error message
text by calling SQLCATOBUFFER again, setting first^output^record to
output^records + 1.
This example uses a 75-character output record and a buffer of 375 characters. The
example also declares an SQLMSG file number, which it initializes to -1. The
SQLCATOBUFFER call returns the SQLMSG file number so that it can be used in
subsequent calls.
CALL SQLCATOBUFFER ( sqlca, ! SQLCA structure
msg^buf, ! Message buffer
375, ! Buffer length
,,, ! Omitted
75, ! output record size
sqlmsg^file); ! SQLMSG file number

HP NonStop SQL Programming Manual for TAL—527887-001


4- 18
System Procedures SQLGETCATALOGVERSION

SQLGETCATALOGVERSION
The SQLGETCATALOGVERSION procedure returns the version of an SQL catalog.

error := SQLGETCATALOGVERSION ( [ catalogname ] ! i


, sqlversion ) ; ! o

error returned value

INT
returns the outcome of the operation. Zero (0) indicates a successful operation. For
a description of SQL errors, see the SQL/MP Messages Manual.

catalogname input

STRING .EXT
specifies the fully qualified name of the catalog for which you are requesting
information. The name must be:
• Left justified and padded with blanks
• A maximum of 26 characters
If you omit catalogname, SQLGETCATALOGVERSION uses the default catalog.

sqlversion output

INT .EXT
is the version of the catalog. The procedure returns one of these values:
1. Version 1 catalog (created by NonStop SQL C10)
2. Version 2 catalog (created by NonStop SQL C30)

SQLGETOBJECTVERSION
The SQLGETOBJECTVERSION procedure returns a value that indicates the SQL
object version. This value represents the oldest NonStop SQL release that can perform
all DML and most DDL operations defined for a given table, view, or index.

error := SQLGETOBJECTVERSION ( objectname, ! i


sqlversion ) ; ! o

error returned value

INT
returns the outcome of the operation. Zero (0) indicates a successful operation. For
a description of SQL errors, see the SQL/MP Messages Manual.

HP NonStop SQL Programming Manual for TAL—527887-001


4- 19
System Procedures SQLGETOBJECTVERSION

objectname input

STRING .EXT
specifies the fully qualified file name of the NonStop SQL object for which you are
requesting information. The name must be:
• Left justified and padded with blanks
• A maximum of 34 characters

sqlversion output

INT .EXT
is the version of the object. The value returned is:
1. Version 1 object that is compatible with NonStop SQL C10
2. Version 2 object that is compatible with NonStop SQL C30

Guidelines
If the object uses any of the Version 2 features shown in this table,
SQLGETOBJECTVERSION returns a value representing a Version 2 object.
Otherwise, SQLGETOBJECTVERSION returns a value representing a Version 1
object.

Table 4-4. NonStop SQL Release C30 (Version 2) Features


Category Features
Data Types FLOAT (includes REAL and DOUBLE PRECISION)
DATETIME (includes DATE, TIME, and TIMESTAMP)
INTERVAL
UPSHIFT CHARACTER or VARCHAR
Functions Date-time functions
Exponentiation UPSHIFT function
Features Columns that can contain null values
Clustering key
Constraints using Version 2 data types or functions

The following attributes are Version 2 features that do not cause


SQLGETOBJECTVERSION to return the value 2 in sqlversion. To determine if these
attributes are present, a program must query the catalog tables containing the
description of the table or view.
• NO AUDITCOMPRESS attribute
• HEADING attribute
• HELP TEXT attribute

HP NonStop SQL Programming Manual for TAL—527887-001


4- 20
System Procedures SQLGETSYSTEMVERSION

These attributes, however, are considered Version 2 features by the catalog manager
process, which handles DDL statements. Tables and views that use these features
must be handled by DDL statements executed on a NonStop SQL C30 system.

SQLGETSYSTEMVERSION
The SQLGETSYSTEMVERSION procedure returns the version of NonStop SQL file
system and disk process components that are running on a system.

error := SQLGETSYSTEMVERSION ( [ nodenumber ] ! i


, sqlversion ) ; ! o

error returned value

INT
returns the outcome of the operation. Zero (0) indicates a successful operation. For
more information on the description of SQL errors, see the SQL/MP Messages
Manual.

nodenumber input

INT
specifies the node number of the system for which you are requesting information.
The default is the local system.

sqlversion output

INT .EXT
is the NonStop SQL software release version for the system. The values for
sqlversion are:
1. NonStop SQL C10 (release 1)
2. NonStop SQL C30 (release 2)
Guidelines
Follow these guidelines when you call the SQLGETSYSTEMVERSION procedure:
• For a specific system, you can assume that all NonStop SQL components are the
same release level.
• When you request the version number for a remote system,
SQLGETSYSTEMVERSION returns the version information for the remote disk
process. A successful call does not guarantee that NonStop SQL is installed on the
remote system.
• If you try to return the version of a remote system that has NonStop SQL release
C10 installed, SQLGETSYSTEMVERSION returns an error.

HP NonStop SQL Programming Manual for TAL—527887-001


4- 21
System Procedures SQLSADISPLAY

SQLSADISPLAY
The SQLSADISPLAY procedure displays the execution statistics of SQL statements.
However, SQLSADISPLAY does not display an SQLSA structure produced by a
PREPARE statement.

CALL SQLSADISPLAY ( sqlsa^ ! i


, [ sqlca^ ] ! i
, [ out^file^number ] ! i,o
, [ detail^params ] ) ; ! i

sqlsa^ input

INT .EXT
is a pointer to the SQLSA structure. The TAL compiler automatically declares the
SQLSA structure when you specify the INCLUDE SQLSA directive.

sqlca^ input

INT .EXT
is a pointer to the SQLCA structure. The TAL compiler automatically declares the
SQLCA structure when you specify the INCLUDE SQLCA directive. The SQLCA
structure contains the procedure name and line number of the SQL statement that
set the SQLSA. If you omit the SQLCA name, the display does not contain the
procedure name and process name of the caller.

out^file^number input

INT
is the output file number. If you omit this value or set it to a negative value,
SQLDADISPLAY displays information at your home terminal. NonStop ignores this
parameter if detail^params specifies sequential I/O (SIO).

detail^params input

INT .EXT
determines whether the application uses SIO or Enscribe I/O (which is the default)
to write to the output file. detail^params points to a structure with this declaration:
STRUCT detail^params;
BEGIN
STRING sio;
INT .EXT out^fcb^1;
INT .EXT out^fcb^2 ;
END;
The fields in the detail^params structure are:

HP NonStop SQL Programming Manual for TAL—527887-001


4- 22
System Procedures SQLSADISPLAY

sio
specifies whether sequential I/O (SIO) is used; it can have these values:
Y Use SIO; ignore out^file^number.
N Do not use SIO; write to out^file^number.

out^fcb^1
specifies the first output file control block if SIO is enabled.

out^fcb^2
specifies the second output file control block if SIO is enabled. To use this field,
assign it a value greater than 0.

Guidelines
The PREPARE statement continually redefines the fields of the SQLSA during the
execution of dynamic SQL statements. Therefore, SQLSADISPLAY cannot display an
SQLSA returned by a PREPARE statement.
SQLSADISPLAY displays statistics in this format:
SQL statistics @ \ system.$vol.subvol.file.#line process
cpu,pin
Records Records Disc Message Message Lock
Table Name Accessed Used Reads Count Bytes WE
This table describes the elements of the SQLSADISPLAY display:

Table 4-5. SQLSADISPLAY Procedure Display Elements


Element Description
\ system.$ vol. subvol. file The fully qualified file name of the calling program
# line The line number of the calling program
process cpu,pin The processor and PIN of the calling program
Table Name The name of each table
Records Accessed The number of records accessed in each table (includes
records examined by the disk process, file system, and SQL
executor)
Records Used The number of records actually used by the statement
Disc Reads The number of disk reads caused by accessing this table
Message Count The number of messages sent to execute operations on this
table
Message Bytes The number of message bytes sent to access this table
Lock WE A flag indicating either that lock waits occurred (W) or that
lock escalations occurred (E) for the table

HP NonStop SQL Programming Manual for TAL—527887-001


4- 23
System Procedures SQLSADISPLAY

Figure 4-1 shows an example of the information that SQLSADISPLAY displays at the
home terminal. To generate this display, a program must:
1. Include the SQLSA and SQLCA structures.
2. Execute an SQL DML statement.
3. Call the SQLSADISPLAY procedure:
CALL SQLSADISPLAY (sqlsa, sqlca);

Figure 4-1. SQLSADISPLAY Display

SQL statistics @ \sanfran.$system.accts.prog10.#333.2 process 12,255


Table Name Records Records Disc Message Message
Accessed Used Reads Count Bytes Lock WE

\sanfran.$sqlvol.accts.tab10

123 22 3 10 3245

\sanfran.$vol001.fy91.employee

9987231 1 99999 1 100 e

\sanfran.$sqlvol.accts.tab20

1 1 0 1 100 w
VST0401.vsd

HP NonStop SQL Programming Manual for TAL—527887-001


4- 24
5
Program Compilation and Execution
This section describes the compilation and execution of a TAL program that contains
embedded SQL statements. This section covers:
• Compiling a TAL source program including running the TAL and SQL compilers,
running the Accelerator, and using the Binder program
• Determining SQL program file validity
• Understanding automatic SQL recompilation
• Maximizing local autonomy
• Executing an SQL program file
Figure 5-1 on page 5-2 shows the steps you follow to compile and execute a TAL
program that contains embedded SQL statements. Steps 1 through 4 are described
under Compiling a TAL Program on page 5-2. These steps are similar to the steps for
compiling a TAL program that does not contain embedded SQL statements, except for
the SQL compilation step (Step 4). Step 5 is described under Executing an SQL
Program File on page 5-30.

HP NonStop SQL Programming Manual for TAL—527887-001


5-1
Program Compilation and Execution Compiling a TAL Program

Figure 5-1. Compiling and Executing a Program

TAL/SQL TALLIB

Source Run-Time
File (s) Library

SQL
Binder Accelerator Compiler
TAL Compiler

3 4
1 2

TAL/SQL TAL/SQL TAL/SQL


Single Single TAL/SQL
Obejct Object Obejct
Object
File (s) File File
File

5
TAL TNS Run the
TAL Object TAL Object and TNS/R object file
Code Code Object
Code

SQL Source SQL Source SQL Source


Statements Statements Statements
VST0501.vsd

Compiling a TAL Program


To compile a TAL source file that contains embedded SQL statements:
1. Run the TAL compiler to compile the TAL statements in each source file of your
program.
2. Use the Binder program, if necessary, to combine multiple object files into one
object file.
3. Run the SQL compiler to compile the SQL statements in the TAL object file.
These steps are described in detail in this section.

HP NonStop SQL Programming Manual for TAL—527887-001


5-2
Program Compilation and Execution Running the TAL Compiler

Running the TAL Compiler


To run the TAL compiler, enter an implicit TACL RUN command at your TACL prompt
or from an OBEY command file. The syntax is:

TAL / [ IN source-file ] [, OUT list-file ]

[ , run-option] [ , run-option] ... / [ object-file ]

[ ; directive [ , directive ] ... ]

directive can be:

[ SYMBOLPAGES num-pages ]

[ SQL [ option ]
[ ( option [ , option ] ... ) ]

option is:

[ PAGES num-pages ]

[ RELEASE1 | RELEASE2 ]

[ SQLMAP | NOSQLMAP ]

[ WHENEVERLIST | NOWHENEVERLIST ]

source-file
is the primary source file of your compilation unit. The source file can be an EDIT
format disk file (file code 101), a terminal, a magnetic tape unit, or a process. The
default is your home terminal (if your TACL process is in interactive mode).

list-file
is the name of the file that receives the output from the compiler. If you specify
OUT without a list file, TAL suppresses the output. If you omit OUT and you started
the compiler from your TACL process, the OUT file is your home terminal. Often,
the list file is a spooler location (for example, $S.#TALLIST).

run-option
is a TACL RUN command option, as described in the TACL Reference Manual.

object-file
is a Guardian file name that specifies the bindable object code for the compilation unit.
If you omit the object file, the compiler creates a file named OBJECT on your
default subvolume. If the compiler cannot create OBJECT (usually, because a file
with this name already exists and cannot be purged), the compiler creates a file

HP NonStop SQL Programming Manual for TAL—527887-001


5-3
Program Compilation and Execution Using the Binder Program

named ZZBI nnnn on your default subvolume (nnnn is a 4-digit number determined
by the system).

directive
is a TAL compiler directive as described in this manual or in the TAL Reference
Manual.
You must include the SQL directive either in the command line or at the beginning
of the primary source file. Other TAL compiler directives are optional. For more
information on the description of the SQL directive, see Section 3, NonStop SQL
Statements and Directives.
In this example, the TAL compiler compiles the source file PARTSRC, writes the listing
to the spooler location $S.#PARTLST, and writes the object file to the disk file
PARTOBJ on your default subvolume.
TAL /IN partsrc, OUT $s.#partlst, NOWAIT / partobj; SQL
For more information about TAL compiler options, see the TAL Reference Manual.

Using the Binder Program


The Binder program allows you to read, link, modify, and build executable object files
for SQL and TAL object files (as well as C, COBOL85, and Pascal object files). Follow
these guidelines when you bind SQL object files:
• Consider SQL object files to be like other object files.
• Bind object files after they are compiled by either the TAL or the SQL compiler.
• Binding invalidates a previously SQL validated object file (which is the result of a
successful explicit SQL compilation). You must explicitly SQL compile the file again
to revalidate it.

Caution. Do not use the Binder STRIP command on object files that contain embedded SQL
statements. The STRIP command removes the Binder and INSPECT tables from the object
file. Without the Binder table, the SQL compiler cannot compile the program and the SQL
executor cannot execute the program.

Including the TALLIB Run-Time Library


Before you can compile an object file using the SQL compiler, the TALLIB run-time
library must be bound with the object file. The TALLIB library should be installed on the
same subvolume as the TAL compiler. Specify the TALLIB library file either during the
TAL compilation using a SEARCH directive or after compilation using the Binder
program.

HP NonStop SQL Programming Manual for TAL—527887-001


5-4
Program Compilation and Execution Running the Accelerator

When you run the TAL compiler, use the SEARCH directive to include the TALLIB run-
time library. This SEARCH directive appears in a TAL source file:
! TAL source file
?SEARCH ($system.system.TALLIB)
...
You can also specify the SEARCH directive in the command line for the TAL compiler:
TAL /IN partsrc, OUT $s.#partlst, NOWAIT / partobj ; SQL ,
SEARCH ($system.system.TALLIB)
These Binder commands build an object file named PROGOBJ that includes the
TALLIB library:
ADD * FROM progobj
SELECT SEARCH $system.system.TALLIB
BUILD progobj !

Running the Accelerator


If your object file will run on a TNS/R system, you can run the Accelerator to optimize
the object code. Because the Accelerator invalidates SQL object files, you must run it
before you run the SQL compiler. For more information about the Accelerator, see the
Programmer’s Guide for TNS/R Systems and the Accelerator Manual.

Running the SQL Compiler


The SQL compiler generates SQL object code in the TAL object file. SQL compilation
also verifies the SQL objects used in SQL statements and generates an optimized
execution plan for each SQL statement. Optionally, you can invoke the EXPLAIN utility
to produce a report on the execution plans for SQL DML statements and the TACL
DEFINEs used by the program. (For a complete list of SQL compiler functions, see
What Does the SQL Compiler Do? on page 5-11.

HP NonStop SQL Programming Manual for TAL—527887-001


5-5
Program Compilation and Execution Running the SQL Compiler

To run the SQL compiler, use the SQLCOMP command. The syntax is:

SQLCOMP / IN object-file [ , OUT [ list-file ] ]

[ , run-option] [ , run-option ] ... /

[ compiler-option [ , compiler-option ] ... ]

compiler-option is:

[ CATALOG catalog-name ]

[ CURRENTDEFINES | STOREDDEFINES ]

[ EXPLAIN ]
[ [ PLAN ] ]
[ [ DEFINES [ file-name ] [, OBEYFORM ] ]]
[ ]
[ NOEXPLAIN ]

[ FORCE | NOFORCE ]

[ OBJECT | NOOBJECT ]

[ RECOMPILE | NORECOMPILE ]

[ RECOMPILEONDEMAND | RECOMPILEALL ]

object-file
is a disk file name. This file cannot be in a user library or a system library. The
object file can be generated by the:
• TAL compiler
• Binder program
• Accelerator
• SQL compiler
You must run the SQL compiler on the same system where object-file exists. If you do
not specify a system or volume name, the SQL compiler uses your current default
values.

list-file
identifies the destination where the SQL compiler directs the listing; list-file can be a
disk file name, process name (including a spooler collector), or a device name
(including a terminal, magnetic tape unit, or line printer). The syntax is:
[\ system.] external-file

HP NonStop SQL Programming Manual for TAL—527887-001


5-6
Program Compilation and Execution Running the SQL Compiler

\ system
is an optional system name.

external-file
is one of these Guardian names:
[$ volume-name.][subvolume-name.] disk-file-name
$ device-name
$ device-number
$ process-name
$ spooler-collector-name[.# spooler-location-name]
If list-file does not exist, the SQL compiler creates it. If list-file already exists, the SQL
compiler appends the new output to it.
If you specify OUT but omit list-file, the SQL compiler does not produce a listing.
If you omit OUT, the SQL compiler directs the listing to the OUT file of the invoking
process (which is usually your home terminal).

run-option
is a TACL RUN command option, as described in the TACL Reference Manual.

catalog-name
is the name of the catalog that is to hold a description of the program; catalog-
name is a subvolume name. If you partially qualify the catalog name, the system
expands the name by using your current default values.
You can also specify a TACL CLASS CATALOG DEFINE name for catalog-name.
The catalog, object file, and SQL compiler must be on the same system.
If the program was previously SQL compiled and recorded in a different catalog,
catalog-name overrides the catalog name stored in the program file. The program
is dropped from the previous catalog and recorded in catalog-name.
If you omit the CATALOG clause, the SQL compiler uses the current default
catalog. If you have not defined a default catalog, the SQL compiler uses your
current default subvolume.

CURRENTDEFINES | STOREDDEFINES
specifies the set of TACL DEFINEs used to interpret DEFINE names in the SQL
statements in the program file.

CURRENTDEFINES
selects the current set of TACL DEFINEs for compiling the program.
CURRENTDEFINES is the default.

HP NonStop SQL Programming Manual for TAL—527887-001


5-7
Program Compilation and Execution Running the SQL Compiler

STOREDDEFINES
selects set of TACL DEFINEs stored with the program the last time it was SQL
compiled. This option applies only to programs that have been SQL compiled.

FORCE | NOFORCE
controls how syntax errors affect SQL compilation.

FORCE
directs the SQL compiler to produce a valid, executable object file regardless
of any syntax errors. The SQL compiler writes the SQL source statements to
the object file so that the statements can automatically be recompiled if
executed at run time.
You can use the FORCE option to debug a program if you do not need to
execute the SQL statements that generate errors.

NOFORCE
directs the SQL compiler to produce the SQL object file only if there are no
syntax errors. NOFORCE is the default.
[ EXPLAIN ]
[ [ PLAN ] ]
[ [ DEFINES[ file-name ][, OBEYFORM ] ] ]
[ ]
[ NOEXPLAIN ]
controls whether the compiler invokes the EXPLAIN utility.

EXPLAIN
enables the EXPLAIN utility.

PLAN
selects the optimized execution plan determined by the SQL compiler for DML
statements in the program. PLAN is the default.

DEFINES [ file-name ] [, OBEYFORM ]


displays the TACL DEFINEs used to SQL compile the SQL statements. The
DEFINEs appear at the end of the SQL compiler listing. These DEFINEs are
the ones that would be used if you were to recompile the program with the
STOREDDEFINES option.

file-name
is the destination where the DEFINE listing is written. The destination is an
external-file as described for OUT list-file.

HP NonStop SQL Programming Manual for TAL—527887-001


5-8
Program Compilation and Execution Running the SQL Compiler

OBEYFORM
specifies writing the TACL DEFINE list in OBEY format so that you can
enter an OBEY command from your TACL prompt to set the DEFINEs
before run time or compile time. If you omit OBEYFORM, the listing is in
the format displayed by the INFO DEFINE command. If you omit
DEFINES, a DEFINE listing is not generated.

NOEXPLAIN
disables the EXPLAIN utility. NOEXPLAIN is the default.

OBJECT | NOOBJECT
controls whether the compiler produces an SQL program file.

OBJECT
directs the compiler to generate an SQL program file (depending on
whether errors occur and whether the FORCE or NOFORCE option is in
effect).
OBJECT is the default.

NOOBJECT
directs the compiler to perform checking functions, to generate an
EXPLAIN listing if you have also specified EXPLAIN, and not to produce
an SQL program file.

RECOMPILE | NORECOMPILE
specifies whether the program should be automatically recompiled, if
necessary.

RECOMPILE
directs the SQL compiler to automatically recompile a program whenever
all of these conditions occur at run time:
• The program file is marked invalid.
• Run-time TACL DEFINEs are different from SQL compile-time
DEFINEs.
• The timestamp check on file opens indicate that the program should
have been marked as invalid, but it was not marked because the
program was network-inaccessible or already executing.
• An access path is unavailable.
RECOMPILE is the default.

HP NonStop SQL Programming Manual for TAL—527887-001


5-9
Program Compilation and Execution Running the SQL Compiler

NORECOMPILE
directs the SQL compiler not to automatically recompile the program.
(Therefore, if any of the preceding run-time conditions occur, the program
cannot continue execution and would need explicit SQL compilation for
revalidation.)

RECOMPILEONDEMAND | RECOMPILEALL
specifies whether the compiler should recompile an entire invalid program or
only those SQL statements that require recompilation and are actually
executed. If you specify NORECOMPILE, this option is ignored.

RECOMPILEONDEMAND
directs the SQL compiler to recompile only those statements in the invalid
program that are actually executed. Automatic recompilation occurs the
first time an individual SQL statement is executed.

RECOMPILEALL
directs the SQL compiler to automatically recompile the entire program if it
is invalid. Automatic recompilation occurs at program load time.
RECOMPILEALL is the default.
In this example, the SQL compiler compiles the program file PARTOBJ, writes the
listing to the spooler location $S.#PARTLST, and records the program file in catalog
PROGCAT on volume $VOL1. Upon successful completion of the run, the compiler
rewrites PAROBJ as a validated SQL program file.
SQLCOMP /IN partobj, OUT $s.#partlst, NOWAIT / &
CATALOG $vol1.progcat

Caution. Do not use the same name for different procedures in separate source modules if
the modules contain SQL statements. NonStop SQL might interpret internal data structures as
duplicates, which would cause the SQL statements in one of the procedures not to be included
in the SQL object program.

Access Privileges
To SQL compile a program file, you must have these access privileges:
• Read and purge authority for the program file
• Read and write authority for the PROGRAMS, USAGES, and TRANSIDS tables of
the catalog in which the program is to be registered
• Read and write authority for the USAGES and TRANSIDS tables of any catalog in
which a table, view, or index that the program uses is registered

HP NonStop SQL Programming Manual for TAL—527887-001


5- 10
Program Compilation and Execution Running the SQL Compiler

Statistics Information
For the SQL compiler to determine the best execution plan, it needs the current
statistics for any referenced tables. To provide these statistics, a database
administrator can use the UPDATE STATISTICS statement, which writes statistical
information about the tables in the catalog in which the table is registered. For more
information, see the UPDATE STATISTICS statement in the SQL/MP Reference
Manual.

What Does the SQL Compiler Do?


When you SQL compile a program file, the SQL compiler performs these functions:
• Resolves names. The compiler expands SQL object names, including TACL
DEFINE names, in the program using the current default volume, the current
catalog.
• Checks object references in catalogs. The compiler checks the catalogs for SQL
object names to verify their existence and to read their descriptions. Then, the
compiler evaluates the object type and characteristics for each reference.
• Determines an optimized execution plan. The compiler analyzes the SELECT,
INSERT, UPDATE, and DELETE statements to determine the best access paths
and join, sort, and blocking strategies for executing each statement. Then, the
compiler writes the object code for the execution plan to the program file.
• Generates executable code. The compiler compiles the execution plan into
executable object code.
• Stores information in catalogs. If the compilation is successful, the compiler
registers the program in the specified PROGRAMS catalog table and stores
dependencies in the USAGES table. The compiler also stores dependencies in the
USAGES catalog table of the catalogs where tables, views, and indexes that the
program uses are registered.
• Marks the program file SQL sensitive and SQL valid. If the compilation is
successful, the compiler sets the SQL sensitive and SQL valid indicators in the
program's file label.
• Generates a listing. The compiler writes the compiler listing (including any warning
or error messages) to the OUT file or device.
• Estimates execution cost. For SQL DML statements, the compiler lists an estimate
for the cost of processing the statement based on the statistics in the catalogs.
• Reports error and warning conditions. The compiler reports error and warning
conditions, as described under Interpreting SQL Compiler Messages on page 5-14.

HP NonStop SQL Programming Manual for TAL—527887-001


5- 11
Program Compilation and Execution Running the SQL Compiler

SQL Program File Format


The input program file to the SQL compiler can be a TAL object file, a file generated by
the Binder program, a file generated by the Accelerator, or a file previously compiled by
the SQL compiler. Figure 5-2 shows the format of a NonStop SQL program file.

Figure 5-2. NonStop SQL Program File Format

SQL Program File


File Label
SQL Valid Information
Generated by
SQL Sensitive the SQL
Compilation Timestamp Compiler

Object Code
TAL Object Code Generated by
the TAL
Compiler

SQL Source Statement 1

SQL Source Statement 2


SQL Source
Statements
. Stored by the
TAL Compiler
.
.
SQL Source Statement n

Execution
Plans
Generated by
the SQL
Compiler
SQL Object Code
Stored
DEFINES

VST0502.vsd

HP NonStop SQL Programming Manual for TAL—527887-001


5- 12
Program Compilation and Execution Running the SQL Compiler

Using a PARAM Command With the SQL Compiler


Use the TACL PARAM command to specify the BINSERV processes and the swap-file
subvolume that the SQL compiler uses for explicit SQL compilation. A PARAM
command does not apply to automatic SQL recompilation or dynamic SQL compilation.
The syntax for the PARAM command for explicit SQL compilation is:

PARAM [ parameter-name parameter-value ]


[ , parameter-name parameter-value ]...

parameter-name parameter-value
are parameter name and value pairs. These pairs apply to the SQL compiler:
BINSERV guardian-90-name
SWAPVOL subvol

BINSERV guardian-90-name
specifies the program file of the BINSERV program that the SQL compiler uses
during compilation. Follow these guidelines for guardian-name:
• If guardian-90 - name designates a system other than the system on which
the SQL compiler is running, the BINSERV parameter is ignored.
• If guardian-90-name does not include a volume or subvolume name, the
SQL compiler uses your current default values.
The default value for guardian-90-name is the BINSERV program file on the
same subvolume as the SQL compiler.

SWAPVOL subvol
designates a subvolume as the location for temporary files. If you do not
specify a SWAPVOL subvolume, the SQL compiler uses your default
subvolume for temporary files.
You enter a PARAM command before you run the SQL compiler. For example:
PARAM BINSERV $talsql.utils.binserv, SWAPVOL $scratch
...
SQLCOMP /IN tobj, OUT $s.#tlst, NOWAIT / CATALOG $vol.cat
To see parameters that are currently defined, enter a PARAM command without any
parameter name and value pairs. For more information about the PARAM command,
see the TACL Reference Manual.

HP NonStop SQL Programming Manual for TAL—527887-001


5- 13
Program Compilation and Execution Running the SQL Compiler

Interpreting SQL Compiler Messages


The SQL compiler issues messages for error and warning conditions. An error can
prevent successful compilation of a program file, but a warning does not prevent
successful compilation. For a description of SQL compiler messages, see the SQL/MP
Messages Manual.
Error Conditions. An error condition results from an invalid reference to an SQL
object in an SQL statement. Examples of invalid references are incorrect column
names or incompatible data types. If an error occurs, the SQL compiler produces a
listing, but it does not record the program file in the catalog and does not validate it for
execution.
Dynamic SQL statements are not compiled during explicit SQL compilation. These
statements are compiled at run time by a PREPARE statement, which returns a run-
time error if invalid syntax or an invalid reference occurs.
You can force the SQL compilation regardless of errors. To force compilation, specify
the FORCE option in the SQLCOMP command. If you use the FORCE option, the
compiler records the SQL object program file in the catalog and validates the program
file for execution even if errors occur. The FORCE option is sometimes useful for
program debugging when you are not concerned about executing the SQL statements
that produce errors.
The SQL compiler also writes the SQL source statements that have errors to the object
file so that the statements can be automatically recompiled if executed at run time.
Warning Conditions. A warning condition usually occurs when the SQL compiler has
insufficient information available. If a warning occurs, the SQL compiler still records the
program file in the catalog and validates the file for execution and then returns a
warning message. The following paragraphs describe some of the conditions that
cause warnings.
In these two cases, the SQL compiler issues a warning message but still compiles the
statement:
• Compiler assumptions
The compiler made an assumption necessary to complete the compilation. For
example, if the number of columns in the SELECT statement does not match the
number of host variables, the compiler returns a warning message and assumes that
you do not want to use either the extra columns or the extra host variables.
• Unavailable statistics
The compiler did not have the necessary statistics for tables to optimize an execution
plan. The compiler uses statistics in the catalog in which a table or view is registered to
determine an optimized execution plan. These statistics are usually generated by a
database administrator running the UPDATE STATISTICS statement on tables.

HP NonStop SQL Programming Manual for TAL—527887-001


5- 14
Program Compilation and Execution Running the SQL Compiler

For other cases, the SQL compiler first marks the statement as having insufficient
information to compile and then at run time tries to resolve the problem with automatic
recompilation. The SQL compiler does not record dependencies in the USAGES
catalog tables for the affected statement. At run time, if the necessary information is
still not available or any TACL DEFINEs are still unresolved, execution of the statement
causes an error. These cases are:
• Insufficient information
The SQL compiler did not have enough information to determine the validity of a
statement. For example, an SQL statement refers to a table that is unavailable
because the table is on an unavailable remote node. (Another example is an SQL
statement that refers to a table that does not exist. This case always occurs for a
program that both creates and refers to a table; the table, of course, does not exist
when the program is explicitly SQL compiled.)
• Unresolved TACL DEFINEs
An SQL statement often uses a TACL DEFINE name that is not present in the DEFINE
set when the program is explicitly SQL compiled.

SQL Compiler Listings


The SQL compiler writes all the SQL statements in the program file to a listing. If error
or warning conditions occur, the compiler writes messages following the statements
that cause the condition.
For SQL DML statements, the SQL compiler includes the estimated cost of processing
the statement in the listing following the statement. This estimate is a positive integer
that indicates the relative cost. For example, the larger the value, the more processor
time and disk access time is required to execute the statement.
Figure 5-3 shows a sample SQL compiler listing.

HP NonStop SQL Programming Manual for TAL—527887-001


5- 15
Program Compilation and Execution Running the SQL Compiler

Figure 5-3. Sample SQL Compiler Listing (page 1 of 2)

SQL Compiler - T9095C30 - (01NOV91)


COPYRIGHT TANDEM COMPUTERS INCORPORATED 1987, 1988, 1989, 1990, 1991
DATE - TIME : 11/15/91 - 10:08:10
Options : NOFORCE, OBJECT, CURRENTDEFINES, RECOMPILE, RECOMPILEALL, NOEXPLAIN
SQL - PROGRAM FILE = \SYS1.$VOL1.SQLTAL.PROGOBJ
SQL - PROGRAM CATALOG = \SYS1.$VOL1.DBI
SQL - DEFAULT CATALOG = \SYS1.$VOL1.DBI
*************************************************************
SQL - Source File = $VOL1.SQLTAL.PROG
222 ROLLBACK WORK

187 COMMIT WORK

145 INSERT INTO =PARTLOC


146 VALUES ( :PARTLOC^REC.LOC^CODE,
147 :PARTLOC^REC.PARTNUM,
148 :PARTLOC^REC.QTY^ON^HAND )
*** Statistics: Estimated cost: 1
170 INSERT INTO =PARTS
171 VALUES ( :PARTS^REC.PARTNUM,
172 :PARTS^REC.PARTDESC,
173 SETSCALE (:PARTS^REC.PRICE, 2),
174 :PARTS^REC.QTY^AVAILABLE)
*** Statistics: Estimated cost: 2
101 BEGIN WORK
48 DECLARE GET_SUPPLIER_CURSOR CURSOR FOR
49 SELECT SUPPNUM,
50 SUPPNAME,
51 STREET,
52 CITY,
53 STATE,
54 POSTCODE
55 FROM =SUPPLIER
56 WHERE SUPPNUM = :SUPPLIER^OF^PARTS
57 REPEATABLE ACCESS
*** Statistics: Estimated cost: 1 VST0503.vsd

HP NonStop SQL Programming Manual for TAL—527887-001


5- 16
Program Compilation and Execution Using the EXPLAIN Utility

Figure 5-3. Sample SQL Compiler Listing (page 2 of 2)

BINDER - OBJECT FILE BINDER - T9621C30 - (01NOV91) SYSTEM \SYS1.


Copyright Tandem Computers Incorporated 1982-1989, 1991
Object file \SYS1.$VOL1.SQLTAL.PROGOBJ
TIMESTAMP 1991-11-15 10:08:10

2 Code Pages
12 Primary data words
408 Secondary data words
64 Data pages
0 Resident code pages
2 Extended data pages
PAGE 1 11/15/91 - 10 : 08 : 10
Heap location: Extended data space
1 Heap size in pages
420 Top of stack location in words
1 Code segment
0 Binder Warnings
0 Binder Errors
PAGE 2 11/15/91 - 10 : 08 : 10

SQL ************************************************************************************
SQL - Summary of SQL Compiling
SQL - Number of SQL Statements = 6
SQL - Number of SQL Errors = 0
SQL - Number of SQL Warnings = 0
SQL - Number of other Errors = 0
SQL - Compile Time 00 : 00 : 01 .137
SQL - Elapsed Time 00 : 00 : 34.294
SQL - Program file is \SYS1.VOL1.SQLTAL.TROGOBJ
SQL - > > > SQL COMPILATION STORED IN PROGRAM FILE < < <
SQL ************************************************************************************
VST0503a.vsd

Using the EXPLAIN Utility


The EXPLAIN utility generates reports about the execution plans used for each SQL
statement. You can use EXPLAIN reports to determine the database tables and
indexes used by your program. You can also determine whether creating other indexes
or modifying a query would improve the performance of your program. The EXPLAIN
utility has these report options:
• EXPLAIN PLAN report
• EXPLAIN DEFINES report

HP NonStop SQL Programming Manual for TAL—527887-001


5- 17
Program Compilation and Execution Using the EXPLAIN Utility

Generating an EXPLAIN PLAN Report


The EXPLAIN PLAN report applies only to SQL DML statements. A plan shows the
strategy for executing a DML statement and includes optimized access paths, joins,
and sorts.
The EXPLAIN PLAN report generates a plan for a statement that contains subqueries
into separate query plans, one for each subquery and one for the statement itself. This
report numbers the query plans in each statement in the order they appear. Each plan
can contain these steps:
1. Scan a table
2. Join two or more tables
3. Insert into a table
4. Perform a sort operation
In the next example, the SQL compiler compiles the newprog program file using the
EXPLAIN PLAN option to generate the statement execution plans. The command also
specifies the catalog name rather than use the current default subvolume name for the
catalog. The SQL compiler writes the output to the spooler. The command is:
SQLCOMP / IN newprog, OUT $s.#explain, NOWAIT / &
... CATALOG sales, EXPLAIN PLAN
By default, the SQL compiler uses the current set of TACL DEFINEs to create the
object file.
In the next example, the SQL compiler writes an execution plan and set of DEFINEs to
the EDIT file EXOUT, but it does not recompile the OXPLAIN program file:
SQLCOMP /IN oxplain, OUT exout/ NOOBJECT STOREDDEFINES &
EXPLAIN PLAN DEFINES, OBEYFORM
The catalog name for the program unit is stored in the program file so that you do not
have to include the CATALOG option. NOOBJECT suppresses the generation of a new
object file, so the compiler does not write a record about the program file to the
catalog.
The TACL DEFINE set is the set stored with the program OXPLAIN. The execution
plans are the plans that the compiler would generate if it were generating object code;
they are not the plans stored in the object file OXPLAIN.

Generating an EXPLAIN DEFINES Report


The EXPLAIN DEFINES report shows the mapping of TACL DEFINE names used in
SQL DML, DCL, and DDL statements. This report lists:
• Each TACL DEFINE name and its associated Guardian name
• The default volume and default catalog used by the program (which it obtains from
the =_DEFAULTS DEFINE)

HP NonStop SQL Programming Manual for TAL—527887-001


5-18
Program Compilation and Execution Using the EXPLAIN Utility

You can have the EXPLAIN utility generate the EXPLAIN DEFINES report in either of
these formats:
OBEY command file The EXPLAIN utility generates the TACL ADD DEFINE
format commands for the DEFINEs. You can subsequently use the
TACL OBEY command to generate the commands in the file.
INFO DEFINE format The EXPLAIN utility uses the format produced by the TACL
INFO DEFINE command.

Figure 5-4 shows an example of the OBEY command file format report. In an actual
report, each instance of subvolume-name, guardian-name, and define-name would be
replaced by the actual name
.

Figure 5-4. OBEY Command File Format of the EXPLAIN DEFINES Report

ALTER DEFINE = _DEFAULTS, VOLUME subvolume-name


ALTER DEFINE = _DEFAULTS, CATALOG subvolume-name

ADD DEFINE = define-name, FILE guardian-90-name


ADD DEFINE = define-name, FILE guardian-90-name
. . . VST0504.vsd

Note. When you issue an OBEY command using the OBEY command file format to compile or
execute a program, ensure that these TACL DEFINE parameters are set as follows:

SET DEFMODE ON
SET DEFINE CLASS MAP

Figure 5-5 shows an an example of the INFO DEFINE format report. In an actual
report, each instance of guardian-name and define-name would be replaced by the
actual name.

HP NonStop SQL Programming Manual for TAL—527887-001


5-19
Program Compilation and Execution Using the EXPLAIN Utility

Figure 5-5. INFO DEFINE Format of the EXPLAIN DEFINES Report

DEFINE NAME =_DEFAULTS


CLASS DEFAULTS
VOLUME guardian-90-name
CATALOG guardian-90-name

DEFINE NAME define - name


CLASS MAP
FILE guardian-90-name

DEFINE NAME define - name


CLASS MAP
FILE guardian-90-name

. . . . . . VST0505.vsd

Figure 5-6 shows an EXPLAIN report that includes both the execution plans and stored
DEFINEs. The EXPLAIN sample listing shows the SQL compiler options in effect, a
portion of the execution plan, and the DEFINEs report in the OBEY command file
format.

HP NonStop SQL Programming Manual for TAL—527887-001


5-20
Program Compilation and Execution Using the EXPLAIN Utility

Figure 5-6. EXPLAIN Utility Report

SQL Compiler - T9095C30 - (01NOV91)


COPYRIGHT TANDEM COMPUTERS INCORPORATED 1987, 1988, 1989, 1990, 1991
DATE - TIME : 11/15/91 - 09:18:15
Options : NOFORCE, NOOBJECT, STOREDDEFINES, RECOMPILE,
RECOMPILEALL, EXPLAIN PLAN DEFINES, OBEYFORM
SQL - PROGRAM FILE = \SYS1.$VOL1.PROGS.OXPLAIN
SQL - PROGRAM CATALOG = \SYS1.$VOL1.INVENT
SQL - DEFAULT CATALOG = \SYS1.$VOL1.INVENT
*************************************************************
SQL - Source File = \SYS1.$VOL1.PROGS.XPLAIN

59 DECLARE GET_EMP_BY_AVG_SAL_CURSOR CURSOR FOR


60 SELECT EMPNUM, FIRST_NAME, LAST_NAME, SALARY
61 FROM =EMPLOYEE
62 WHERE SALARY >
63 ( SELECT AVG (SALARY)
64 FROM =EMPLOYEE
65 BROWSE ACCESS )
66 AND DEPTNUM = :select_dept
67 BROWSE ACCESS
68
-----------------------------------------------------------------------------------------
QUERY PLAN : 1
STATEMENT TYPE : SELECT
-----------------------------------------------------------------------------------------
. . .
109 CONTROL EXECUTOR PARALLEL EXECUTION ON
-----------------------------------------------------------------------------------------
DEFINES MAPPING
-----------------------------------------------------------------------------------------
ALTER DEFINE =_DEFAULTS, VOLUME \SYS1.$VOL1.PROGS
ALTER DEFINE =_DEFAULTS, CATALOG \SYS1.$VOL1.INVENT
ADD DEFINE =EMPLOYEE, FILE \SYS1.$VOL1.PERSNL.EMPLOYEE
ADD DEFINE =CUSTOMER, FILE \SYS1.$VOL1.SALES.CUSTOMER
ADD DEFINE =ORDERS, FILE \SYS1.$VOL1.SALES.ORDERS
SQL *************************************************************
SQL - Summary of SQL Compiling
SQL - Number of SQL Statements = 3
SQL - Number of SQL Errors = 0
SQL - Number of SQL Warnings = 0
SQL - Number of other Errors = 0
SQL - Compile Time = 00:00:01.887
SQL - Elapsed Time = 00:00:11.656
SQL - Program file is \SYS1.$VOL1.PROGS.OXPLAIN
SQL - >> PROGRAM FILE UNCHANGED BECAUSE OF NOOBJECT OPTION << VST0506.vsd
SQL*************************************************************

HP NonStop SQL Programming Manual for TAL—527887-001


5-21
Program Compilation and Execution Determining Program File Validity

Determining Program File Validity


SQL program files can be valid or invalid. A valid program file can execute with the
current description of the database. Certain operations performed on the program file
or on database objects used by the program cause a program file to become invalid.
An invalid program file requires SQL recompilation because of changes to either itself
or the database (or both).
The SQL compiler validates a program file after a successful explicit SQL compilation
or after errors occurred during the compilation and the FORCE option was in effect.
The SQL compiler records the validation in the file label of the program file and in the
PROGRAMS catalog table. A program file has two classifications for SQL validation:
• SQL sensitive
• SQL valid
The SQL sensitive classification is required for program file execution. It also protects
the file from access by Enscribe utilities. The SQL compiler marks a file as SQL
sensitive by setting the SQL sensitive flag in the file label.
The SQL valid classification indicates that the program file can execute without
automatic recompilation. An SQL valid program contains compiled SQL statements
(rather than SQL source statements). An SQL valid program ensures better
performance because a fully optimized execution plan is available and no automatic
SQL recompilation is required. The SQL compiler sets the SQL valid flag and records
the compilation timestamp in the file label during explicit SQL compilation.
To determine whether an SQL program file is valid or invalid, use one of these
commands:
• FUP FILEINFO command with the DETAIL option (described in the FUP Reference
Manual)
• SQLCI FILEINFO or VERIFY command (described in the SQL/MP Version
Management Guide)

Changes to a Program File


The following operations on a program file invalidate the file. An invalid program file
has the VALID flag and the SQL SENSITIVE flag set to N in its file label.
• Moving or copying a file. For example, if you use the FUP DUPLICATE command
to copy a program file, the original file is unaffected, but the new file is invalid.
• Binding a file. If you explicitly bind a file, the original file is unaffected, but the
resulting target file is invalid.
• Running the Accelerator on a file. If you run the Accelerator to optimize the object
code, the file becomes invalid.

HP NonStop SQL Programming Manual for TAL—527887-001


5-22
Program Compilation and Execution Changes to Database Objects

Changes to Database Objects


When changes are made to database objects (such as tables, views, and indexes), a
program file that uses these objects becomes invalid. Altering the database object
requires a new execution plan for the program file. These database changes are:
• Executing an UPDATE STATISTICS statement with the RECOMPILE option for a
table
• Dropping a table or view
• Adding an index to a table that was created by a CREATE INDEX statement with
the INVALIDATE option specified
• Dropping an index or constraint on a table
• Adding a constraint, column, or partition to a table

Note. These last two items invalidate a program regardless of its use of the particular index,
column, or partition. A program’s dependency on an affected table, as recorded in the
USAGES table, causes invalidation.

When a program file is invalidated by one of the operations just listed, the SQL catalog
manager also resets the VALID flag for the program in the PROGRAMS catalog.

Other Changes
Not all changes to the program file or database cause the program file to become
invalid. The database changes that do not invalidate a program file are:
• Renaming a program file
• Altering the security or owner of a program file or an object the program uses
• Altering the file attributes including the AUDIT flag
• Creating a new view on a table
• Adding an index to a table that was created by a CREATE INDEX statement with
the NO INVALIDATE option specified
• Adding or dropping comments to a table or view
• Executing an UPDATE STATISTICS statement with the NORECOMPILE option for
a table used by the program
Changing a TACL DEFINE does not invalidate a program file; however, automatic
recompilation might be necessary if the DEFINE is different from the one that was used
during the original compilation. Sometimes, however, either the program file or the
catalog in which the program is registered is not available to have the VALID flag reset.
For example, a table is altered on system \SYSTEMA in a network when system
\SYSTEMB is unavailable, but a program on \SYSTEMB uses the altered table on
\SYSTEMA. In this case, the program on \SYSTEMB is not marked as invalid in the file
label or in the catalog.
HP NonStop SQL Programming Manual for TAL—527887-001
5-23
Program Compilation and Execution Understanding Automatic SQL Recompilation

Therefore, an invalid program file is sometimes marked as SQL valid. NonStop SQL
allows this discrepancy to provide local autonomy in database management
operations. An invalid program that is erroneously marked valid is detected at run time
by a timestamp check and automatically recompiled.

Understanding Automatic SQL Recompilation


Automatic SQL recompilation is the run-time compilation, invoked by the SQL executor,
of an entire program file or a single SQL statement in a program file. The functions of
automatic SQL recompilation are:
• Determines the most efficient access to a database by ensuring that an execution
plan uses the current description of the database (this execution plan remains in
effect until the program stops or another SQL recompilation occurs)
• Maximizes database availability and node autonomy by generating a new
execution plan at run time if the currently compiled plan cannot work because a
required index is unavailable
• Allows a program to refer to database objects that did not exist during explicit SQL
compilation
• Allows a program to use different sets of TACL DEFINEs to specify different
databases (for example, a development database and a production database)
If the SQL recompilation is successful, the program file or SQL statement executes. If
the recompilation fails, NonStop SQL returns an error to the SQLCODE variable and
the SQL communication area (SQLCA), if it is declared.
Several considerations for automatic SQL recompilation are:
• Automatic SQL recompilation does not validate the program file itself; it validates
only the copy of the file in memory. Only explicit SQL compilation validates an
invalid program file.
• When an SQL statement is recompiled, the SQL compiler uses the default volume
and catalog that were used for the explicit compilation and the TACL DEFINEs set
from SQL load time (described under SQL Load Time on page 5-25).
• Automatic SQL recompilation can cause the performance degradation of a
program. For the best performance, run valid program files that do not need to be
recompiled.

Predicting Automatic SQL Recompilation


You can enable or disable automatic SQL recompilation when you explicitly SQL
compile a program file. When you enter the SQLCOMP command, use the
RECOMPILE option (which is the default) to enable automatic SQL recompilation and
the NORECOMPILE option to disable it. For application management considerations
(that is, whether you want to enable or disable automatic recompilation), see the
SQL/MP Installation and Management Manual.

HP NonStop SQL Programming Manual for TAL—527887-001


5-24
Program Compilation and Execution Predicting Automatic SQL Recompilation

If automatic SQL recompilation is enabled, these events can trigger a recompilation:


• SQL load time
• Table open time
• A new TACL DEFINE at SQL load time
• An unavailable access path (index)
• The attempted execution of an uncompiled SQL statement

SQL Load Time


SQL load time occurs when the first SQL statement in a program is executed. These
conditions can cause automatic recompilation at SQL load time:
• If the SQL valid flag is set to invalid, recompilation occurs. Automatic recompilation
of an invalid program file occurs each time the program runs.
• If the set of TACL DEFINEs at run time is different from the set used when you
explicitly compiled the program.
To control the extent of recompilation at SQL load time, use the SQLCOMP command
RECOMPILEALL or RECOMPILEONDEMAND option. For automatic recompilation of
the entire program, use the RECOMPILEALL option (which is the default). To limit
automatic recompilation to only statements that are actually executed, use the
RECOMPILEONDEMAND option.

Table Open Time


When the SQL executor accesses a table, an SQL statement is automatically
recompiled if the timestamp for the table is different than the timestamp for the last
SQL compilation of the statement.
Usually, the SQL executor opens a table the first time the program executes an SQL
statement that refers to the table. The executor then leaves the table open until the
program stops. DDL and database utility operations on the table (or on a dependent
index) cause the table to be closed and the timestamp of the table to be updated.
When the SQL statement that uses the table executes again and the table has been
closed, the executor compares the timestamp of the new statement to the timestamp of
the table and recompiles the statement, if necessary.
Only the specific SQL statement is automatically recompiled when the timestamp
check reveals a discrepancy with the table timestamp.

New TACL DEFINEs


If the set of TACL DEFINEs at run time is different from the set when you explicitly
compiled the program and you specified the SQLCOMP command
RECOMPILEONDEMAND option, the statement is recompiled. The compiler uses the

HP NonStop SQL Programming Manual for TAL—527887-001


5-25
Program Compilation and Execution Understanding the Run-Time Timestamp Check

SQL load time TACL DEFINEs for a static SQL statement and the current active TACL
DEFINEs when a PREPARE statement is executed for a dynamic SQL statement.

Unavailable Access Path (Index)


If the SQL executor tries to execute an SQL statement and detects that an access path
in the execution plan is unavailable, the executor invokes the SQL compiler to
recompile the statement. The SQL compiler then determines the best alternate access
path (if such a path exists) to execute the statement. Only the affected statement is
automatically recompiled when the access path becomes unavailable.

Attempted Execution of an Uncompiled SQL Statement


If the SQL executor encounters an uncompiled SQL statement, it invokes the SQL
compiler to compile the statement. A program can contain uncompiled SQL statements
if:
• A table or view used by an SQL statement did not exist during explicit SQL
compilation.
• A description of a table, view, or index needed for the execution plan of an SQL
statement was not available during explicit SQL compilation.
• The program was explicitly compiled with the FORCE option and an SQL
statement had errors.

Understanding the Run-Time Timestamp Check


A program file and all SQL database objects (such as a tables, protection views, and
indexes) have unique timestamps. The SQL executor checks each timestamp to
ensure that a program file uses the current definition of an object for its execution plan.
For example, consider these cases:
• Program PROGRAMA, which is SQL valid when it runs, uses table TABLEA.
• After PROGRAMA starts executing, a database administrator adds a new column
to TABLEA using the ALTER TABLE statement (TABLEA is not locked by
PROGRAMA). The execution plans in PROGRAMA that were generated from the
old TABLEA definition during explicit SQL compilation time are no longer valid.
• When the first SQL statement that uses TABLEA executes, the SQL executor
opens TABLEA and checks the timestamp to ensure that PROGRAMA has a valid
definition for TABLEA. The SQL executor compares the TABLEA timestamp with
the PROGRAMA timestamp. The TABLEA timestamp is more recent than the
PROGRAMA timestamp.
• The SQL executor invokes the SQL compiler to recompile the statement using the
current TABLEA definition. Recompilation does not modify PROGRAMA on disk or
record dependencies in the catalog; it only changes the copy of PROGRAMA in
memory.

HP NonStop SQL Programming Manual for TAL—527887-001


5-26
Program Compilation and Execution Understanding the Run-Time Timestamp Check

If TABLEA is open when you execute the ALTER TABLE statement, the system
closes the table. The next time the SQL statement is executed, the SQL executor
reopens TABLEA, which forces the timestamp check and the statement to be
recompiled.
Figure 5-7 shows this run-time object definition check.

Figure 5-7. Run-Time Checks and Automatic SQL Recompilation

SQL Object Code


. . .
SELECT . . .
FROM tablea . . .
Timestamp programa

SQL Executor

SQL Object Code


(copy) Automatic
... SQL
SELECT . . . Recompilation
FROM tablea . . . Rewrites Area

Timestamp programa

Catalog

Timestamp programa VST0507.vsd

HP NonStop SQL Programming Manual for TAL—527887-001


5-27
Program Compilation and Execution Understanding Run-Time Recompilation Errors

Understanding Run-Time Recompilation Errors


For automatic SQL recompilation of an entire program at run time, the SQL executor
returns compilation errors or warnings as follows:
• If an SQL statement causes an error or warning, the statement remains
uncompiled in the program file and the SQL executor suppresses the error or
warning message.
• If the SQL executor subsequently tries to execute the uncompiled statement, the
SQL executor tries again to automatically recompile the statement. If the statement
still causes a compilation error or warning, the SQL executor returns a run-time
error message to the program.
At run time, a program receives SQL compiler errors only when the SQL statement that
produces the error executes.

Maximizing Local Autonomy


Local autonomy in a network-distributed database ensures that a program can access
data on the local system, regardless of the availability of remote SQL objects. If your
program accesses a network-distributed database, you can maximize local autonomy
by:
• Using a local partition, rather than the primary partition, as the table name for
partitioned tables
• Using TACL DEFINEs
• Using current statistics
• Skipping unavailable partitions
For more information about managing applications for local autonomy, see the
SQL/MP Installation and Management Manual.

Using a Local Partition


If your program uses a remote partition, the SQL compiler looks for information about
the table in a remote catalog. If the remote system is down, the SQL compilation fails.
However, if your program uses a local partition, the SQL compiler looks for the
information in a local catalog. Provided the local system and data are available, the
SQL compilation is successful.

HP NonStop SQL Programming Manual for TAL—527887-001


5- 28
Program Compilation and Execution Using TACL DEFINEs

This example shows the concept of maximizing local autonomy. The parts table is a
partitioned table that resides on the \NEWYORK and \CHICAGO systems:
\NEWYORK The first partition contains all rows in which PARTS.PARTNUM (the
primary key) is less than 5000.
\CHICAGO The second partition contains all rows in which PARTS.PARTNUM is 5000
or greater. An index on the PARTDESC column of table PARTS is named
IXPART.

A program declares a cursor defined as:


EXEC SQL DECLARE get_part_cursor CURSOR FOR
SELECT partnum, partdesc, price, qty_available
FROM =parts
WHERE parts.partnum < 5000
AND parts.partdesc = "V8 DISK OPTION";
The program running on \NEWYORK uses a TACL DEFINE named =PARTS to
associate the parts table with the first partition located at \NEWYORK:
SET DEFINE CLASS MAP
ADD DEFINE =parts, FILE \newyork.$vol1.sales.parts
If \CHICAGO is unavailable at compile time, the SQL compiler can still compile the
program because enough information is available in the catalogs on \NEWYORK
where the first partition is registered.
Assume that the compiler uses the index on \CHICAGO in the optimized execution
plan. If \CHICAGO is still unavailable at run time, the SQL executor invokes the SQL
compiler to automatically recompile the statement. The SQL compiler determines an
execution plan that does not use the index IXPART but will sequentially scan the rows
in the first partition to find all parts that have “V8 DISK OPTION” in the PARTDESC
column.

Using TACL DEFINEs


By using TACL DEFINEs in a program to refer to tables and associating those TACL
DEFINEs with local partitions, you increase the possibilities for successful compilations
of programs that access a distributed database. All SQL compilations are affected,
including explicit and dynamic compilations and automatic recompilations.

Using Current Statistics


For a partitioned table to have local autonomy, the UPDATE STATISTICS statement
must be executed on the table at least once. If the SQL catalog in which a table is
registered does not have any statistics for the table, the SQL optimizer does a catalog
look-up operation for each partition of the table to estimate the aggregate number of
nonempty blocks and records. Also, if the statistics for an unavailable partitioned table
have not been updated, you will receive an SQL warning and file-system error even if
your query does not try to retrieve any rows from the unavailable partition. Executing
the UPDATE STATISTICS statement eliminates both of these problems.

HP NonStop SQL Programming Manual for TAL—527887-001


5- 29
Program Compilation and Execution Skipping Unavailable Partitions

Skipping Unavailable Partitions


Use the SKIP UNAVAILABLE PARTITION option of the CONTROL TABLE directive to
cause NonStop SQL to skip a partition that is not available and to open the next
available partition that satisfies the search condition of a query. (NonStop SQL also
returns a warning message (8239) to the SQLCA.) The SKIP UNAVAILABLE
PARTITION option applies to static or dynamic SQL statements that refer to partitioned
tables and partitioned indexes of the tables.

Executing an SQL Program File


You execute an SQL program file as you would any program file by using the TACL
RUN (or RUND) command or a process-creation system procedure such as
NEWPROCESS. This subsection describes how to execute a program file from your
TACL process; for information about executing a program file using a system
procedure, see the Guardian Procedure Calls Reference Manual.
Before running the program file, you can specify TACL DEFINE, PARAM, and ASSIGN
commands for run-time parameters and control. For more information about these
commands, see the TACL Reference Manual.
NonStop SQL returns any run-time errors and warnings to the SQLCODE variable and
the SQL communications area (SQLCA) if it is declared. For information about error
processing, see Section 6, Error and Status Processing. For a list of errors and
warnings, see the SQL/MP Messages Manual.
For an SQL program file to execute, the file must be:
• Validated by the SQL compiler for execution
• Recorded in a PROGRAMS catalog table
To execute an SQL program file, you (or your application process if you use a process-
creation system procedure) must have access authority as follows:
• Read and execute authority to the program file
• Read authority to the catalog in which the program is registered
• Read authority to any catalog in which tables or views used by the program are
registered for SQL statements requiring automatic recompilation

Using the RUN Command


To execute an SQL program file from your TACL process, use the TACL RUN
command. You can enter a RUN command either explicitly or implicitly. For an explicit
RUN command, enter the keyword RUN (or RUND) followed by the program file. For

HP NonStop SQL Programming Manual for TAL—527887-001


5- 30
Program Compilation and Execution Using TACL DEFINEs

an implicit RUN command, enter only the name of the program file. The syntax for the
RUN command is:

[ RUN[D] ] program-file

[ / run-option [ , run-option ] ... / ] [ param-set ]

RUN
executes the program file without debugging.

RUND
executes the program file and initiates debugging under the control of INSPECT or
DEBUG.

program-file
is the name of the SQL program object file.

run-option
is a run option of the RUN command, as described in the TACL Reference Manual.

param-set
is a list of one or more parameters to pass to the program, with each parameter
separated by a space, as described in the TACL Reference Manual.

Using TACL DEFINEs


A DEFINE is a named set of attributes and associated values stored in the process file
segment (PFS) of a process. TACL DEFINEs allow you to specify information about a
process before you run the process. You specify this information by entering TACL
DEFINE commands at your TACL or SQLCI prompt, or by calling Guardian system
procedure calls (or a by a combination of both command and procedure calls).
With NonStop SQL, you can use TACL DEFINE names in your program to specify the
names of catalogs, tables, views, indexes, partitions, and other programs.
If you use TACL DEFINE names in SQL statements to refer to the above SQL objects,
follow the guidelines listed below. For more information about using TACL DEFINEs
with NonStop SQL, see the SQL/MP Reference Manual.

TAL Compilation
For TAL compilation, set TACL DEFINEs for any DEFINE names of tables or views you
use in INVOKE directives.

HP NonStop SQL Programming Manual for TAL—527887-001


5- 31
Program Compilation and Execution Estimating Program Size

SQL Compilation
statements. The SQL compiler registers programs in a catalog. If you are SQL
compiling an object file, you might want to use a DEFINE to specify the catalog.
For explicitly recompiling a program, you can specify the DEFINE set stored in the
program file by using the SQLCOMP command STOREDDEFINES option.
If you specify a DEFINE name in an SQL statement that is not present in your current
set of DEFINEs, the SQL compiler issues a warning message and leaves the
statement uncompiled in the object file. When you run your program, NonStop SQL
tries again to compile the SQL statement using automatic recompilation. If the SQL
compiler fails to find the DEFINE name this time, it issues an error message.

Program Execution
For program execution, set TACL DEFINEs for all DEFINE names used in SQL
statements if the current DEFINE set is not the same set used for SQL compilation. If
the current DEFINE set is different, the program is subject to automatic recompilation
as described on page 5-24.
Before issuing the RUN command, you can specify TACL DEFINE commands that
apply to SQL statements in the program. You can create, modify, delete, and display
DEFINEs with TACL commands or Guardian system procedure calls. You can also
specify the =_SORT_DEFAULTS DEFINE to control sort operations. However, if you
modify a DEFINE after SQL load time, the change has no effect on static SQL
statements.
To determine the DEFINE set with which a program was compiled, use the EXPLAIN
DEFINES option of the SQLCOMP command.
When the process begins execution, it receives your current set of DEFINE values
from the process file segment (PFS) of your TACL process, provided the DEFMODE
option is ON. If DEFMODE is OFF, TACL propagates only your =_DEFAULTS DEFINE
to the new process.

Estimating Program Size


A program that uses embedded SQL statements and directives to access a NonStop
SQL database uses much more memory than a program that accesses an Enscribe
database. This subsection describes how to estimate the virtual memory used by
embedded SQL statements and directives in a program’s extended data segment.
Some statements require no extra extended memory, but other statements generate a
run-time call to the SQL executor and do use extra memory. The SQL executor uses
extended memory to run and the memory shown below for parameters and data
structures.

HP NonStop SQL Programming Manual for TAL—527887-001


5- 32
Program Compilation and Execution Estimating Program Size

These structures are shared by all SQL statements and directives in a program:
Bytes Structure Description
430 SQLCA Count once if you specify INCLUDE SQLCA
838 SQLSA Count once if you specify INCLUDE SQLSA

Use this table to estimate the number of bytes used by each embedded SQL statement
and directive in the extended data segment.

Table 5-1. Calculating Virtual Memory Requirements for Each SQL Statement or
Directive
Bytes Required Description of SQL Statement
72 Base value for a statement with no host variables
+ 4 + (24 * number of input host Required for a statement with input host variables
variables)
+ 4 + (24 * number of output host Required for a statement with output host variables
variables)
+ 146 Required for a static SQL statement that uses a
cursor declared in the global area of the program

Follow these guidelines when you use this table:


• Count a host variable once per occurrence.
• Count only these SQL statements and directives (which generate a run-time call to
the SQL executor):
ALTER DROP LOCK TABLE
BEGIN WORK END WORK OPEN
CLOSE EXECUTE RELEASE
COMMENT EXECUTE IMMEDIATE ROLLBACK WORK
CREATE FETCH SELECT
DELETE FREE RESOURCES UNLOCK TABLE
DESCRIBE HELP TEXT UPDATE
DESCRIBE INPUT INSERT UPDATE STATISTICS

Do not count:
BEGIN DECLARE SECTION and END DECLARE SECTION
CONTROL EXECUTOR, CONTROL QUERY, and CONTROL TABLE
DECLARE CURSOR
INVOKE
WHENEVER

HP NonStop SQL Programming Manual for TAL—527887-001


5- 33
Program Compilation and Execution Estimating Program Size

Caution. The system allocates real memory in 2 KB pages. If an SQL statement uses only
part of a page, the system allocates the entire page. Therefore, the real memory used by
embedded SQL statements can be larger than the figures shown in Table 5-1 on page 5-33.

A program can encounter memory problems in these cases:

• It contains a large number of embedded SQL statements.

• It runs on a system with limited memory (for example, 16 MB or less).

• It runs in a processor that is also running a large number of other programs.

To reduce the memory use in the extended data segment, follow these guidelines:

• Declare only the host variables that your program actually requires.

• Declare all host variables in one Declare Section if possible. The system allocates the host
variables contiguously in one or more pages, rather than allocating each host variable in a
separate page.

• Execute SQL statements in listing order as often as possible. Thus, the SQL statements
can share many of the pages in the extended data segment.

• As a last measure, use dynamic SQL statements. Using dynamic SQL statements can
reduce memory use; however, it also can degrade a program’s performance because of
the additional SQL run-time compilations.

HP NonStop SQL Programming Manual for TAL—527887-001


5- 34
6 Error and Status Processing
NonStop SQL returns error and status information to an application program following
the execution of each embedded SQL statement. NonStop SQL returns some
information to the integer SQLCODE variable and more extensive information to these
data structures:
• SQL communications area (SQLCA). The SQLCA contains run-time information
including errors and warnings generated by the most recently executed dynamic or
static SQL statement.
• SQL descriptor area (SQLDA). The SQLDA contains information about input
parameters and output variables in dynamic SQL statements.
• SQL statistics area (SQLSA). The SQLSA contains statistics and performance
information after the execution of DML and some dynamic SQL statements.
This section describes how to check the SQLCODE variable and the SQL data
structures to get information about:
• Errors and warnings after the execution of SQL statements
• Performance and statistics after the execution of SQL statements
• Dynamic SQL operations

Getting Error and Warning Information


NonStop SQL provides these methods you can use to check for and process errors
and warnings in your program:
• Checking the value of the SQLCODE variable
• Using the WHENEVER directive
• Checking information in the SQLCA

Using the SQLCODE Variable


NonStop SQL returns status to the SQLCODE variable after the execution of each
embedded SQL statement. The SQLCODE variable can have these values:
Value Status
<0 Error
>0 Warning
0 Successful

Each NonStop SQL message has an assigned code number that is returned to
SQLCODE. For the values for SQLCODE and their meanings, see the SQL/MP
Messages Manual.

HP NonStop SQL Programming Manual for TAL—527887-001


6-1
Error and Status Processing Using the SQLCODE Variable

Declaring the SQLCODE Variable


Declare SQLCODE in your program as an integer variable:
INT SQLCODE;
If you omit the SQLCODE declaration, the compiler generates an “undeclared
identifier” error. The SQLCODE variable must be declared within scope of the
embedded SQL statement that you will execute. To ensure SQLCODE is always in this
scope, declare SQLCODE as a global variable at the start of each module that
contains embedded SQL statements.

Checking the SQLCODE Variable


Figure 6-1 shows an example that inserts two column values into the PARTS table and
checks for errors using the SQLCODE variable.

HP NonStop SQL Programming Manual for TAL—527887-001


6-2
Error and Status Processing Using the SQLCODE Variable

Figure 6-1. Checking the SQLCODE Variable

! Variable declarations
EXEC SQL BEGIN DECLARE SECTION;
STRUCT .in^parts^rec;
BEGIN
INT in^partnum;
FIXED(2) in^price;
STRING in^partdesc[0:17];
END;
EXEC SQL END DECLARE SECTION;
EXEC SQL INCLUDE SQLCA; ! Include the SQLCA structure !
! for detailed error information !
INT SQLCODE; ! Include the SQLCODE variable !
! for simple error checking !
. . .
PROC driver MAIN;
BEGIN
! Blank fill in^partdesc:
in^parts^rec.in^partdesc ':='
[ $OCCURS(in^parts^rec.in^partdesc) * [" "] ] ;
! Begin TMF transaction and check SQLCODE:
EXEC SQL BEGIN WORK;
IF SQLCODE < 0 THEN CALL handle^errors;
IF SQLCODE > 0 AND SQLCODE <> 100 THEN
CALL handle^warnings;
! Do an SQL INSERT into the parts table:
in^parts^rec.in^partnum := 4120;
in^parts^rec.in^price := 60000.00;
in^parts^rec.in^partdesc ':=' "V8 DISK OPTION";
EXEC SQL
INSERT INTO sales.parts (partnum, price, partdesc)
VALUES ( :in^parts^rec.in^partnum,
:in^parts^rec.in^price,
:in^parts^rec.in^partdesc);
! Check SQLCODE for errors and warnings:
IF SQLCODE < 0 THEN CALL handle^errors;
IF SQLCODE > 0 AND SQLCODE <> 100 THEN
CALL handle^warnings;
! End TMF transaction and check SQLCODE:
EXEC SQL COMMIT WORK;
IF SQLCODE < 0 THEN CALL handle^errors;
IF SQLCODE > 0 AND SQLCODE <> 100 THEN
CALL handle^warnings; VST0601.vsd
END;

HP NonStop SQL Programming Manual for TAL—527887-001


6-3
Error and Status Processing Using the WHENEVER Directive

Using the WHENEVER Directive


The WHENEVER directive specifies an action that a program takes depending on the
outcome of subsequent DML, DCL, and DDL SQL statements. WHENEVER provides
tests for these conditions:
• An error occurred.
• A warning occurred.
• No rows were found.
You can specify a WHENEVER directive anywhere in your program. When you specify
this directive, the TAL compiler inserts statements that perform run-time checking after
the SQL statement using the SQLCODE variable. Table 6-1 shows the TAL compiler
pseudocode used to check SQLCODE and the order in which the checks are made.

Table 6-1. TAL Compiler Pseudocode for Checking SQLCODE


Order Condition Compiler Pseudocode
1 NOT FOUND IF SQLCODE = 100 THEN action-specification ;
2 SQLERROR IF SQLCODE < 0 THEN action-specification ;
3 SQLWARNING IF SQLCODE > 0 AND
SQLCODE <> 100 THEN action-specification ;
action-specification is one of:
CALL : procedure-name ;
GOTO : label-name ;
GO TO : label-name ;
CONTINUE ;

Each WHENEVER directive independently applies to the SQL statement. For example,
specifying a WHENEVER SQLWARNING directive does not affect the checking for a
WHENEVER SQLERROR or a WHENEVER NOT FOUND directive.

Determining the Scope of a WHENEVER Directive


The order that a WHENEVER directive appears in a program determines its scope.
Some points to consider are:
• A WHENEVER directive is in effect until another WHENEVER directive for the
same condition appears.
• If a WHENEVER directive is coded in a procedure, the directive remains in effect
outside of the procedure even if the scope of the procedure is no longer valid.
Therefore, if you do not want the directive to remain in effect, disable it at the end
of the procedure as described in the next subsections.
• A program’s order includes any files that are copied into the program using a
SOURCE directive. If a copied file contains a WHENEVER directive, that directive
is in effect following the SOURCE directive.

HP NonStop SQL Programming Manual for TAL—527887-001


6-4
Error and Status Processing Using the WHENEVER Directive

• A WHENEVER directive does not affect SQL statements if they appear in the
program before the WHENEVER directive.
• If you are debugging a program and you use a WHENEVER directive to call an
error handling procedure, you might need to save the SQLCODE value in a local
variable within the error handling procedure. Each subsequent SQL statement
resets SQLCODE, and you might lose a value you need to debug your program.

Enabling and Disabling the WHENEVER Directive


You can enable and disable the WHENEVER directive for different parts of your
program. For example, you might want to handle SQL errors by checking the
SQLCODE variable after an SQL statement instead of using WHENEVER
SQLERROR.
This example shows how to enable and disable condition checking for the
WHENEVER directive:
EXEC SQL
WHENEVER SQLERROR CALL :error^proc; ! Enables checking
...
EXEC SQL
WHENEVER SQLERROR; ! Disables checking
To avoid an infinite loop if the error handling code generates errors or warning, you can
disable the WHENEVER directive within the error handling procedure. An infinite loop
can occur when the:
• SQLERROR condition executes a statement that generates an error
• SQLWARNING condition executes a statement that generates a warning
• NOT FOUND condition executes a statement that generates a NOT FOUND
condition
To avoid these situations, disable the appropriate WHENEVER directive for the part of
your program that handles each condition. Figure 6-2 shows an example that enables
and disables the directive.

HP NonStop SQL Programming Manual for TAL—527887-001


6-5
Error and Status Processing Using the WHENEVER Directive

Figure 6-2. Enabling and Disabling the WHENEVER Directive

EXEC SQL WHENEVER SQLERROR CALL :error^handler;


PROC proc^1(i, j, k);
INT i;
INT j;
INT k;
BEGIN
EXEC SQL SELECT ...;
EXEC SQL SELECT ...;
EXEC SQL SELECT ...;
END;
PROC proc^2(i, j, k);
INT i;
INT j;
INT k;
BEGIN
EXEC SQL SELECT ...;
EXEC SQL SELECT ...;
EXEC SQL SELECT ...;
END;
! Reset SQLERROR checking while in error handler:
EXEC SQL WHENEVER SQLERROR;
PROC error^handler;
BEGIN
CALL SQLCADISPLAY(sqlca);
CALL ABEND;
END;

! Reenable SQLERROR checking after error^handler:


EXEC SQL WHENEVER SQLERROR CALL :error^handler;
PROC driver MAIN;
INT a;
INT b;
INT c;
BEGIN
CALL proc^1(a, b, c);
CALL proc^2(c, b, a);
EXEC SQL INSERT...; VST0602.vsd

END;

HP NonStop SQL Programming Manual for TAL—527887-001


6-6
Error and Status Processing Using the WHENEVER Directive

Using the CALL Format


If you use the CALL format of WHENEVER to call an error handling procedure, follow
these guidelines:
• Specify the WHENEVER directive globally and precede the directive with a forward
declaration of the error handling procedure(s).
• Declare the error handling procedure or subprocedure without parameters, and do
not allow it to return a value.
• Ensure that the error handling procedure or subprocedure you call is accessible
from each SQL statement affected by the WHENEVER directive.

Using the GOTO Format


If you use the GOTO (or GO TO) format, specify the WHENEVER directive at the
beginning of the procedure containing the GOTO and disable it at the end of the
procedure. For example:
PROC error^proc;
BEGIN
EXEC SQL WHENEVER SQLERROR GOTO :error^handler;
RETURN;
...
error^handler:
... ! error handling routine
EXEC SQL WHENEVER SQLERROR; ! Disable WHENEVER
END; ! End of error^proc

Using an Aggregate Function


All aggregate functions except COUNT return a null value when operating on an empty
set. If a host variable receives the null value as the result of an aggregate function, you
must specify an indicator variable and test the result of the indicator variable.
Otherwise, NonStop SQL returns a “no indicator variable provided” condition instead of
a “no rows found” condition. A WHENEVER NOT FOUND directive does not detect this
condition.

Example of Using WHENEVER Directives


This example inserts two column values into the PARTS table and checks for errors
using WHENEVER directives. The WHENEVER SQLWARNING and WHENEVER
SQLERROR directives refer to parts of the program that handle the respective
condition.

HP NonStop SQL Programming Manual for TAL—527887-001


6-7
Error and Status Processing Using the WHENEVER Directive

Figure 6-3. Using WHENEVER Directives

! Variable declarations:
EXEC SQL BEGIN DECLARE SECTION;
STRUCT .in^parts^rec;
BEGIN
INT in^partnum;
FIXED(2) in^price;
STRING in^partdesc[0:17];
END;
EXEC SQL END DECLARE SECTION;
! Include the SQLCA for detailed error information:
EXEC SQL INCLUDE SQLCA;
! Include SQLCODE for simple error checking:
INT SQLCODE;
! Forward declare error handling code:
PROC handle^warnings; FORWARD;
PROC handle^errors; FORWARD;
! Specify WHENEVERs globally, for errors and warnings:
EXEC SQL WHENEVER SQLWARNING CALL :handle^warnings;
EXEC SQL WHENEVER SQLERROR CALL :handle^errors;
PROC DRIVER MAIN;
BEGIN
! Blank fill in^partdesc:
in^parts^rec.in^partdesc ':='
[ $OCCURS(in^parts^rec.in^partdesc) * [" "] ] ;
! Begin the TMF transaction:
EXEC SQL BEGIN WORK;
in^parts^rec.in^partnum := 4120;
in^parts^rec.in^price := 60000.00;
in^parts^rec.in^partdesc ':=' "V8 DISK OPTION";
! Execute an SQL INSERT into the parts table:
EXEC SQL
INSERT INTO =parts (partnum, price, partdesc)
VALUES ( :in^parts^rec.in^partnum,
:in^parts^rec.in^price,
:in^parts^rec.in^partdesc);
! End the TMF transaction:
EXEC SQL COMMIT WORK; VST0603.vsd

END;

HP NonStop SQL Programming Manual for TAL—527887-001


6-8
Error and Status Processing Getting Information From the SQLCA

Getting Information From the SQLCA


NonStop SQL returns run-time information, including errors and warnings, for the most
recently executed SQL statement to the SQL communication area (SQLCA). The
SQLCA is the primary status checking area for application programs because it
contains more detailed information than the SQLCODE variable. The compiler
initializes the SQLCA before each executable SQL statement.

Declaring the SQLCA Structure


Use the INCLUDE SQLCA directive to declare the SQLCA in the variable declarations
part of your TAL program. If the SQLCA must always be accessible to all parts of your
program, include the INCLUDE SQLCA directive with your global variable declarations.
The syntax is:

INCLUDE SQLCA

An example of the INCLUDE SQLCA directive is:


! Global declarations:
EXEC SQL
INCLUDE SQLCA;
...

Using System Procedures With the SQLCA Structure


Table 6-2 shows SQL system procedures you can use to retrieve and display
information from the SQLCA structure.

Table 6-2. System Procedures for the SQLCA Structure


System Procedure Description
SQLCADISPLAY Writes to a file or to a terminal the error or warning messages
returned to the program by SQL
SQLCAGETINFOLIST Writes to a record area in the program a subset (which you
specify) of the error or warning information in the SQLCA
SQLCATOBUFFER Writes to a record area in the program the error or warning
messages returned to the program by SQL
SQLCAFSCODE Returns information about file-system, disk-process, or NonStop
Kernel operating system errors

To include declarations for these procedures in your program, use the SOURCE
directive for the EXTDECS file.
Figure 6-4 shows an example that calls the SQLCADISPLAY procedure.

HP NonStop SQL Programming Manual for TAL—527887-001


6-9
Error and Status Processing Getting Performance and Statistics Information

Figure 6-4. Calling an SQL System Procedure

?SOURCE $system.system.extdecs (SQLCADISPLAY,


? SQLCAFSCODE
,
? SQLCAGETINFOLIST,
? SQLCATOBUFFER)

! Global declarations:

EXEC SQL INCLUDE SQLCA;

...
! Error handling routine:
...
CALL SQLCADISPLAY (SQLCA);
VST0604.vsd

...

If your program uses the NUMOUT procedure to display an error message, you must
remove the negative sign before displaying the error number. To avoid this situation,
use the INCLUDE SQLCA directive and then call the SQLCADISPLAY procedure to
display the error message.
For more information about SQL system procedures, see Section 4, System
Procedures

Getting Performance and Statistics


Information
NonStop SQL uses the SQL statistics area (SQLSA) to communicate statistics to a
TAL program. NonStop SQL returns a new set of statistics in the SQLSA following the
execution of these statements:
The OPEN, FETCH, SELECT, INSERT, UPDATE, and DELETE statements A
PREPARE statement that describes input parameters and output columns associated
with a dynamic SQL statement that was prepared Use the INCLUDE SQLSA directive
to declare the SQLSA in your program. The syntax is:

INCLUDE SQLSA

Place the INCLUDE SQLSA directive in your program with:


• Global declarations to use the SQLSA throughout your program
• Local declarations to use the SQLSA for special purposes (for example, one
SQLSA for PREPARE statements and another SQLSA for DML statements)

HP NonStop SQL Programming Manual for TAL—527887-001


6- 10
Error and Status Processing Getting Performance and Statistics Information

Figure 6-5 shows the SQLSA structure generated in a TAL program by the INCLUDE
SQLSA directive. NonStop SQL generates this structure and inserts it in the program
following the INCLUDE SQLSA directive.

Figure 6-5. SQLSA Structure Description

STRUCT .sqlsa;
BEGIN
STRING eye^catcher[0:1];
INT version;
STRUCT dml;
BEGIN
INT num^tables;
STRUCT stats[0:15];
BEGIN
STRING table^name[0:23];
INT(32) records^accessed;
INT(32) records^used;
INT(32) disc^reads;
INT(32) messages;
INT(32) message^bytes;
INT waits;
INT escalations;
STRING sqlsa^reserved[0:3];
END; -- stats
END; -- dml
STRUCT prepare = dml;
BEGIN
INT input^num;
INT input^names^len;
INT output^num;
INT output^names^len;
INT name^map^len;
INT sql^statement^type;
END; -- prepare
VST0605.vsd
END; -- sqlsa

Table 6-3 describes the fields in the SQLSA data structure.

Table 6-3. SQLSA Fields (page 1 of 3)


Field Name Description
EYE^CATCHER Identification field, set by the system to SA.
VERSION Current version of the SQLSA; subsequent NonStop SQL
software releases can change this version ID.
DML Structure where statistics on DML statement execution are
returned.

HP NonStop SQL Programming Manual for TAL—527887-001


6-11
Error and Status Processing Getting Performance and Statistics Information

Table 6-3. SQLSA Fields (page 2 of 3)


Field Name Description
NUM^TABLES Number of tables accessed by a DML statement. Maximum
is 16.
STATS Array containing NUM^TABLES valid entries, one for each
table accessed.
TABLE^NAME Guardian internal file name of the table accessed.
RECORDS^ACCESSED Number of records accessed in the corresponding table.
RECORDS^USED Number of records altered or returned.
DISC^READS Number of disk reads and writes.
MESSAGES Number of messages sent to the disk process.
MESSAGE^BYTES Number of bytes sent in all the messages sent to the disk
process.
WAITS Number of lock waits or timeouts.
ESCALATIONS Number of times record locks are escalated to file locks.
SQLSA^RESERVED Reserved
PREPARE Structure to which statistics on a PREPARE statement are
returned. This structure applies only for dynamic SQL. The
information provided is used by your program to allocate
the buffers required to describe the prepared statement.
INOUT^NUM Number of input parameters in the prepared statement.
INPUT^NAMES^LENGTH Length of the buffer required to contain names of input
parameters.

HP NonStop SQL Programming Manual for TAL—527887-001


6-12
Error and Status Processing Getting Information About Dynamic SQL Operations

Table 6-3. SQLSA Fields (page 3 of 3)


Field Name Description
OUTPUT^NUM Number of output variables in the prepared statement.
Output variables are SELECT columns or LASTSYSKEY
on INSERT RETURNING.
OUTPUT^NAMES^LENGTH Length of buffer required to contain names of output
variables.
NAME^MAP^USE Reserved for system use SQL^STATEMENT^TYPE Type
of statement being prepared. This literal declarations
represent the values for this field:
_SQL_STATEMENT_SELECT Cursor SELECT
_SQL_STATEMENT_INSERT Insert
_SQL_STATEMENT_UPDATE Update
_SQL_STATEMENT_DELETE Delete
_SQL_STATEMENT_DDL DDL statement
_SQL_STATEMENT_CONTROL Run-time CONTROL
TABLE
_SQL_STATEMENT_DCL Lock, unlock, or FREE
RESOURCES
To use these declarations, include the TALDECS file in
your program with a SOURCE directive:

?SOURCE $ vol. subvol.TALDECS

Getting Information About Dynamic SQL


Operations
NonStop SQL uses the SQL descriptor area (SQLDA) to provide information about
input parameters and output variables in dynamic SQL statements. The SQLDA also
provides pointers to data buffers that your program uses to set values for input
parameters and to receive values for output variables. The names buffer, which you
can generate with the SQLDA or declare separately, receives the names of the input
parameters or output variables.
You can use the SQLDA data structure in:
• A DESCRIBE INPUT statement to get information about input parameters
• A DESCRIBE statement to get information about output columns
• The USING DESCRIPTOR clause of a FETCH statement to fill a cursor with rows
from an SQL table
• The USING DESCRIPTOR clause of an EXECUTE statement to execute an
dynamic SQL statement

HP NonStop SQL Programming Manual for TAL—527887-001


6-13
Error and Status Processing Declaring the SQLDA and Names Buffer

Declaring the SQLDA and Names Buffer


Use the INCLUDE SQLDA directive to declare a structure template for the SQLDA in a
TAL program using dynamic SQL statements. The syntax is:

INCLUDE SQLDA ( sqlda-name [ , sqlvar-count ]

[ , names-buffer-name, name-string-size ]

[ , { RELEASE1 | RELEASE2 } ])

sqlda-name
is the SQLDA structure name.

sqlvar-count
is the number of parameters for which you expect to specify input values or
number of columns for which you expect to receive output values. The default is 1.

names-buffer-name
is the SQLDA names buffer

name-string-size
is the number of characters in the longest parameter or column name expected in
the DESCRIBE or DESCRIBE INPUT statement.
A qualified column name can be from 1 to 30 characters long and is in the format:
table-name.column-name
A parameter name is an SQL identifier with a maximum of 30 characters.

RELEASE1 or RELEASE2
is the NonStop SQL release. The default is the release of the TAL compiler, unless it is
overridden by the release option parameter in the SQL directive.
Follow these guidelines when you use INCLUDE SQLDA:
• Supply a place-holder value for the parameters or columns and the length of the
names buffer. Then allocate memory as needed.
• Indicator variable names appear in the names buffer. If the names are short, the
INCLUDE SQLDA directive generates sufficient space for them; however, if the
names are long and you use many indicator variables, you should explicitly
allocate the names buffer separately from the INCLUDE SQLDA statement.

HP NonStop SQL Programming Manual for TAL—527887-001


6-14
Error and Status Processing Declaring the SQLDA and Names Buffer

Figure 6-6 and Figure 6-7 on page 6-16 show structure templates generated by the
INCLUDE SQLDA directive for NonStop SQL Release 1 and Release 2.
Figure 6-6. Release C30 SQLDA Template and Names Buffer

LITERAL SQLDA^EYE^CATCHER = "D1";

STRUCT sqlda-name (*) ;


BEGIN
STRING eye^catcher[0:1];
INT num^entries;
STRUCT sqlvar[0: sqlvar-count - 1];
BEGIN
INT data^type;
INT data^len;
! fields for NUMBERS:
! scale = data^len.<0:7>
! length = data^len.<8:15>
! fields for DATETIME or INTERVAL:
! qualifier = data^len.<0:7>
! length = data^len.<8:15>
INT precision;
! fields for DATETIME or INTERVAL:
! leading field precision = precision.<0:7>
! fraction precision = precision.<8:15>
INT null^info;
INT(32) var^ptr;
INT(32) ind^ptr;
FIXED reserved;
END;
END;
VST0606.vsd
STRING . names-buffer-name[ 0 : length - 1 ];

HP NonStop SQL Programming Manual for TAL—527887-001


6-15
Error and Status Processing Declaring the SQLDA and Names Buffer

Figure 6-7. Release C10 SQLDA Template and Names Buffer

LITERAL SQLDA^EYE^CATCHER^R1 = "DA";

STRUCT sqlda-name (*) ;


BEGIN
STRING eye^catcher[0:1];
INT num^entries;
STRUCT sqlvar[0: sqlvar-count - 1 ];
BEGIN
INT data^type;
INT data^len;
! fields for NUMBERS:
! scale = data^len.<0:7>
! length = data^len.<8:15>
INT null^info;
INT(32) var^ptr;
INT(32) reserved;
END;
END;

STRING . names-buffer-name[ 0 : length - 1 ];


VST0607.vsd

The SQL compiler determines length in bytes for the names buffer using this formula:
length = ( name-string-size + 11 ) * sqlvar-count
The compiler derives the 11 bytes added to the name-string-size from the:
length field 2 bytes
table name 8 bytes
separator ( – ) 1 byte

Table 6-4 describes each field in the SQLDA.

HP NonStop SQL Programming Manual for TAL—527887-001


6-16
Error and Status Processing Declaring the SQLDA and Names Buffer

Table 6-4. SQLDA Fields (page 1 of 2)


Field Name Description
SQLDA^EYE^CATCHER A constant declared by the system. If you requested an SQLDA
structure of a release that is different from the release of the
SQL compiler, SQLDA^EYE^CATCHER appears as either
SQLDA^EYE^CATCHER^R1 or SQLDA^EYE^CATCHER^R2.
EYE^CATCHER Identifying field that your program must initialize with the
system-declared SQLDA^EYE^CATCHER literal. NonStop SQL
statements do not return values to EYE^CATCHER.
NUM^ENTRIES Number of input parameters or output variables this SQLDA
structure can accommodate. If your program used INCLUDE
SQLDA, TAL sets NUM^ENTRIES to the number you specified
for sqlvar^count. If your program allocated the SQLDA
dynamically, the program must supply a value for
NUM^ENTRIES.
SQLVAR Descriptions for input parameters or output variables. The
DESCRIBE INPUT and DESCRIBE statement returns one
SQLVAR entry for each input parameter or each output
variable.
DATA^TYPE Data type of the parameter or output variable.
DATA^LEN The length in DATA^LEN depends on the data type as follows:
• For a fixed-length character string, DATA^LEN contains the
number of characters in the string.
• For a variable-length character string, DATA^LEN contains
the maximum number of characters allowed in the string
(not including the two bytes of length).
• For both binary and decimal numeric items, DATA^LEN
bits 0:7 contain the decimal scale of the item.
• For a binary numeric item, DATA^LEN bits 8:15 contain the
byte length of the item (2, 4, or 8).
• For a decimal numeric item, DATA^LEN bits 8:15 contain
the byte length of the item (the number of characters).
• For a DATETIME or INTERVAL item, DATA^LEN bits 0:7
contain a code for the range of DATETIME fields. Bits 8:15
contain the storage size for the item.
PRECISION * PRECISION depends on the data type as follows:
For a FLOAT or binary numeric column, PRECISION contains
the numeric precision.
For a date-time or INTERVAL item, PRECISION bits 0:7
contain the leading field precision. Bits 8:15 contain the fraction
precision. If the FRACTION field is not included, bits 8:15 are
0.

HP NonStop SQL Programming Manual for TAL—527887-001


6-17
Error and Status Processing Initializing the EYE^CATCHER Field

Table 6-4. SQLDA Fields (page 2 of 2)


Field Name Description
NULL^INFO * For input parameters, NULL^INFO contains a negative integer
if the parameter could contain a null value.
For output columns, NULL^INFO contains a negative integer if
the column could contain a null value. (To verify whether the
parameter or column is really null, check for a negative value at
the location shown in IND^PTR).
VAR^PTR VAR^PTR is the extended address of the actual data (the value
of the input parameter or output column). The extended
address is not returned by NonStop SQL; your program must
initialize VAR^PTR to point to the input and output data buffers.
IND^PTR * IND^PTR is the extended address of a flag that indicates
whether or not a parameter or column is actually null.
If your program must process null values, initialize IND^PTR to
a valid address. For input parameters, the program then sets
the flag pointed to by IND^PTR to -1 if the parameter is null
and 0 if the parameter is not null. For output columns, NonStop
SQL initializes the flag pointed to by IND^PTR to -1 if the
column is null and to 0 if the column is not null.
If your program does not need to process null values, initialize
IND^PTR to an invalid address.
* This data item is generated only when you specify RELEASE2 in the INCLUDE SQLDA directive.

Initializing the EYE^CATCHER Field


To initialize the EYE^CATCHER field in the SQLDA, use the SQLDA^EYE^CATCHER
literal declaration:
sqlda^name.EYE^CATCHER ':=' SQLDA^EYE^CATCHER;
where sqlda^name is the SQLDA in your program.
If you specify an SQLDA structure with a release that is different from the release of
the SQL compiler, NonStop SQL appends an _R1 or _R2 to SQLDA_EYE_CATCHER
declaration. For example, you are using NonStop SQL release C30 and you specify a
C10 SQLDA structure, the flag ^R1 is appended to the SQLDA^EYE^CATCHER
declaration (SQLDA^EYE^CATCHER^R1).

Using Literal Declarations for the SQLDA


Use the literal declarations in the TALDECS file as values in the SQLDA DATA^TYPE
and PRECISION fields. To include these declarations in your program, use the
SOURCE directive. For example:
?SOURCE $ volume. subvol.TALDECS
Table 6-5 and Table 6-6 show the literal declarations in the TALDECS file.

HP NonStop SQL Programming Manual for TAL—527887-001


6-18
Error and Status Processing Using Literal Declarations for the SQLDA

Table 6-5. Literal Declarations for Character, Numeric, and Decimal Values
Type of Data Value Literal Declaration
Character Data
ASCII (fixed-length string) 0 _SQLDT_ASCII_F
ASCII (fixed-length string, upshifted) 1 _SQLDT_ASCII_F_UP
ASCII (variable-length string) 64 _SQLDT_ASCII_V
ASCII (variable-length string, upshifted) 65 _SQLDT_ASCII_V_UP
Numeric Data
16-bit signed (signed SMALLINT) 130 _SQLDT_16BIT_S
16-bit unsigned (unsigned SMALLINT) 131 _SQLDT_16BIT_U
32-bit signed (signed INT) 132 _SQLDT_32BIT_S
32-bit unsigned (unsigned INT) 133 _SQLDT_32BIT_U
64-bit signed (signed LARGEINT) 134 _SQLDT_64BIT_S
32-bit floating point 140 _SQLDT_REAL
64-bit floating point 141 _SQLDT_DOUBLE
Decimal Data
Unsigned DECIMAL 150 _SQLDT_DEC_U
DECIMAL, leading sign separate (not SQL type) 151 _SQLDT_DEC_LSS
ASCII DECIMAL, leading sign embedded 152 _SQLDT_DEC_LSE
DECIMAL, trailing sign separate (not SQL type) 153 _SQLDT_DEC_TSS
DECIMAL, trailing sign embedded (not SQL type) 154 _SQLDT_DEC_TSE

For a date-time or interval item, bits 0:7 of the DATA^LEN field in the SQLDA contain a
code for the range of date-time fields. Table 6-6 shows the literal declarations defined
to represent these codes.
Table 6-6. Literal Declarations for Date-Time and INTERVAL Values (page 1 of 2)
Type of Data Value Literal Declaration
General DATETIME 192 _SQLDT_DATETIME
Literal Declarations for Interval Data Types
YEAR TO YEAR 195 _SQLDT_INT_Y_Y
MONTH TO MONTH 196 _SQLDT_INT_MO_MO
YEAR TO MONTH 197 _SQLDT_INT_Y_MO
DAY TO DAY 198 _SQLDT_INT_D_D
HOUR TO HOUR 199 _SQLDT_INT_H_H
DAY TO HOUR 200 _SQLDT_INT_D_H
MINUTE TO MINUTE 201 _SQLDT_INT_MI_MI
HOUR TO MINUTE 202 _SQLDT_INT_H_MI

HP NonStop SQL Programming Manual for TAL—527887-001


6-19
Error and Status Processing Using Literal Declarations for the SQLDA

Table 6-6. Literal Declarations for Date-Time and INTERVAL Values (page 2 of 2)
Type of Data Value Literal Declaration
DAY TO MINUTE 203 _SQLDT_INT_D_MI
SECOND TO SECOND 204 _SQLDT_INT_S_S
MINUTE TO SECOND 205 _SQLDT_INT_MI_S
HOUR TO SECOND 206 _SQLDT_INT_H_S
DAY TO SECOND 207 _SQLDT_INT_D_S
FRACTION TO FRACTION 208 _SQLDT_INT_F_F
SECOND TO FRACTION 209 _SQLDT_INT_S_F
SECOND TO FRACTION 209 _SQLDT_INT_S_F
MINUTE TO FRACTION 210 _SQLDT_INT_MI_F
HOUR TO FRACTION 211 _SQLDT_INT_H_F
DAY TO FRACTION 212 _SQLDT_INT_D_F

Table 6-7. Literal Declarations for Ranges of Date-Time Fields (page 1 of 2)


Range of Fields Value Literal Declaration
YEAR TO YEAR 1 _SQLDT_INT_QUAL_Y_Y
MONTH TO MONTH 2 _SQLDT_INT_QUAL_MO_MO
DAY TO DAY 3 _SQLDT_INT_QUAL_D_D
HOUR TO HOUR 4 _SQLDT_INT_QUAL_H_H
MINUTE TO MINUTE 5 _SQLDT_INT_QUAL_MI_MI
SECOND TO SECOND 6 _SQLDT_INT_QUAL_S_S
FRACTION TO FRACTION 7 _SQLDT_INT_QUAL_F_F
YEAR TO MONTH 8 _SQLDT_INT_QUAL_Y_MO
YEAR TO DAY 9 _SQLDT_INT_QUAL_Y_D
YEAR TO HOUR 10 _SQLDT_INT_QUAL_Y_H
YEAR TO MINUTE 11 _SQLDT_INT_QUAL_Y_MI
YEAR TO SECOND 12 _SQLDT_INT_QUAL_Y_S
YEAR TO FRACTION 13 _SQLDT_INT_QUAL_Y_F
MONTH TO DAY 14 _SQLDT_INT_QUAL_MO_D
MONTH TO HOUR 15 _SQLDT_INT_QUAL_MO_H
MONTH TO MINUTE 16 _SQLDT_INT_QUAL_MO_MI
MONTH TO SECOND 17 _SQLDT_INT_QUAL_MO_S
MONTH TO FRACTION 18 _SQLDT_INT_QUAL_MO_F
DAY TO HOUR 19 _SQLDT_INT_QUAL_D_H
DAY TO MINUTE 20 _SQLDT_INT_QUAL_D_MI

HP NonStop SQL Programming Manual for TAL—527887-001


6-20
Error and Status Processing Example of Using the SQLDA

Table 6-7. Literal Declarations for Ranges of Date-Time Fields (page 2 of 2)


Range of Fields Value Literal Declaration
DAY TO SECOND 21 _SQLDT_INT_QUAL_D_S
DAY TO FRACTION 22 _SQLDT_INT_QUAL_D_F
HOUR TO MINUTE 23 _SQLDT_INT_QUAL_H_MI
HOUR TO SECOND 24 _SQLDT_INT_QUAL_H_S
HOUR TO FRACTION 25 _SQLDT_INT_QUAL_H_F
SECOND TO SECOND 26 _SQLDT_INT_QUAL_S_S
SECOND TO FRACTION 27 _SQLDT_INT_QUAL_S_F
FRACTION TO FRACTION 28 _SQLDT_INT_QUAL_F_F

Example of Using the SQLDA


Assume you declare an SQLDA structure named SQLDAX and a names buffer named
NAMEBUF for allocation during compilation. The SQLDA structures must reserve
space for the 20 columns you plan to use in dynamic SQL statements. The names
buffer must reserve space for column names with a maximum length of 30 characters.
You code the INCLUDE SQLDA directive as:
EXEC SQL
INCLUDE SQLDA ( sqldax, 20, namebuf, 30 );
...
Figure 6-8 shows the SQLDA structure template generated by the TAL compiler.

HP NonStop SQL Programming Manual for TAL—527887-001


6-21
Error and Status Processing Example of Using the SQLDA

Figure 6-8. SQLDA Structure Template

LITERAL SQLDA^EYE^CATCHER = "D1";


STRUCT SQLDAX (*);
BEGIN
STRING eye^catcher[0:1];
INT num^entries;
STRUCT sqlvar[0:19];
BEGIN
INT data^type;
INT data^len;
! fields for NUMBERS:
! scale = data^len.<0:7>
! length = data^len.<8:15>
! fields for DATETIME or INTERVAL:
! qualifier = data^len.<0:7>
! length = data^len.<8:15>
INT precision;
! fields for DATETIME or INTERVAL:
! leading field precision = precision.<0:7>
! fraction precision = precision.<8:15>
INT null^info;
INT(32) var^ptr;
INT(32) ind^ptr;
FIXED reserved;
END;
END;
STRING .namebuf [0:819]; VST0608.vsd

The compiler determines the length (820 bytes) of the names buffer (NAMEBUF) from
the parameters in the INCLUDE SQLDA directive using the formula under Declaring
the SQLDA and Names Buffer on page 6-14.
You then declare a structure for the output SQLDA:
STRUCT .osqlda (sqldax);
...

HP NonStop SQL Programming Manual for TAL—527887-001


6-22
7
Dynamic NonStop SQL Operations
Dynamic SQL operations allow a program to construct, compile, and execute an SQL
statement that is unknown until the program is executing. This section describes
concepts that are important for understanding how dynamic SQL operations work.
A static SQL statement appears in the TAL source program at compile time. A program
using static SQL statements receives input values from host variables and sends
output values to host variables. A static SQL statement is:
EXEC SQL
INSERT INTO EMPLOYEE_TABLE VALUES ('BROWN',6400);
In contrast, all or part of a dynamic SQL statement is input or generated, stored in a
character host variable, compiled, and executed at run time. A program using dynamic
SQL sends input values to SQL through SQL input parameters and receives output
values from SQL through host variables or data buffers defined in the program. A
dynamic SQL example is:
User enters an INSERT statement
Program reads INSERT statement into command buffer
EXEC SQL
PREPARE statement-name FROM : statement-buffer;
EXEC SQL
EXECUTE statement-name; ! Insertion performed
You can perform most of the same operations using dynamic SQL that you can
perform with static SQL. You can use DDL, DML, and DCL statements in both modes;
cursors work similar in both modes.
After compilation, SQL executes the statements in the same way whether they are
dynamic SQL statements or static SQL statements. With dynamic SQL, however, you
must perform some operations, such as building descriptors for host variables, that the
TAL compiler performs for you if you are using static SQL.
For examples of TAL programs that use dynamic SQL operations, see Appendix C,
Examples of Dynamic NonStop SQL Programs

HP NonStop SQL Programming Manual for TAL—527887-001


7-1
Dynamic NonStop SQL Operations Determining Uses for Dynamic SQL Operations

Determining Uses for Dynamic SQL


Operations
Programs that use dynamic SQL operations can be useful for a number of applications.
For example:
• You can develop an interactive interface that is similar to SQLCI, but is designed
for an inexperienced user.
• You want to switch between several copies of identical databases. For this
application, you use a dynamic SQL program with run-time TACL DEFINEs.
• You want to restrict access to the data in a table. For example, the program might
code an UPDATE statement for certain columns in a table, but allow the user to
enter the selection criteria (WHERE clause) at run time.
• Your program must communicate with other software that communicates with the
user. For example, an application exists on a personal computer, and the user
wants to manipulate data in a NonStop SQL database on a host system. Your
program cannot use SQLCI. The application allows the user to formulate an SQL
statement on the personal computer and send it to a server process on the HP
NonStop system over MULTILAN or some other communications protocol.

Developing a Dynamic SQL Application


A dynamic SQL application can accept statements directly from the user or through a
screen interface like Pathway, or the program can build the statements with little or no
user input. The application might process an entire SQL statement, or it might process
only part of a statement (such as the WHERE clause) and explicitly code the rest of the
statement in the program.
A program that uses dynamic SQL to process input directly from a user can be similar
to the NonStop SQL Conversational Interface (SQLCI), requiring the user to know SQL
syntax to formulate a complete SQL statement. The statement can contain input
parameters; if it does, the program can prompt the user for the parameter values.
You can also write a program for direct user input so that the user does not have to
know SQL syntax. In this case, the program prompts the user for the necessary values
(or displays a screen for the user to enter the values) and then constructs the SQL
statement by concatenating these values to known syntax elements.
For example, a program can handle any CREATE TABLE statement by concatenating
the string “CREATE TABLE” and punctuation (for example, commas, colons) to the
table name, column names, data types, and options entered by a user and stored in
local variables. The program user sees only a series of prompts, such as ENTER THE
TABLE NAME, ENTER THE FIRST COLUMN NAME, and so forth.

HP NonStop SQL Programming Manual for TAL—527887-001


7-2
Dynamic NonStop SQL Operations Writing a Dynamic SQL Pathway Server

Writing a Dynamic SQL Pathway Server


If you are writing a TAL server that interfaces with Pathway and uses dynamic SQL
statements, follow these steps:
1. Use the TAL SOURCE directive to include the declarations in the EXTDECS file for
the Guardian OPEN, READUPDATE, and REPLY system procedures:
?SOURCE $SYSTEM.SYSTEM.EXTDECS (OPEN, READUPDATE, REPLY)
Except for constructing the SQL statement, these tasks are not unique to servers
using SQL. You perform these tasks in addition to the tasks you would perform for
any dynamic SQL program:
2. Define storage for the messages to be received from the SCREEN COBOL
requester.
3. Define a character string to contain the statement that the program will construct
from the input.
4. Call the OPEN and READUPDATE procedures to read $RECEIVE.
5. Construct the SQL statement:
• Check values passed from the requester in the buffer to decide what the
statement includes.
• As each value is read, concatenate the corresponding text to form the
statement.
For example, suppose the screen describes a personnel record. If any column
does not have a value, the user can enter N. The request message you defined is
named LIST^MSG. This code checks the EMPNUM field in LIST^MSG and, if
required, concatenates the text “empnum” to the statement you are constructing:
STRING .cmd [0:199];
STRING .cmd^end;
cmd ':=' "SELECT " -> @cmd^end;
...
IF list^msg.empnum <> "N" THEN
cmd^end ':=' "EMPNUM " -> @cmd^end;
The statement now contains the string “SELECT EMPNUM”. You continue to
construct the entire statement based on the values the user entered.
6. After the database request has been processed, construct the reply message.
Instead of formatting and displaying the output values, you assign the values to the
reply message. The first field in the reply message record must contain the reply
code to communicate with the SCREEN COBOL requester.
7. Call REPLY to send the reply message to the requester (screen program).

HP NonStop SQL Programming Manual for TAL—527887-001


7-3
Dynamic NonStop SQL Operations Specifying Input Parameters and Output Variables

Restrictions for Record Layout


If possible, avoid having any fields in your requester or server messages that are an
odd number of bytes long. There are some subtle differences in the way
SCREENÊCOBOL and TAL generate fields in records when fields contain an odd
number of bytes. Therefore, take special care that the field layout in the TAL server
matches the layout in the SCREEN COBOL requester. Therefore, to avoid problems,
follow these guidelines:
• Use DDL to describe the request and reply messages and then use the TAL and
COBOL85 forms of the structures derived from the DDL.
• In the SCREEN COBOL requester, avoid constructing messages by listing several
data items in the SEND statement; instead, the requester should send a single
structure to the server.

Specifying Input Parameters and Output Variables


A dynamic SQL statement can contain input parameters. Input parameters might
denote criteria to be used in a WHERE clause, values to be inserted into the database,
or values used to update or delete database records. Input parameters are specified in
the statement as either a question mark (?) or a question mark plus a name (?VAL). An
input parameter can appear in an SQL expression wherever a constant can appear.
The program uses the DESCRIBE INPUT statement with an input SQLDA structure to
get information about the input parameters and obtain pointers to the input values.
NonStop SQL returns data to a program through output variables. Output variables are
user-defined areas in the program. Output variables can be host variables or individual
data buffers to which the program’s output SQLDA structure points. Output variables
usually contain columns returned from a SELECT statement. A program uses the
DESCRIBE statement with an output SQLDA structure to get information about the
output variables.
This sequence shows a typical context for input parameters and output variables in
dynamic SQL operations. If you know in advance which columns will be selected, you
can use this sequence.
HOSTVAR ':=' "SELECT empnum, salary FROM =employee
WHERE SALARY > ?sal"; ! input parameter ?sal
!.. dynamically compile the statement, use DESCRIBE INPUT
! to get information about input parameters, prompt the
! user and read in the value for ?sal, declare and open
! a cursor for the statement.
...
EXEC SQL
FETCH cursor INTO :enum, :salary; ! output variables
! :enum and :dept

HP NonStop SQL Programming Manual for TAL—527887-001


7-4
Dynamic NonStop SQL Operations Using the SQLDA and Names Buffer

If you do not know in advance which columns to select, you can dynamically compile
the statement, use DESCRIBE to find out which columns are being selected, and then
allocate data buffers to receive the column values. The SQLDA structure contains
pointers to the buffers.
In this case, the FETCH statement would look like this:
EXEC SQL
FETCH cursor
USING DESCRIPTOR : sqlda; ! The SQLDA contains
! pointers to output
! data buffers
Internally, SQL execution is the same for both options.

Using the SQLDA and Names Buffer


To allocate storage for information about input parameters and output variables in a
dynamic SQL statement, the dynamic SQL program declares one or more instances of
the SQLDA and names buffer. The SQLDA holds this information:
The number of input parameters or output variables the SQLDA can accommodate in
the NUM^ENTRIES field For each input parameter or output variable, an SQLVAR
structure with this information:
Field Description
DATA^TYPE Data type (TAL data type literals are shown under Allocating Memory
for the Values. on page 7-20)
DATA^LEN Length and scale or date-time qualifier
PRECISION Leading field precision for a date-time or INTERVAL item, or the
numeric precision for a FLOAT or binary numeric item
NULL^INFO Indicator for whether the item can contain a null value
VAR^PTR Extended address of the input parameter or output variable
IND^PTR Extended address of the associated indicator variable (if it exists)

The DESCRIBE and DESCRIBE INPUT statements set the NULL^INFO field
depending on whether the prepared SQL statement includes a null indicator and not
whether the column actually allows a null value. To determine if a column allows a null
value, check the NULLALLOWED column in the COLUMNS table for the catalog where
the table is registered.
When your program issues a DESCRIBE INPUT or DESCRIBE statement, the system
supplies values for all the fields of the SQLDA except EYE^CATCHER,
NUM^ENTRIES, VAR^PTR, and IND^PTR. Your program must initialize these SQLDA
fields as described in these susbsections.

HP NonStop SQL Programming Manual for TAL—527887-001


7-5
Dynamic NonStop SQL Operations Using the SQLDA and Names Buffer

Before DESCRIBE INPUT or DESCRIBE:


• Set the EYE^CATCHER field to the literal SQLDA^EYE^CATCHER.
• Set NUM^ENTRIES to the number of SQLVAR entries allocated in the SQLDA (the
number of input parameters or output columns expected). If you do not know this
number in advance, you can get it from the INPUT^NUM or OUTPUT^NUM fields
of the SQLSA after the PREPARE statement executes.

After DESCRIBE INPUT or DESCRIBE:


• Set VAR^PTR to point to the input or output data buffers.
• Set IND^PTR to point to any indicator variables. If your program does not process
null values, set IND^PTR to an invalid address such as the one shown in the
detailed dynamic SQL program in Appendix C.
• In some cases, your program might change the contents of the DATA^TYPE,
DATA^LEN, or PRECISION fields. Two cases are when the data type of the input
parameter or output variable you declared is compatible with but not the same as
the data type SQL uses, or when you want to manipulate the scale information in
the first byte of the DATA^LEN field.
For input parameter handling, the FETCH or EXECUTE operation usually references
the same SQLDA structure used for DESCRIBE INPUT. Similarly, for output variable
handling, the FETCH or EXECUTE operation references the same SQLDA structure
used for DESCRIBE.
If the program will execute a statement using input parameters, you declare an SQLDA
to describe the input parameters. If the program will execute a dynamic SELECT
statement or an INSERT statement with the RETURNING LASTSYSKEY option, you
declare a second SQLDA to describe the output variables (SELECT columns or
system-defined primary key).
The names buffer stores the names of the input parameters (after DESCRIBE INPUT)
or the names of selected columns (after DESCRIBE). For an expression, the names
buffer contains a null string. If you will need to prompt the user for parameter values or
display column names for output to the user, you should declare one or more names
buffers.
You can generate an SQLDA template and allocate a names buffer by entering the
INCLUDE SQLDA directive. The generated SQLDA template has the format shown
with INCLUDE SQLDA in Section 6, Error and Status Processing
To process the SELECT statement
SELECT EMPNUM, SALARY FROM =EMPLOYEE WHERE SALARY > ?SAL

HP NonStop SQL Programming Manual for TAL—527887-001


7-6
Dynamic NonStop SQL Operations Using Dynamic SQL Programming Techniques

The program performs these tasks:


• Issues the PREPARE statement to dynamically compile the SELECT statement.
• Declares an input SQLDA and an output SQLDA. If needed, the program also
declares corresponding input and output names buffers.
• Uses the DESCRIBE INPUT statement to retrieve the description for the input
parameter ?SAL into an input SQLDA. The input SQLDA will need at least one
SQLVAR entry for the parameter.
• Uses the DESCRIBE statement to retrieve the ENUM and SALARY descriptions
for an output SQLDA. The output SQLDA will need at least two SQLVAR entries,
one for each column.
• Sets the VAR^PTR fields in the SQLDAs to point to the input and output data
buffers. Sets the IND^PTR fields to the addresses of any associated indicator
variables or to a null address.

Using Dynamic SQL Programming Techniques


The simplest dynamic SQL program does not have any input parameters or output
variables. This program processes statements such as CREATE TABLE or DROP
INDEX, which do not require input parameters. A dynamic SQL program that executes
a dynamic SELECT statement is more complex; it does not know the number of
SELECT columns and input parameters until run time.
This section describes programming techniques for dynamic SQL programs that
include:
• Input parameters and output variables
• Run-time memory allocation
This section shows several methods to use dynamic SQL statements; it does not show
the most efficient or only method to develop a particular application.
Appendix C, Examples of Dynamic NonStop SQL Programs provides program
examples that use dynamic SQL operations.

Overview of a Dynamic SQL Program


The following paragraphs describe a dynamic SQL program that handles any SQL
statement and allocates memory at run time. The examples use host variables to store
the cursor name and statement name. Using host variables allows the program to
dynamically compile multiple statements and have all the statements simultaneously
available for execution.
The names for functions, such as ALLOCATE^SQLDA, and variables, such as
IMNAMESBUB^PTR, are arbitrarily chosen.

HP NonStop SQL Programming Manual for TAL—527887-001


7-7
Dynamic NonStop SQL Operations Overview of a Dynamic SQL Program

Setting Up the Environment


1. Use the DATAPAGES directive to cause the BINSERV process to allocate the
maximum object program data pages (64) for SQL data structures and statement
buffers:
?DATAPAGES 64
2. Copy any required external declarations. Some of these declarations are shown
below; however, your application might need additional declarations.
?SOURCE $system.system.EXTDECS (
! For SQL ! SQLCADISPLAY,
SQLCATOBUFFER,
SQLFSCODE,
SQLGETINFOLIST,
SQLSADISPLAY,
! For startup ! INITIALIZER,
! For memory management ! DEFINEPOOL,
GETPOOL,
PUTPOOL
! For terminal I/O ! MYTERM,
OPEN,
READ,
WRITE,
WRITEREAD
! For data conversion ! NUMIN,
DNUMIN,
FORMATCONVERT,
FORMATDATA,
FNAMEEXPAND,
! For abnormal termination ! ABEND
);
! For data type literals and utility routines (required)
?SOURCE $vol.subvol.TALDECS;
! For run-time and utility routines (optional)
?SEARCH $vol.subvol.TALLIB;
3. Declare the SQLCA and SQLSA data structures:
EXEC SQL INCLUDE SQLCA;
EXEC SQL INCLUDE SQLSA;
4. Declare the SQLDA and names buffers. INCLUDE SQLDA generates a template;
for the names buffer, you must declare your own template. If you do not plan to
allocate the names buffer dynamically, use INCLUDE SQLDA with the name-string-
size parameter instead of creating your own template.
EXEC SQL INCLUDE SQLDA (sqlda^templ, 1);
STRUCT namesbuf^template(*);
BEGIN
STRING namestr [0:1000];
END;

HP NonStop SQL Programming Manual for TAL—527887-001


7-8
Dynamic NonStop SQL Operations Overview of a Dynamic SQL Program

5. Declare the SQLCODE variable and any host variables:


INT sqlcode; -- required for error processing
EXEC SQL BEGIN DECLARE SECTION;
! Pointers to input and output SQLDAs. (The SQLDAs will
! be dynamically allocated later.)
INT .isqlda^ptr (sqlda^templ);
INT .osqlda^ptr (sqlda^templ);
! Pointers to input and output names buffers.
INT .inamesbuf^ptr (namesbuf^templ);
INT .onamesbuf^ptr (namesbuf^templ);
! Buffer for the statement entered by the user.
! MAXLEN is a literal you define for the statement length.
STRING statement^buffer[0:MAXLEN];
! Variable for the statement name. Use with PREPARE,
! DESCRIBE, OPEN, FETCH, CLOSE. LEN is a literal you
! define for the length of the name.
STRING statement^hostvar[0:LEN];
! Variable for the name of the cursor to use for
! processing the statement.
STRING cursor^hostvar[0:LEN];
EXEC SQL END DECLARE SECTION;
The variables STATEMENT^HOSTVAR and CURSOR^HOSTVAR are optional. You
can code statement and cursor names in the PREPARE and DECLARE CURSOR
statements.

Reading and Compiling the Statement


1. Specify WHENEVER directives for error handling:
EXEC SQL WHENEVER SQLERROR CALL :handle^error;
EXEC SQL WHENEVER SQLWARNING CONTINUE;
You can place the WHENEVER directives anywhere; however, you must declare or
forward declare the error handling procedures before you declare the WHENEVER
directives.
2. Read the SQL statement you want to execute from input from a user.
3. Prepare the SQL statement:
! Using a statement name:
EXEC SQL PREPARE s1 FROM :statement^buffer;
! Using a statement host variable:
statement^hostvar ':=' "s1";
EXEC SQL PREPARE :statement^hostvar
FROM :statement^buffer;

HP NonStop SQL Programming Manual for TAL—527887-001


7-9
Dynamic NonStop SQL Operations Overview of a Dynamic SQL Program

Use the information returned to the SQLSA structure after the PREPARE statement
executes in the next procedure.

Handling the Input Parameters


If sqlsa.PREPARE.INPUT^NUM is 0, skip these steps.
1. Get the number of input parameters and the length of the names buffer (for
parameter names) from the SQLSA structure (sqlsa.PREPARE.INPUT^NUM and
sqlsa.PREPARE.INPUT^NAMES^LEN).
2. Allocate memory for the input SQLDA (and names buffer, if needed). This example
uses the procedure ALLOCATE^SQLDA. The GETPOOL procedure returns a
pointer to the SQLDA in ISQLDA^PTR.
3. Initialize the SQLDA header fields (SQLDA^EYE^CATCHER is defined by the TAL
compiler):
isqlda^ptr.eye^catcher ':=' SQLDA^EYE^CATCHER;
isqlda^ptr.num^entries := sqlsa.PREPARE.INPUT^NUM;
4. Specify a DESCRIBE INPUT statement to access input parameters:
! Using a statement name:
EXEC SQL DESCRIBE INPUT s1
INTO :isqlda^ptr
NAMES INTO :inamesbuf^ptr.namestr;
! Using a statement host variable:
EXEC SQL DESCRIBE INPUT :statement^hostvar
INTO :isqlda^ptr
NAMES INTO :inamesbuf^ptr.namestr;
5. Loop through the SQLVAR array in the input SQLDA. Loop n times, where n is the
number of parameters from sqlsa.PREPARE.INPUT^NUM). On each iteration:
• Check the DATA^TYPE field. If necessary, adjust the data type and reset
DATA^LEN and PRECISION accordingly.
• Allocate a data buffer with size equal to DATA^LEN for the parameter. Use
GETPOOL to allocate the memory.
• DATA^LEN is used differently for different data types. For example, for a binary
numeric item the upper byte contains the scale, so you must ignore the upper
byte if you are not handling scale. For more information, see Table 6-4 on
page 6-17.
• Set VAR^PTR to point to the memory.
If you are not allocating memory dynamically, you will have declared a variable
for each input parameter value, and put the address of the variable in
VAR^PTR.

HP NonStop SQL Programming Manual for TAL—527887-001


7-10
Dynamic NonStop SQL Operations Overview of a Dynamic SQL Program

If you know the number and data type of your input parameter values, you can
simply set DATA^TYPE, DATA^LEN, and VAR^PTR.
Some programs might check DATA^TYPE and DATA^LEN again when the
actual values are obtained.
• If you are handling null values, check NULL^INFO and continue as follows
according to its value:
0 Do not allocate memory. However, for the best results, set IND^PTR to an
invalid address, such as %HFFFC0000%D, as shown in the example on page
7-18.
-1 Allocate 2 bytes of memory for the indicator variable and set IND^PTR to
point to the memory allocated in the previous step. (If you are not allocating
memory dynamically, define a variable for the indicator and put its address in
IND^PTR.)
6. Loop through the names buffer to read the corresponding name for each
parameter and prompt the user for each value. Read each value into the data
buffer you have allocated for the corresponding parameter, according to the data
type of the value. If the parameter can be null (NULL^INFO is -1) and the value
entered was null, set the indicator variable at the location in IND^PTR to -1.

Handling the Output Variables


Perform these steps if sqlsa.PREPARE.OUTPUT^NUM is greater than 0 (zero).
1. Get the length of the output names buffer from
sqlsa.PREPARE.OUTPUT^NAMES^LEN
2. Call ALLOCATE^SQLDA to allocate memory for the output SQLDA (and output
names buffer, if needed). GETPOOL returns a pointer to the SQLDA in
OSQLDA^PTR.
3. Initialize the SQLDA header fields (SQLDA^EYE^CATCHER is defined by the TAL
compiler):
OSQLDA^PTR.EYE^CATCHER ':=' SQLDA^EYE^CATCHER;
OSQLDA^PTR.NUM^ENTRIES := sqlsa.PREPARE.OUTPUT^NUM;
4. Issue a DESCRIBE statement to access the output variables:
! Using a statement name:
EXEC SQL DESCRIBE s1
INTO :osqlda^ptr
NAMES INTO :onamebuf^ptr.namestr;
! Using a statement host variable:
EXEC SQL DESCRIBE :statement^hostvar
INTO :osqlda^ptr
NAMES INTO :onamebuf^ptr.namestr;

HP NonStop SQL Programming Manual for TAL—527887-001


7-11
Dynamic NonStop SQL Operations Overview of a Dynamic SQL Program

5. Loop through the SQLVAR array in the output SQLDA (loop n times, where n is the
number of columns from sqlsa.PREPARE.OUTPUT^NUM). On each iteration:
• Check DATA^TYPE. If necessary, adjust the data type and reset DATA^LEN
and PRECISION accordingly.
• Allocate a data buffer with size equal to DATA^LEN for the output column.
GETPOOL allocates the memory.
DATA^LEN is used differently for different data types. For example, for a binary
numeric item the upper byte contains the scale, so you must ignore the upper byte
if you are not handling scale. For more information, see Table 6-4 on page 6-17.
• Set VAR^PTR to point to the memory.
If you are not allocating memory dynamically, you will have declared a variable for
each possible column value; therefore, put the address of the variable in
VAR^PTR.
If you know the number and data type of your output column values, you can
simply set DATA^TYPE, DATA^LEN, and VAR^PTR.
Some programs might check DATA^TYPE and DATA^LEN again when the actual
values are obtained.
• If you are handling null values, check NULL^INFO and continue as follows
according to its value:
-1 Allocate two bytes of memory for the indicator variable.
0 Do not allocate any memory.
• If necessary, set IND^PTR to point to the memory allocated in the previous
step. (If you are not allocating memory dynamically, you will define a variable
for the indicator and put its address in IND^PTR.)
6. To show column headings (as SQLCI does), loop through the names buffer to read
the corresponding name for each column and display the column names.

Performing the Database Request and Displaying the Values


If the statement is a SELECT (or if sqlsa.PREPARE.SQL^STATEMENT^TYPE is
SQL^STATEMENT^SELECT), perform Steps 1 through 8. If the statement is not a
SELECT statement, perform Steps 2, 6, and 7.
1. Declare a cursor to handle the SELECT statement.
! Using cursor and statement names:
EXEC SQL DECLARE c1 CURSOR FOR s1;
! Using cursor and statement host variables:
EXEC SQL DECLARE :cursor^hostvar CURSOR
FOR :statement^hostvar;

HP NonStop SQL Programming Manual for TAL—527887-001


7-12
Dynamic NonStop SQL Operations Overview of a Dynamic SQL Program

2. Begin a TMF transaction (for both SELECT and non-SELECT statements):


EXEC SQL BEGIN WORK;
3. Open the cursor:
! Using a cursor name:
EXEC SQL OPEN c1
USING DESCRIPTOR :isqlda^ptr;
! Using a cursor host variable:
EXEC SQL OPEN :cursor^hostvar
USING DESCRIPTOR :isqlda^ptr;
4. Execute a loop to fetch the values and display them.
! Using a cursor name:
EXEC SQL FETCH c1
USING DESCRIPTOR :osqlda^ptr;
! Using a cursor host variable:
EXEC SQL FETCH :cursor^hostvar
USING DESCRIPTOR :osqlda^ptr;
Display the values in a format according to data type. (For a repetitive display of
column names, use the output names buffer at this point and omit the last step
under Step 4.)
Handle null values as follows:
• If NULL^INFO is -1, then check the indicator variable pointed to by IND^PTR. If
the indicator variable is also -1, display something representing a null value
(perhaps blanks or zeroes); otherwise, display the value pointed to by
VAR^PTR.
• If NULL^INFO is 0, display the value pointed to by VAR^PTR.
5. Close the cursor:
! Using a cursor name:
EXEC SQL CLOSE c1;
! Using a cursor host variable:
EXEC SQL CLOSE :cursor^hostvar;
6. If the statement was not a SELECT statement, execute the statement:
• If there were input parameters:
! Using a statement name:
EXEC SQL EXECUTE s1
USING DESCRIPTOR :isqlda^ptr;
! Using a statement host variable:
EXEC SQL EXECUTE :statement^hostvar
USING DESCRIPTOR :isqlda^ptr;

HP NonStop SQL Programming Manual for TAL—527887-001


7-13
Dynamic NonStop SQL Operations Dynamically Allocating Memory

• If there were no input parameters:


! Using a statement name:
EXEC SQL EXECUTE s1;
! Using a statement host variable:
EXEC SQL EXECUTE :statement^hostvar;
7. End the TMF transaction (for both SELECT and other statements):
EXEC SQL COMMIT WORK;
8. If you do not want to reexecute the statement, call PUTPOOL to deallocate the
memory for the SQLDAs and names buffers and for the values.
The following paragraphs describe some of these steps in detail.

Dynamically Allocating Memory


A program can dynamically allocate memory for input parameters and output variables
at run time when the parameters and variables are known. To dynamically allocate
memory, follow these steps:
1. Declare a structure template for the SQLDA by issuing the INCLUDE SQLDA
directive, and for the names buffer by specifying your own template (Refer to page
7-14.)
2. Declare an SQLSA by issuing the INCLUDE SQLSA directive.
3. PREPARE the input statement.
4. Use the information in the SQLSA to determine the number of input parameters
and output variables in the statement.
5. Allocate space for the required number of SQLDA entries to describe the
parameters and output variables, using the GETPOOL system procedure.
6. Allocate space for the values input to the program or output from the database,
again using GETPOOL.
These steps are described in order on the following pages.

Declaring the SQLDA Structure Template and the Names


Buffer Template
To use the INCLUDE SQLDA directive, you must supply both the number of input
parameters or output variables and a size for the names buffer. You can specify large
numbers to ensure that any data you might obtain at run time will fit. If you are not
concerned about memory use, this is the simplest course to take.
A more memory-efficient method is to use INCLUDE SQLDA to generate a template
for the structure and later allocate memory dynamically both for the SQLDA structure
itself and for the variables and names contained in the input statement.

HP NonStop SQL Programming Manual for TAL—527887-001


7-14
Dynamic NonStop SQL Operations Dynamically Allocating Memory

Dynamic allocation of the names buffer is somewhat different, because INCLUDE


SQLDA causes an actual string (not a template) to be declared for the names buffer. If
you want to allocate this memory dynamically, you should omit the name-string-size
parameter from the INCLUDE SQLDA statement. You can then declare a names buffer
template with a large value, and use the template to allocate memory.
In the names buffer template, use a number that is greater than any possible size your
names buffer could be; otherwise, DESCRIBE INPUT and DESCRIBE might stop
describing parameter or variable names too soon. Remember also that indicator
variable names appear in the names buffer; if the names are long and you use many
indicator variables, you will need to accommodate the indicator variable names.
To estimate the names buffer size, use this formula, also accounting for indicator
variable names:
size = (name-string-size + 11) * sqlvar-count
To access the SQLDA, you declare pointers that you later pass to a procedure that
allocates the memory. Sample declarations are:
EXEC SQL BEGIN DECLARE SECTION;
INT .EXT isqlda^ptr (sqlda^type);
INT .EXT osqlda^ptr (sqlda^type);
EXEC SQL END DECLARE SECTION;
After GETPOOL executes, ISQLDA^PTR will point to the memory for the input SQLDA
structure, and OSQLDA^PTR will point to the memory for the output SQLDA structure.

Declaring the SQLSA Structure


Declare an SQLSA structure using the INCLUDE SQLSA directive:
EXEC SQL INCLUDE SQLSA;

Compiling the Input Statement with PREPARE


Use PREPARE to dynamically compile the statement that was input to the program.
The code shown in Figure 7-1 gives an overview of the sequence you can follow. The
statement is prepared with the name S1.

HP NonStop SQL Programming Manual for TAL—527887-001


7-15
Dynamic NonStop SQL Operations Dynamically Allocating Memory

Figure 7-1. Using a PREPARE Statement to Compile a Statement

EXEC SQL BEGIN DECLARE SECTION;


...
STRING .statement^buffer[0:511];
...
EXEC SQL END DECLARE SECTION;
...
--Prompt for a new statement. Pass statement^buffer
--to a procedure that reads and interprets the input.
...
EXEC SQL PREPARE s1 FROM :statement^buffer;
VST0701.vsd

Using the SQLSA Structure


After the input statement is dynamically compiled with the PREPARE statement, the
SQLSA contains this information:
• The number of input parameters in the statement is in
sqlsa.PREPARE.INPUT^NUM; use this information to decide how many parameter
values to solicit from the user.
• The length of the buffer that is required to contain the names of the input
parameters is in sqlsa.PREPARE.INPUT^NAMES^LEN.
• The number of output variables in the statement is in
sqlsa.PREPARE.OUTPUT^NUM; use this information to decide how many column
values to report.
• The length of the buffer that is required to contain the names of the output
variables is in sqlsa.PREPARE.OUTPUT^NAMES^LEN.
• The type of statement being prepared is in
sqlsa.PREPARE.SQL^STATEMENT^TYPE; use this information to decide what
type of statement was entered. Literals defined for the values are shown with
INCLUDE SQLSA in Table 3-1 on page 3-4.
Because some SQL statements that execute after the PREPARE reset the SQLSA,
you should save the values from the sqlsa.PREPARE fields in separate variables
immediately after the PREPARE statement. You can pass these values to a procedure
that allocates memory for the required number of input parameters and output
variables as well as for the required input and output names buffer length.

HP NonStop SQL Programming Manual for TAL—527887-001


7-16
Dynamic NonStop SQL Operations Dynamically Allocating Memory

Allocating Memory for the SQLDA Structures and Names


Buffers
In preparation for allocating memory to store the SQLDA structure, you must get the
number of input parameters or output variables from the SQLSA structure. Similarly, to
allocate memory for the names buffer, you must get the length of the input or output
names buffer from the SQLSA structure. For example:
-- Save the SQLSA values immediately after PREPARE:
inum := sqlsa.PREPARE.INPUT^NUM;
inameslen := sqlsa.PREPARE.INPUT^NAMES^LEN;
IF ( inum > 0) THEN
CALL allocate^sqlda(inum);
...
IF ( inameslen > 0) THEN
CALL allocate^namesbuf(inameslen);
To allocate memory for the SQLDAs and names buffers for the input and output
variables, use the GETPOOL system procedure. GETPOOL allocates a block of
memory, and returns the address of that block.
Before calling GETPOOL, initialize the pool using the system procedure
DEFINEPOOL. For example:
-- In global declarations:
LITERAL pool^size^in^bytes = 8192d;
INT .EXT pool^head[0:18];
INT .EXT pool[0 : pool^size^in^bytes/2d - 1d];
-- In setup or main procedure code:
error := DEFINEPOOL(pool^head, pool, pool^size^in^bytes);
After calling GETPOOL, your program should put the values returned by GETPOOL
into pointers to the SQLDA and names buffer variables that were defined earlier.

Caution. If your program uses more than one extended segment, you must ensure that the
memory in which you place the SQLDA structure is visible when the SQL statement that uses
the SQLDA executes.

The is code shows declaring an SQLDA template and using the template to calculate
the memory required for the SQLDA structure:
-- Global variable declarations:
EXEC SQL INCLUDE SQLDA (sqlda^type, 1);
-- Code in allocate^sqlda procedure:
mem^needed := $LEN(sqlda^type) +
(num^entries -1) * $LEN(sqlda^type.sqlvar);
-- Call to GETPOOL:
@sqlda^ptr := GETPOOL(pool^head, mem^needed);

HP NonStop SQL Programming Manual for TAL—527887-001


7-17
Dynamic NonStop SQL Operations Dynamically Allocating Memory

Initializing EYE^CATCHER and IND^PTR


When you allocate the SQLDA, you must explicitly initialize the EYE^CATCHER and
IND^PTR fields. You must initialize IND^PTR even if your program is not using
indicator variables to handle null values.
Your program must initialize the EYE^CATCHER field in the SQLDA. TAL provides the
SQLDA^EYE^CATCHER literal declaration, which you use as follows:
sqlda^name.EYE^CATCHER ':=' SQLDA^EYE^CATCHER;
where sqlda^name is the SQLDA in your program.
You must also initialize the IND^PTR field for each SQLVAR entry. This example shows
a recommended literal for initializing IND^PTR -- a 32-bit address that is guaranteed
invalid. When you use this literal, it is equivalent to initializing IND^PTR to null:
LITERAL NULL^ADDR = %HFFFC0000%D;
...
FOR i := 0 TO isqlda^ptr.num^entries - 1 DO
isqlda^ptr.sqlvar[i].IND^PTR := NULL^ADDR;
The ALLOCATE^SQLDA procedure, which will also be called to allocate the output
SQLDA, could contain code like that shown in Figure 7-2. This procedure also
initializes the EYE^CATCHER and IND^PTR fields.

HP NonStop SQL Programming Manual for TAL—527887-001


7-18
Dynamic NonStop SQL Operations Dynamically Allocating Memory

Figure 7-2. Allocating the SQLDA Structure

-- SQLDA^TYPE and SQLVAR were generated by INCLUDE SQLDA


-- LITERAL pool^size^in^bytes = 8192d;
-- INT .pool^head[0:18];
-- INT .pool[0:pool^size^in^bytes/2d - 1d];
-- Pool must be initialized using DEFINEPOOL before this
-- procedure is called
INT(32) PROC allocate^sqlda (num^entries);
INT num^entries; -- number of input or output
-- variables
BEGIN
INT .EXT sqlda^ptr(sqlda^type); -- pointer to be
-- returned
INT mem^reqd; -- number of bytes -- required for
-- the SQLDA
INT i; -- loop counter
-- Compute amount of memory needed for the SQLDA. Formula
-- used here is recommended. sqlda^mem is explained
-- earlier in this section.
mem^reqd := $LEN(sqlda^mem) + (num^entries - 1)
* $LEN(sqlda^mem.sqlvar);
-- call GETPOOL to allocate memory (error checking omitted)
@sqlda^ptr := GET (pool^head, $DBL(mem^reqd) );
sqlda^ptr.num^entries := num^entries;
-- Initialize EYE^CATCHER (code shown earlier)
-- If you are not handling null values, initialize IND^PTR
-- to null (code shown earlier in this section)
-- return the pointer to newly allocated memory:
return @sqlda^ptr; VST0702.vsd

END;

To allocate memory for the names buffer, you call GETPOOL using the saved value
from sqlsa.PREPARE.INPUT^NAMES^LEN. In this call, INAMESBUF^PTR is a pointer
to the memory allocated for an input names buffer.
IF inameslen > 0 THEN
@inamesbuf^ptr := GETPOOL(pool^head, $DBL(inameslen) );

HP NonStop SQL Programming Manual for TAL—527887-001


7-19
Dynamic NonStop SQL Operations Dynamically Allocating Memory

Allocating Memory for the Values.


After the descriptions of the input parameters and output variables are specified, the
program must allocate space for the actual values. The user might enter these values
for input parameters, or the system might return them for columns (output variables).
The following paragraphs describe how to handle input parameters.
The program uses the DESCRIBE INPUT statement to fill in the SQLDA and names
buffer with the descriptions of the input parameters in the SQL statement. If you specify
NAMES INTO, the names of the parameters are also returned in the names buffer.
The DESCRIBE INPUT statement is as follows. Notice that the names are placed in
the STRING field of the names buffer template declared for dynamic memory
allocation.
EXEC SQL
DESCRIBE INPUT : statement or :statement-hostvar
INTO :isqlda^ptr
NAMES INTO :inamesbuf^ptr.namestr;
The DESCRIBE INPUT statement places the descriptions for the parameters into the
location pointed to by ISQLDA^PTR, (the input SQLDA) and the names of the
parameters into the location pointed to by INAMESBUF^PTR.
Immediately after DESCRIBE INPUT executes, the VAR^PTR field in the SQLDA
points to the first entry in the names buffer. You can use VAR^PTR to read the names
from the names buffer only if you access the names buffer immediately following
DESCRIBE INPUT. After you have set VAR^PTR to point to the data, you can no
longer use VAR^PTR to access the names buffer and must loop through the names
buffer to get the names.
The program can now allocate memory for the parameter values to be entered.
Handling Scale. If your program must handle numeric values with scale, you will need
to read scale information from the input SQLDA structure. The DESCRIBE INPUT
statement places this information in bits 0 through 7 of the DATA^LEN field in the
SQLVAR array. For handling input parameters, these possibilities exist:
• The program can ignore scale entirely: set bits 0 through 7 of DATA^LEN to 0 and
send integers to SQL.
• The program can ignore scale but accept scaled values from the user: set bits 0
through 7 of DATA^LEN to 0, truncate digits to the right of the decimal point in the
user-entered value, and send the resulting integers to SQL.
• The program can handle scale: write a procedure that scales the user-entered
value to match the value in bits 0 through 7 of DATA^LEN.
Similar considerations apply if your program must handle precision for date-time,
INTERVAL, FLOAT, or binary numeric values. The precision information is in the
PRECISION field of the SQLVAR entry.

HP NonStop SQL Programming Manual for TAL—527887-001


7-20
Dynamic NonStop SQL Operations Dynamically Allocating Memory

Literal Declarations
Your program will need to check DATA^TYPE to make sure that the type of the value to
be placed in the buffer pointed to by VAR^PTR matches the type expected by SQL.
Table 7-1 shows the literal declarations that represent various data types that you can
use in your program.

Table 7-1. Literal Declarations for Data Types


Literal Declaration Data Type
_SQLDT_ASCII_F Fixed-length character string
_SQLDT_ASCII_V Variable-length character string
_SQLDT_16BIT_S 16-bit signed integer
_SQLDT_16BIT_U 16-bit unsigned integer
_SQLDT_32BIT_S 32-bit signed integer
_SQLDT_32BIT_U 32-bit unsigned integer
_SQLDT_REAL 32-bit floating point
_SQLDT_DOUBLE 64-bit floating point
_SQLDT_64BIT_S 64-bit signed integer
_SQLDT_DEC_U Unsigned ASCII numeric (DECIMAL) number
_SQLDT_DEC_LSS DECIMAL number, leading sign separate
_SQLDT_DEC_LSE DECIMAL number, leading sign embedded
_SQLDT_DEC_TSS DECIMAL number, trailing sign separate
_SQLDT_DEC_TSE DECIMAL number, trailing sign embedded
_SQLDT_DATETIME DATETIME item

Other literal declarations have been defined to represent PRECISION values for
numeric and date-time values and to be used with the PRECISION field of the SQLDA.
For a complete list of data type and PRECISION literal declarations, see the INCLUDE
SQLDA statement in Section 6. To include the declarations for these literals, use the
SOURCE directive to include the TALDECS file:
?SOURCE $system.system.TALDECS
Figure 7-3 shows sample code for allocating memory for input parameter values. You
can use the same code later to allocate memory for output variables.

HP NonStop SQL Programming Manual for TAL—527887-001


7-21
Dynamic NonStop SQL Operations Dynamically Allocating Memory

Figure 7-3. Allocating Memory for Values (page 1 of 2)

INT PROC setupvarbuffers (sqlda^ptr);


STRUCT .EXT sqlda^ptr (sqlda^type);
BEGIN
INT i;
INT mem^reqd;
FOR i := 0 TO sqlda^ptr.num^entries-1 DO
BEGIN
-- Determine the amount of memory needed by this entry's
-- data type. Note that for binary and decimal numeric
-- items, the byte length is extracted from bits 8 - 15.
-- The upper 8 bits store the scale of the item.
CASE sqlda.sqlvar[i].data^type OF
BEGIN
_SQLDT_ASCII_F, - - CHAR
_SQLDT_ASCII_F_UP ->
mem_reqd := sqlda.sqlvar[i].data_len;
_SQLDT_ASCII_V, - - VARCHAR
_SQLDT_ASCII_V_UP ->
mem_reqd := sqlda.sqlvar[i].data_len + 2;
_SQLDT_16BIT_S, - - SMALLINT
_SQLDT_16BIT_U, - - SMALLINT UNSIGNED
_SQLDT_32BIT_U, - - INTEGER UNSIGNED
_SQLDT_32BIT_S, - - INTEGER
_SQLDT_64BIT_S, - - LARGEINT
_SQLDT_REAL, - - REAL
_SQLDT_DOUBLE -> - - DOUBLE PRECISION
mem_reqd := sqlda.sqlvar[i].data_len.<8:15>;
_SQLDT_DEC_U, - - DECIMAL UNSIGNED
_SQLDT_DEC_LSS, - - DECIMAL LSS
_SQLDT_DEC_LSE, - - DECIMAL LSE
_SQLDT_DEC_TSS, - - DECIMAL TSS
mem_reqd := sqlda.sqlvar[i].data_len.<8:15>;
_SQLDT_DEC_TSE -> - - DECIMAL TSE
-- Other DATETIME data types except DAY TO FRACTION
_SQLDT_DATETIME, - - DATETIME
_SQLDT_INT_D_F -> - - DAY TO FRACTION
mem^reqd := sqlda.sqlvar[i].data^len.<8:15>;
OTHERWISE ->
-- Print "Data type not supported" message and
-- display sqlda.sqlvar[i].data^len VST0703.vsd
END; -end of case

HP NonStop SQL Programming Manual for TAL—527887-001


7-22
Dynamic NonStop SQL Operations Using the Names Buffer

Figure 7-3. Allocating Memory for Values (page 2 of 2)

--Allocate memory for the data value and assign the byte
--address of the newly allocated data buffer to VAR^PTR:
sqlda.sqlvar[i].var^ptr :=
GETPOOL(pool^head, $DBL(mem^reqd));
IF sqlda.sqlvar[i].var^ptr = -1d THEN
-- Display "Getpool memory management error" message
-- and call ABEND
VST0703.vsd
...

The program can now prompt the user for the input parameter values, set the pointer
to the first SQLVAR element in the input SQLDA, and read through the SQLVAR array,
storing each value the user enters into the appropriate position in memory.

Using the Names Buffer


If you specified NAMES INTO in your DESCRIBE INPUT statement, the names buffer
contains the names of the parameters, which you can use to prompt the user for
parameter values. If indicator parameters were specified, the names of the indicator
parameters are also in the names buffer (for more information on this section, see
Handling Null Values on page 7-36).
The data returned to the names buffer is in this form:
len-1 name-1 len-2 name-2 ... len- n name- n
where name-1 represents the first name, name-2 the second, and name-n the last. The
name length information is a 2-byte integer (SQL data type PIC S9(4) COMP; TAL data
type INT). All names with a length of an odd number of characters are padded with a
blank to make the length an even number; when you display the names, you might
want to check for this blank padding. Expressions appear as a null string with a length
of 0.
For the program to determine the names in the names buffer, you can write a routine to
return the VARCHAR structure for a name when given the index of the parameter
information desired. After the DESCRIBE INPUT statement executes, the information
for each parameter is in the SQLVAR array; the VAR^PTR field contains the address of
the length field for each parameter name in the names buffer.

HP NonStop SQL Programming Manual for TAL—527887-001


7-23
Dynamic NonStop SQL Operations Using the Names Buffer

Some examples of entries in the names buffer are:


Complete Entry Entry Part Description
|04|ABCD| |04| 2-byte length 4-character string with value = 4
|ABCD| 4-character string
|06|ABCDE | |06| 2-byte length 4-character string with value = 6
|ABCDE | 5-character string padded with 1 trailing blank
|00| | |00| 2-byte length with value = 0
|| Null string
A complete names buffer with the names shown in this example might look like this:

|04|ABCD|06|ABCDE |00|

Note. If the SQL statement includes indicator parameters, the indicator parameter names are
included in the names buffer. For more information, see Handling Null Values on page 7-36.

To prompt the user with the parameter names in the input names buffer, you must read
the length of the name and then position a pointer past the length field and onto the
name. Figure 7-4 shows code to use the names buffer, prompt for input, and read
parameter values input by the user.

HP NonStop SQL Programming Manual for TAL—527887-001


7-24
Dynamic NonStop SQL Operations Using the Names Buffer

Figure 7-4. Getting Parameter Values (page 1 of 2)

INT PROC request^invars(sqlda^ptr, inamesbuf^ptr);


STRUCT .EXT sqlda^ptr(sqlda^type); ! input SQLDA pointer
STRING .EXT inamesbuf^ptr; ! points to buffer
BEGIN ! with parameter names
! Define template of TAL types that correspond to SQL types
STRUCT sql^types (*);
BEGIN
STRING v^char[0:MAX^SQL^CHAR^LENGTH];
STRUCT v^varchar = v^char;
BEGIN
INT len;
STRING VAL[0:MAX^SQL^CHAR^LENGTH-2];
END;
INT v^smallint = v^char;
INT(32) v^int = v^char;
FIXED v^largeint = v^char;
FIXED(3) v^numeric = v^char;
REAL v^float = v^char;
REAL(64) v^double = v^char;
STRING v^decimal[0:18] = v^char;
STRING v^datetime[0:25] = v^char;
END;
STRING .param^name[0:39]; ! current parameter name
! (40 is the maximum size
! of a column name).
INT namelen; ! number of bytes in a
! parameter name
INT nameix; ! index into parameter names
! string
INT input^num; ! number of input parameters
INT .EXT param^(sql^types); ! pointer to parameter value
INT maxlen; ! maximum length of a string
! parameter
INT count^read; ! number of bytes of input
! value actually read
INT i; ! loop counter
! Prompt user for input parameter values ...
! Get number of input parameters:
input^num := sqlda^ptr.num^entries; VST0704.vsd

...

HP NonStop SQL Programming Manual for TAL—527887-001


7-25
Dynamic NonStop SQL Operations Using the Names Buffer

Figure 7-4. Getting Parameter Values (page 2 of 2)

nameix := 1;
FOR i := 0 TO (input^num - 1) DO
BEGIN
! Read the length for a parameter name, starting at
! the second byte in the length field (assumes no
! name ever contains more than 255 characters).
namelen := inamesbuf^ptr[nameix];
! If parameter has a name, save the name in PARAM^NAME:
IF namelen THEN
param^name ':=' inamesbuf^ptr[nameix + 1] FOR namelen;
! Move index to next length field:
nameix := namelen + 2 + nameix;
! Request input value based on data type:
! Set pointer to storage for current parameter value:
@param^ := sqlda.sqlvar[i].var^ptr;
maxlen := sqlda.sqlvar[i].data^len;
CASE sqlda.sqlvar[i].data^type OF
BEGIN
SQLDT^ASCII^F,
SQLDT^ASCII^F^UP -> ! Prompt for value for a string
! of maximum MAXLEN characters
! Read the parameter value into the memory pointed to by
! VAR^PTR, the address of which is in param^.param^.v^char
! references the character field in struct sql^types.
CALL READX(term, param^.v^char, maxlen);
! Read values for other data types. Sample calls are:
! For VARCHAR: CALL READX (term, param^.v^varchar.val,
! maxlen,param^.varchar.len);
! For NUMERIC: 1.Prompt and CALL WRITEREAD
! (term, buf, $INT(@next^buf - @sbuf),
! 25, count^read);
! 2.Call DNUMIN to convert input to numeric.
! For DATETIME CALL READX (term, param^.v^datetime
! FOR $OCCURS(param^.v^datetime) );
END; ! end CASE VST0704.vsd
END;

HP NonStop SQL Programming Manual for TAL—527887-001


7-26
Dynamic NonStop SQL Operations Allocating and Filling in Output Variables

Allocating and Filling in Output Variables


To allocate space for output variables, you perform essentially the same set of
operations described for allocating space for input parameters except that the pointers
point to the output SQLDA and names buffer. To get the descriptions of the output
variables into the output SQLDA, you use the DESCRIBE statement instead of
DESCRIBE INPUT:
EXEC SQL DESCRIBE statement or :statement-hostvar
INTO :osqlda^ptr
NAMES INTO :onamesbuf^ptr.namestr;
DESCRIBE places the descriptions of the column values to be output from the
database into the location in memory pointed to by OSQLDA^PTR and the names of
the columns into the location pointed to by ONAMESBUF^PTR. For code to allocate
memory, see Allocating Memory for the Values. on page 7-20.

Handling Scale
If your program must handle numeric values with scale, you will need to read scale
information from the output SQLDA. DESCRIBE places this information in bits 0:7 of
the DATA^LEN field in the SQLVAR array. If you can ignore scale, you can set the
DATA^LEN field to 0, causing data truncation; otherwise, you will need to save the
scale information and write a procedure to handle scale.
The same considerations apply if your program must handle precision for date-time,
INTERVAL, FLOAT, or binary numeric values. The precision information is in the
PRECISION field of the SQLVAR entry.

Displaying Output
To display output from the database after the cursor FETCH, you perform these tasks:
1. Set pointers to the beginning of the first SQLVAR array and to the beginning of the
names buffer.
2. Get the number of output columns from the SQLDA.
3. Write the column name to the output file using the names buffer pointer (only if you
are doing a repetitive display of the column names).
4. Read the DATA^TYPE field from the SQLVAR array to get the data type of the
column value to be written.
5. Retrieve the value from the location pointed to by the VAR^PTR field in the
SQLVAR array. Format the value and write it to output. The steps to use depend on
the data type of the value.

HP NonStop SQL Programming Manual for TAL—527887-001


7-27
Dynamic NonStop SQL Operations Allocating and Filling in Output Variables

The sequence just described displays names and values repetitively. For example:
EMPNUM 2000
EMPNAME JANE ROBERTS
EMPNUM 1566
EMPNAME CATHERINE WILLIAMS
EMPNUM 1890
EMPNAME RICHARD SMITH

You can also display the column names as headings (similar to SQLCI) by executing
the following loop. Assume that the value in sqlsa.PREPARE.OUTPUT^NUM was
saved in variable OUTNUM. Loop OUTNUM times:
1. Get the length of the column name.
2. Advance to the name.
3. Display the name with some blank space.
4. Advance to the next length field.
If you use this second method, you will need to execute a second loop to interpret and
display the values, including enough blank space for each value to fall under its column
heading.
You can use data type literals (listed and described under Allocating Memory for the
Values. on page 7-20) to decide how to display output column values.
Figure 7-5 shows sample code for displaying the current row output by a SELECT
statement.

HP NonStop SQL Programming Manual for TAL—527887-001


7-28
Dynamic NonStop SQL Operations Allocating and Filling in Output Variables

Figure 7-5. Displaying Output (page 1 of 3)

-- Declare, open, fetch, and close the cursor.


-- before executing this code.
-- Global declarations used in printing output:
STRING .EXT next^buf; --ptr to end of data in buffer
--Put a string into the line, starting at beginning:
DEFINE PUT^STR(s) = @next^buf := @sbuf;
next^buf ':=' s -> @next^buf #;
--Put an integer into the line, starting at beginning:
DEFINE PUT^INT(n) = @next^buf := @sbuf;
@next^buf := @next^buf +
$DBL(DNUMOUT(next^buf, $DBL(n),10)) #;
--Put an integer into the line, starting after the
--beginning:
DEFINE PUT^INT^MID(n) = @next^buf := @next^buf +
$DBL(DNUMOUT(next^buf, $DBL(n),10)) #;
--Put an INT(32) into the line, starting at beginning:
DEFINE PUT^DBL(n) = @next^buf := @sbuf;
@next^buf := @next^buf +
$DBL(DNUMOUT(next^buf, n,10)) #;
PROC display^result(osqlda^ptr, onamesbuf^ptr);
STRUCT .EXT osqlda^ptr(sqlda^type); --output SQLDA ptr
STRING .EXT onamesbuf^ptr; -- ptr to buffer with column
-- names of table
BEGIN
INT length;
INT nameix; --index into column names buffer
INT output^num; --number of columns output by SELECT
INT datalen; --length of a column value
INT .EXT param^(sql^types); -- ptr to where to put
-- column value
-- SQL^TYPES is a structure with fields of different
-- SQL data types equivalenced to each other
INT i; --loop counter
-- Get number of columns to output in current row:
VST0705.vsd
output^num := osqlda^ptr.num^entries;

HP NonStop SQL Programming Manual for TAL—527887-001


7-29
Dynamic NonStop SQL Operations Allocating and Filling in Output Variables

Figure 7-5. Displaying Output (page 2 of 3)

FOR i := 0 to (output^num - 1) DO
BEGIN
@param^ := osqlda^ptr.sqlvar[i].var^ptr;
datalen := osqlda^ptr.sqlvar[i].data^len;
-- Position onamesbuf^ptr to the length prefix in
-- the names buffer, save the length, move
-- the pointer past the prefix and onto a name, and save
-- the column name. Code is the same as that used for
-- input parameter names (see "Getting Parameter Values").

-- If you want to display the column names once (as SQLCI


-- display all the names at this point. The remaining
-- does), rather than repetitively with each FETCH,
-- code here assumes a repetitive display of column names
-- and their associated values.

CASE osqlda^ptr.sqlvar[i].data^type OF
BEGIN
_SQLDT_ASCII_F,
_SQLDT_ASCII_F_UP -> -- display first 38 characters:
PUT^STR^MID (param^.v^char for $MIN(38,datalen);

_SQLDT_16BIT_S -> -- handle sign for smallint signed:


IF param^.v^smallint >= 0 THEN
BEGIN
PUT^INT^MID (param^.v^smallint);
END
ELSE
BEGIN
PUT^STR^MID("-");
PUT^INT^MID(-param^.v^smallint);
END;
_SQLDT_16BIT_U ->
PUT^DBL^MID ($UDBL(param^.v^smallint) ); VST0705.vsd

HP NonStop SQL Programming Manual for TAL—527887-001


7-30
Dynamic NonStop SQL Operations Using Dynamic Cursors

Figure 7-5. Displaying Output (page 3 of 3)

-- Proceed to handle all the possible data types for


-- output values and write the data pointed to by
-- the VAR^PTR field in the output SQLDA in a format
-- depending on the data type. For complete code, see
-- the detailed sample program
END; --end CASE
--Call WRITE to print the contents of the output buffer

END; -- end FOR loop, traversing sqlvar array


END; VST0705.vsd

Using Dynamic Cursors


Dynamic SQL statements use cursors to process SELECT statements in the same way
static SQL statements use cursors. The program reads rows from a table, one by one,
and sends the column values to output data buffers specified in the program. This
subsection provides some guidelines when you use cursors. The order for executing
statements to use a cursor with dynamic SQL operations is:
Operation Description
PREPARE statement-name Dynamically compiles the SELECT statement
FROM :host-variable defining the cursor
Issue the DESCRIBE INPUT and
DESCRIBE statements
DECLARE cursor-name CURSOR Declares the cursor
FOR statement-name
OPEN cursor-name Opens the cursor and gets parameter values
USING DESCRIPTOR input-sqlda from input data buffer in the program
Loop until end-of-file
FETCH cursor-name Retrieves data and outputs column values to
USING DESCRIPTOR output-sqlda output data buffer in the program
CLOSE cursor-name Closes the cursor

Follow these guidelines when you declare and use a cursor:


• You can use a host variable wherever you can use the cursor-name and
statement-name parameters. For each new statement and cursor, you store the
name in the host variable before executing the statements.
• The DECLARE CURSOR, PREPARE, OPEN, FETCH, CLOSE, DELETE WHERE
CURRENT, UPDATE WHERE CURRENT, DESCRIBE INPUT, and DESCRIBE
statements for a particular cursor and its associated statement must all appear in
the same procedure.

HP NonStop SQL Programming Manual for TAL—527887-001


7-31
Dynamic NonStop SQL Operations Using Dynamic Cursors

• The PREPARE statement does not have to precede the other statements in the
program listing order; however, the PREPARE statement must be executed after
DECLARE CURSOR and before DESCRIBE, DESCRIBE INPUT, OPEN, FETCH,
and CLOSE.

Using Cursors with a USING DESCRIPTOR Clause


If the program is handling input parameters with values entered at run time, you use
the USING DESCRIPTOR clause with the OPEN statement to specify values for the
parameters in the SELECT statement. The input SQLDA specifies the address of
program data buffers that contain the input parameter values.
You also use the USING DESCRIPTOR clause with the FETCH statement to write
column values to an output buffer specified in the program’s variable declarations. The
output SQLDA specifies the address of program data buffers into which FETCH copies
the data.

Using Cursors with an UPDATE WHERE CURRENT Clause


To use UPDATE WHERE CURRENT with a static cursor, you specify a FOR UPDATE
OF clause with a column list in the DECLARE CURSOR statement. In contrast, to use
UPDATE WHERE CURRENT with a dynamic SQL cursor, you must specify a FOR
UPDATE OF clause in the SELECT statement associated with the cursor.
This example shows an UPDATE WHERE CURRENT operation with a dynamic SQL
cursor. In the example, the host variable HOSTVAR contains the SELECT statement to
define the cursor. The host variable :SALVAR receives the selected values.
--Copy the string:
--"SELECT salary FROM =employee FOR UPDATE OF salary"
--into host variable hostvar
...
EXEC SQL
PREPARE s1 FROM :hostvar;
EXEC SQL
DECLARE c1 CURSOR FOR s1;
EXEC SQL
OPEN c1;
EXEC SQL
FETCH c1 INTO :salvar;
EXEC SQL
UPDATE =employee SET salary = salary * 1.20
WHERE CURRENT OF c1;

HP NonStop SQL Programming Manual for TAL—527887-001


7-32
Dynamic NonStop SQL Operations Using Statement and Cursor Host Variables

Using Statement and Cursor Host Variables


TAL supports using statement and cursor host variables in dynamic SQL operations.
You can use host variables instead of statement and cursor names, with the DECLARE
CURSOR, PREPARE, OPEN, FETCH, and CLOSE statements. For each new
statement or cursor name, you store the name in the host variable before executing the
statements. Thus, you must code the statements only once.
The example program in Figure 7-6 shows one method to use statement and cursor
host variables.

HP NonStop SQL Programming Manual for TAL—527887-001


7-33
Dynamic NonStop SQL Operations Using Statement and Cursor Host Variables

Figure 7-6. Statement and Cursor Host Variables (page 1 of 2)

?SQL
?INSPECT
?SYMBOLS
?NOCODE, NOMAP, NOLMAP
?DATAPAGES 64
STRING .buf^end;
INT .home^term[0:11];
INT home^term^fnum;
INT .ibuf[0:19];
STRING .sbuf := @ibuf '<<' 1;
INT i;
INT sqlcode;
EXEC SQL BEGIN DECLARE SECTION;
INT(32) answer;
STRUCT .curs[0:2]; - - Table of 3 cursor names
BEGIN
STRING name[0:1];
END;
STRUCT .stmt[0:2]; - - Table of 3 statement names
BEGIN
STRING name[0:1];
END;
LITERAL TEXT^LEN = 80;
STRUCT .text[0:2]; - - Table of text for 3 statements
BEGIN
STRING str[0:TEXT^LEN-1];
END;
EXEC SQL END DECLARE SECTION;
? NOLIST
? SOURCE $SYSTEM.SYSTEM.EXTDECS (
? CLOSE,
? DNUMOUT,
? INITIALIZER,
? MYTERM,
? OPEN,
VST0706.vsd
? WRITE
? )
? LIST

HP NonStop SQL Programming Manual for TAL—527887-001


7-34
Dynamic NonStop SQL Operations Using Statement and Cursor Host Variables

Figure 7-6. Statement and Cursor Host Variables (page 2 of 2)

PROC p MAIN;
BEGIN
CALL INITIALIZER;
CALL MYTERM (home^term);
CALL OPEN (home^term, home^term^fnum);
curs[0].name ':=' "c1";
curs[1].name ':=' "c2";
curs[2].name ':=' "c3";
stmt[0].name ':=' "s1";
stmt[1].name ':=' "s2";
stmt[2].name ':=' "s3";
- - Blank fill text buffer:
FOR i := 0 to 2 DO
text[i].str ':=' " " & text[i].str FOR TEXT^LEN - 1;
text[0].str ':='
"select empnum from =employee where salary > 100000";
text[1].str ':='
"select salary from =employee where jobcode = 400";
text[2].str ':='
"select deptnum from =dept where location = ""NEW YORK""";
! Use statement and cursor host variables to PREPARE the statements
! and associate successive cursors with the statements.
FOR i := 0 to 2 DO
BEGIN
EXEC SQL PREPARE :stmt[i].name FROM :text[i].str;
EXEC SQL DECLARE :curs[i].name CURSOR FOR :stmt[i].name;
END; - - end FOR loop
-- FETCH rows using the cursors and display the results.
FOR i := 0 to 2 DO
BEGIN
EXEC SQL BEGIN WORK;
EXEC SQL OPEN :curs[i].name;
WHILE sqlcode >= 0 AND sqlcode <> 100 DO
BEGIN
EXEC SQL FETCH :curs[i].name INTO :answer;
IF sqlcode >= 0 AND sqlcode <> 100 THEN
BEGIN
sbuf ':=' "answer = " -> @buf^end;
@buf^end := @buf^end '+' dnumout (buf^end, answer, 10);
CALL WRITE (home^term^fnum, ibuf, @buf^end '-' @sbuf);
END;
END;
EXEC SQL CLOSE :curs[i].name;
CALL WRITE (home^term^fnum, ibuf, 0);
EXEC SQL COMMIT WORK;
END; -- end FOR loop
CALL CLOSE (home^term^fnum);
END; -- end proc p VST0706.vsd

The program in Figure 7-6 on page 7-34 produces this output when run with the data in
the sample database:
answer = 1
answer = 23
answer = 29

HP NonStop SQL Programming Manual for TAL—527887-001


7-35
Dynamic NonStop SQL Operations Handling Null Values

answer = 32
answer = 65
answer = 89000
answer = 69000
answer = 68000
answer = 96000
answer = 65000
answer = 3000
answer = 4000
answer = 4100

Example of an Application
In a possible application for statement and cursor host variables, a server could use a
loop to initialize the arrays of statement and cursor host variable names and the array
of statements and to execute the PREPARE and DECLARE CURSOR statements. The
program could then use the cursors as follows:
-- Read $RECEIVE
-- Examine a flag in the request message to determine
-- which cursor to use
CASE flag OF
BEGIN
-- Assign appropriate name to cursor-host-variable
-- according to flag
END;
EXEC SQL OPEN : cursor-host-variable;
-- Loop until SQLCODE = 100:
BEGIN
EXEC SQL FETCH : cursor-host-variable INTO : column
-host-variables;
-- Display column values
END;
EXEC SQL CLOSE : cursor-host-variable;

Handling Null Values


The input and output SQLDA structures have two fields, NULL^INFO and IND^PTR,
that are used for handling null values. Your program accesses these fields in the
SQLVAR array, in the same way in which you access VAR^PTR.
NULL^INFO indicates whether the input parameter or output variable can contain a null
value. If NULL^INFO is 0, IND^PTR has no meaning. If NULL^INFO is less
than 0, your program should access IND^PTR before each access of
VAR^PTR in order to handle null values correctly.
IND^PTR points to a flag that indicates whether the input parameter or output
variable actually is null. If the parameter or output variable is not null, the
VAR^PTR field specifies the value.

HP NonStop SQL Programming Manual for TAL—527887-001


7-36
Dynamic NonStop SQL Operations Handling Null Values

Allocating Memory for a Possible Null Value


You can allocate memory for indicator variables at the same time you allocate memory
for other values. If NULL^INFO is -1, you allocate a buffer for the indicator value and
assign its address to the IND^PTR field of the appropriate SQLVAR entry. This
example shows code for this allocation. The statements take place within a FOR loop
to handle each input parameter or output column.
--After allocating memory for the data value and assigning
--the address of the memory to VAR^PTR:
IF sqlda^ptr.sqlvar[i].null^info = -1 THEN
BEGIN
sqlda^ptr.sqlvar[i].IND^PTR :=
GETPOOL (pool^head, $DBL(2) ); -- Get 2 bytes
--for the indicator variable
IF sqlda^ptr.sqlvar[i].IND^PTR = -1D THEN
--(print error message and call ABEND)
END;

Handling Null Values in Input Parameters


If your program is to handle null values on input, each parameter in the statement
entered by the user or constructed by your program must have a corresponding
indicator parameter, or a run-time error will occur when a null value is encountered.
After DESCRIBE INPUT executes and for each input parameter described in an
SQLVAR array in the input SQLDA, SQL sets NULL^INFO to -1 if the input parameter
in the prepared statement allows a null value (that is, if the prepared statement
included a null indicator).
If NULL^INFO contains a value of -1 and you are allocating memory dynamically, you
can now allocate 2 bytes of memory for a null indicator value, and then set IND^PTR to
point to the memory. Allocate this memory at the same time you allocate memory for a
possible nonnull parameter value.
If the user specifies a null value for the parameter, you assign a -1 to the location
pointed to by IND^PTR. NonStop SQL checks this value and assumes a null value for
the parameter.
If instead the user does not enter a null value for the input parameter, you can assign a
0 to the location pointed to by IND^PTR. NonStop SQL checks IND^PTR, sees that
IND^PTR indicates a nonnull value, and gets the parameter value from the location
pointed to by VAR^PTR.
This example handles a possible null value in an input parameter. In this example, the
user is supposed to type in a question mark to signify a null value. The datatype-field
refers to the equivalenced data type field in the SQL^TYPES structure on which
PARAM^ is based.
--Variable declarations:
INT .EXT ind^; --pointer used to set null indicator

HP NonStop SQL Programming Manual for TAL—527887-001


7-37
Dynamic NonStop SQL Operations Handling Null Values

INT .EXT param^(sql^types); --pointer to buffer that


--will receive parameter value
--Procedure code:
--Set pointer to storage for current parameter value:
@param^ := isqlda^ptr.sqlvar[i].var^ptr;
-- call READX or WRITEREAD, depending on data type ...
IF (isqlda^ptr.sqlvar[i].null^info = -1) AND
(param^. datatype-field = "?") THEN
BEGIN
@ind^ := isqlda^ptr.sqlvar[i].IND^PTR;
ind^ := -1;
END;

Handling Null Values in Output Variables


DESCRIBE sets NULL^INFO to -1 if the output variable can be null (that is, if the
prepared statement included a null indicator). If the value returned is null, SQL checks
NULL^INFO and moves a -1 into the location pointed to by IND^PTR. (Errors are
returned if the value is null but NULL^INFO is 0 or if IND^PTR is an invalid address.)
Your program must check NULL^INFO to determine whether the value returned can be
null. If NULL^INFO contains a -1, then your program checks the location pointed to by
IND^PTR. If that location contains a -1, then a null value was returned. If the location
contains 0, then a nonnull value was returned and your program should get the value
from the location pointed to by VAR^PTR.
This example handles null values in output variables. BUF is a globally defined output
buffer. NEXT^BUF is a pointer to the end of data in the buffer. SBUF is a string buffer.
This example prints the string “NULL” to represent a null value.
@param^ := osqlda^ptr.sqlvar[i].var^ptr;
@ind^ := osqlda^ptr.sqlvar[i].IND^PTR;
IF osqlda^ptr.sqlvar[i].null^info = -1 AND
ind^ = -1 THEN
BEGIN
buf ':=' "NULL" -> @next^buf;
CALL WRITE(term,buf,$INT(@next^buf - @sbuf));
END
ELSE
--display values according to data type

Null Values and the Names Buffer


If your program processes indicator parameters, the names of the indicator parameters
are included in the names buffer after DESCRIBE INPUT executes. The IND^PTR field
points to the length field for the parameter name in the names buffer. This behavior is
parallel to that of VAR^PTR after DESCRIBE INPUT or DESCRIBE.
This diagram illustrates the structure of the names buffer immediately after DESCRIBE
INPUT when indicator parameters are present for two parameters, where len is a 2-

HP NonStop SQL Programming Manual for TAL—527887-001


7-38
Dynamic NonStop SQL Operations Handling Null Values

byte length, name is a parameter name, ind-len is the length of an indicator parameter
name, and ind-name is an indicator parameter name. Each instance of IND^PTR
points to the length field for the corresponding indicator parameter name.

S Q L V A R [1 ].V A R ^ P T R S Q L V A R [1 ].IN D ^P T R S Q L V A R [2 ].V A R ^P T R S Q L V A R [2 ].IN D ^P T R

le n 1 nam e1 in d -le n -1 in d -n a m e -1 le n 2 nam e2 in d -le n -2 in d -n a m e -2


V S T 0 7 0 7 .v sd

Like input parameter and output variable names, indicator variable names are padded
with blanks to even lengths.
When you are reading through the names buffer to prompt the user for parameter
names, you might need to be aware of the indicator fields and perform tasks such as:
1. Check the NULL^INFO field.
2. If NULL^INFO is -1, read the length field for the indicator.
3. Add this length field plus 2 to the pointer or index to skip to the next name in the
names buffer.

HP NonStop SQL Programming Manual for TAL—527887-001


7-39
Dynamic NonStop SQL Operations Handling Null Values

HP NonStop SQL Programming Manual for TAL—527887-001


7-40
A
Sample NonStop SQL Database
This appendix describes the sample NonStop SQL database used by some of the
examples in this manual. There is one node, the \SYS1 system. The $VOL1 volume on
this system contains the PERSNL, SALES, and INVENT subvolumes. Each subvolume
contains a catalog and tables relating to a specific operation in the organization:
PERSNL Contains the EMPLOYEE, JOB, and DEPT tables, which hold personnel
data.
SALES Contains the CUSTOMER, ORDERS, ODETAIL, and PARTS tables, which
are used for order data.
INVENT Contains the SUPPLIER, PARTSUPP, PARTLOC, and ERRORS tables,
which hold inventory data.

The PARTLOC table is partitioned over three volumes. The other two volumes are
$WHS2 and $WHS3 (indicating the data relates to the parts stored at two different
warehouses).
Figure A-1 on page A-2 shows the names of columns and tables and the relations
between the tables in the sample database.
Figure A-2 on page A-3 shows the source file containing the record descriptions of
database tables. This source file was generated using INVOKE directives executed
from SQLCI. For example, the INVOKE directive used to generate the DEPT table is:
INVOKE persnl.dept FORMAT TAL TO srcfile (dept);

HP NonStop SQL Programming Manual for TAL—527887-001


A-1
Sample NonStop SQL Database

For more information about SQLCI, see the SQL/MP Version Management Guide.
Figure A-1. Sample NonStop SQL Database Relations

empnum custnum errors_date


first_name custname errors_time
last_name street errors_id
deptnum city errors_sql
jobcode state errors_text 1
salary postcode errors_text 2
credit

suppnum
deptnum ordernum suppname
deptname order_date street
manager deliv_date city
rptdept salesrep state
location custnum postcode

jobcode partnum
jobdesc ordernum
partnum suppnum
unit_price partcost
qty_ordered qty_received

Legend
One to one partnum loc_code
partdesc partnum
One to many price qty_on_hand
The PARTLOC table is qty_available
* partitioned by the value
of LOC_CODE.
VSTA01.vsd

HP NonStop SQL Programming Manual for TAL—527887-001


A-2
Sample NonStop SQL Database

Figure A-2. Sample Database Source File (page 1 of 4)

!
! Personnel (PERSNL)
!
!
?SECTION EMPLOYEE
! Record Definition for table \SYS.$VOL.PERSNL.EMPLOYEE
! Definition current at 17:10:47 - 04/20/90
struct employee^type(*);
BEGIN
int empnum;
string first^name[ 0: 14 ];
string last^name[ 0: 19 ];
int deptnum;
int jobcode;
int(32) salary; ! scale is 2
END;
?SECTION DEPT
! Record Definition for table \SYS.$VOL.PERSNL.DEPT
! Definition current at 17:10:59 - 04/20/90
struct dept^type(*);
BEGIN
int deptnum;
string deptname[ 0: 11 ];
int manager;
int rptdept;
struct location;
begin
int len;
string val[ 0:17 ];
end; VSTA02.vsd
END;

HP NonStop SQL Programming Manual for TAL—527887-001


A-3
Sample NonStop SQL Database

Figure A-2. Sample Database Source File (page 2 of 4)

?SECTION JOB
! Record Definition for table \SYS.$VOL.PERSNL.JOB
! Definition current at 17:11:12 - 04/20/90
struct job^type(*);
BEGIN
int jobcode;
struct jobdesc;
begin
int len;
string val[ 0:17 ];
end;
END;
!
!
! Sales (SALES)
!
!
?SECTION CUSTOMER
! Record Definition for table \SYS.$VOL.SALES.CUSTOMER
! Definition current at 17:11:21 - 04/20/90
struct customer^type(*);
BEGIN
int custnum;
string custname[ 0: 17 ];
string street[ 0: 21 ];
string city[ 0: 13 ];
string state[ 0: 11 ];
string postcode[ 0: 9 ];
string credit[ 0: 1 ];
END;
?SECTION ORDERS
! Record Definition for table \SYS.$VOL.SALES.ORDERS
! Definition current at 17:11:32 - 04/20/90
struct orders^type(*);
BEGIN
int(32) ordernum;
int(32) order^date;
int(32) deliv^date;
int salesrep;
int custnum; VSTA02.vsd
END;

HP NonStop SQL Programming Manual for TAL—527887-001


A-4
Sample NonStop SQL Database

Figure A-2. Sample Database Source File (page 3 of 4)

?SECTION ODETAIL
! Record Definition for table \SYS.$VOL.SALES.ODETAIL
! Definition current at 17:11:42 - 04/20/90
struct odetail^type(*);
BEGIN
int(32) ordernum;
int partnum;
int(32) unit^price; ! scale is 2
int(32) qty^ordered;
END;
?SECTION PARTS
! Record Definition for table \SYS.$VOL.SALES.PARTS
! Definition current at 17:11:50 - 04/20/90
struct parts^type(*);
BEGIN
int partnum;
string partdesc[ 0: 17 ];
int(32) price; ! scale is 2
int(32) qty^available;
END;
!
!
! Inventory (INVENT)
!
!
?SECTION SUPPLIER
! Record Definition for table \SYS.$VOL.INVENT.SUPPLIER
! Definition current at 17:12:01 - 04/20/90
struct supplier^type(*);
BEGIN
int suppnum;
string suppname[ 0: 17 ];
string street[ 0: 21 ];
string city[ 0: 13 ];
string state[ 0: 11 ];
string postcode[ 0: 9 ];
VSTA02.vsd
END;

HP NonStop SQL Programming Manual for TAL—527887-001


A-5
Sample NonStop SQL Database

Figure A-2. Sample Database Source File (page 4 of 4)

?SECTION PARTSUPP
! Record Definition for table \SYS.$VOL.INVENT.PARTSUPP
! Definition current at 17:12:11 - 04/20/90
struct partsupp^type(*);
BEGIN
int partnum;
int suppnum;
int(32) partcost; ! scale is 2
int(32) qty^received;
END;
?SECTION PARTLOC
! Record Definition for table \SYS.$VOL.INVENT.PARTLOC
! Definition current at 17:12:23 - 04/20/90
struct partloc^type(*);
BEGIN
string loc^code[ 0: 2 ];
int partnum;
int(32) qty^on^hand;
END;
?SECTION ERRORS
! Record Definition for table \SYS.$VOL.INVENT.ERRORS
! Definition current at 17:12:23 - 04/20/90
struct errors^type(*);
BEGIN
int(32) errors^date;
int(32) errors^time;
int(32) errors^id;
int errors^sql;
int errors^fs;
string errors^text1 [ 0: 239 ];
string errors^text2 [ 0: 239 ];
VSTA02.vsd
END;

HP NonStop SQL Programming Manual for TAL—527887-001


A-6
B
Examples of Static NonStop SQL
Programs
This appendix describes these sample static SQL programs:
• Insertion program (TALTEST)
• Date-time program (TALDT)

Insertion Program
The insertion program (TALTEST) uses the NonStop SQL sample database, which is
described in Appendix A, Sample NonStop SQL Database. TALTEST inserts a part
name, part number, and quantity into the PARTS table and then inserts a new part into
the PARTLOC table.
For database consistency, the program reads the SUPPLIER table to determine
whether the supplier of the part is a record in the table. TALTEST reads the SUPPLIER
table with a cursor, locking the row in the table. Then, it inserts a row in the PARTLOC
and PARTS tables before committing the transaction.
TALTEST uses values that are supplied by initializing variables. It performs error
processing using the SQLCODE value (and not the SQLCA structure).
TALTEST uses the =_DEFAULTS DEFINE for the default catalog in which the SQL
compiler registers the program file and the TACL DEFINE names shown below for the
table names.
SET DEFMODE ON
ALTER DEFINE =_DEFAULTS, CATALOG INVENT
SET DEFINE CLASS MAP
ADD DEFINE =PARTS, FILE SALES.PARTS
ADD DEFINE =SUPPLIER, FILE INVENT.SUPPLIER
ADD DEFINE =PARTLOC, FILE INVENT.PARTLOC
Figure B-1 shows the TALTEST program output. The object file name is TALTESTO.

HP NonStop SQL Programming Manual for TAL—527887-001


B-1
Examples of Static NonStop SQL Programs Insertion Program

Figure B-1. Insertion Program Output

RUN TALTESTO

OUTPUT:

START PROGRAM NEWPART ******


SUPPLIER IS ATTRACTIVE CORP
BEGIN INSERT ON PARTS ************
BEGIN INSERT ON PARTLOC **********
COMMIT TRANSACTION
PART ADDED. PROGRAM ENDS
VSTB01.vsd

HP NonStop SQL Programming Manual for TAL—527887-001


B-2
Examples of Static NonStop SQL Programs Insertion Program

The TAL compiler listing for TALTEST is shown on the following pages.

Page 1 [1] $VOL1.S04.TALTEST 1991-10-15 13:40:20

TAL - T9250C30 - (01NOV91)


Copyright Tandem Computers Incorporated 1976, 1978, 1981-83, 1985, 1987-91
1. 000000 0 0 ?SQL NOWHENEVERLIST
2. 0000000 0 ?SYMBOLS, INSPECT, SAVEABEND, NOMAP, NOCODE, NOGMAP, NOLMAP,
DATAPAGES 64
3. 000000 0 0 ?SEARCH \SYS1.$SYSTEM.SYSTEM.TALLIB
Search file: \SYS1.$SYSTEM.SYSTEM.TALLIB 1991-08-30 11:14:19
4. 000000 0 0
5. 000000 0 0 -- Variables for writing to the terminal:
6. 000000 0 0 INT .home^term[0:11],
7. 000014 0 0 home^term^num,
8. 000014 0 0 .ibuf[0:99];
9. 000160 0 0 STRING .sbuf := @ibuf '<<' 1;
10. 000160 0 0
11. 000160 0 0 -- Pointer to end of the I/O buffer:
12. 000160 0 0 STRING .buf^end;
13. 000160 0 0
14. 000160 0 0 -- SQLCODE for error checking:
15. 000160 0 0 INT sqlcode;
16. 000160 0 0
17. 000160 0 0 -- Program variables:
18. 000160 0 0
19. 000160 0 0 STRUCT .in^data^rec;
20. 000160 0 0 BEGIN
21. 000160 0 1 INT in^partnum;
22. 000160 0 1 STRING in^loc^code[0:17];
23. 000160 0 1 INT(32) in^price;
24. 000160 0 1 STRING in^partdesc[0:17];
25. 000160 0 1 INT(32) in^qty;
26. 000160 0 1 END;
27. 000207 0 0
28. 000207 0 0 -- Host variables:
29. 000207 0 0 EXEC SQL BEGIN DECLARE SECTION;
30. 000207 0 0
31. 000207 0 0 INT supplier^of^parts;
32. 000207 0 0
33. 000207 0 0 EXEC SQL INVOKE =parts AS parts^type;
33. 000207 0 0 EXEC SQL INVOKE =parts AS parts^type;
Source file: [2] $SYSTEM.#3184 1991-10-15 13:40:35
1. 000207 0 0 ! Record Definition for table \SYS1.$VOL1.SALES.PARTS
2. 000207 0 0 ! Definition current at 13:40:35 - 10/15/91
3. 000207 0 0 struct parts^type(*);
4. 000207 0 0 BEGIN
5. 000207 0 1 int partnum /SMALLINT UNSIGNED/;
6. 000207 0 1 string partdesc[0:17];
7. 000207 0 1 int(32) price; ! scale is 2
8. 000207 0 1 int(32) qty^available;
9. 000207 0 1 END;
Source file: [1] $VOL1.S04.TALTEST 1991-10-15 13:35:30
34. 000207 0 0 EXEC SQL INVOKE =supplier AS supplier^type;
34. 000207 0 0 EXEC SQL INVOKE =supplier AS supplier^type;
Source file: [3] $SYSTEM.#3185 1991-10-15 13:40:37
1. 000207 0 0 ! Record Definition for table \SYS1.$VOL1.INVENT.SUPPLIER
2. 000207 0 0 ! Definition current at 13:40:37 - 10/15/91
3. 000207 0 0 struct supplier^type(*);
4. 000207 0 0 BEGIN

HP NonStop SQL Programming Manual for TAL—527887-001


B-3
Examples of Static NonStop SQL Programs Insertion Program

Page 2 [3] $SYSTEM.#3185 1991-10-15


13:40:20

5. 000207 0 1 int suppnum /SMALLINT UNSIGNED/;


6. 000207 0 1 string suppname[0:17];
7. 000207 0 1 string street[0:21];
8. 000207 0 1 string city[0:13];
9. 000207 0 1 string state[0:11];
10. 000207 0 1 string postcode[0:9];
11. 000207 0 1 END;
Source file: [1] $VOL1.S04.TALTEST 1991-10-15 13:35:30
35. 000207 0 0 EXEC SQL INVOKE =partloc AS partloc^type;
35. 000207 0 0 EXEC SQL INVOKE =partloc AS partloc^type;
Source file: [4] $SYSTEM.#3186 1991-10-15 13:40:40
1. 000207 0 0 ! Record Definition for table \TSII.$BOOKS1.S04.PARTLOC
2. 000207 0 0 ! Definition current at 13:40:39 - 10/15/91
3. 000207 0 0 struct partloc^type(*);
4. 000207 0 0 BEGIN
5. 000207 0 1 string loc^code[0:2];
6. 000207 0 1 int partnum /SMALLINT UNSIGNED/;
7. 000207 0 1 int(32) qty^on^hand;
8. 000207 0 1 END;
Source file: [1] $VOL1.S04.TALTEST 1991-10-15 13:35:30
36. 000207 0 0
37. 000207 0 0 STRUCT .parts^rec(parts^type);
38. 000225 0 0 STRUCT .supplier^rec(supplier^type);
39. 000274 0 0 STRUCT .partloc^rec(partloc^type);
40. 000301 0 0
41. 000301 0 0 EXEC SQL END DECLARE SECTION;
42. 000301 0 0
44. 000301 0 0 -- Declare SQL cursors.
45. 000301 0 0 -- This cursor selects from the SUPPLIER table by supplier
number
46. 000301 0 0 -- (SUPPNUM)
47. 000301 0 0
48. 000301 0 0 EXEC SQL DECLARE get_supplier_cursor CURSOR FOR
49. 000301 0 0 SELECT SUPPNUM,
50. 000301 0 0 SUPPNAME,
51. 000301 0 0 STREET,
52. 000301 0 0 CITY,
53. 000301 0 0 STATE,
54. 000301 0 0 POSTCODE
55. 000301 0 0 FROM =supplier
56. 000301 0 0 WHERE SUPPNUM = :supplier^of^parts
57. 000301 0 0 REPEATABLE ACCESS;
58. 000301 0 0
59. 000301 0 0 -- Forward declare error handling procedures:
60. 000301 0 0 PROC NOT^FOUND; FORWARD;
61. 000000 0 0 PROC SQLERROR; FORWARD;
62. 000000 0 0 PROC ABORT^TRANSACTION; FORWARD;
63. 000000 0 0
64. 000000 0 0 -- Copy declarations from EXTDECS file for:
65. 000000 0 0 -- MYTERM, INITIALIZER, OPEN, WRITE, DNUMOUT, and ABEND
66. 000000 0 0
67. 000000 0 0 ?NOLIST, SOURCE $SYSTEM.SYSTEM.EXTDECS (
70. 000000 0 0

HP NonStop SQL Programming Manual for TAL—527887-001


B-4
Examples of Static NonStop SQL Programs Insertion Program

Page 3 [1] $VOL1.S04.TALTEST 1991-10-15 13:40:20

72. 000000 0 0 PROC START^OPERATIONS;


73. 000000 1 0 BEGIN
74. 000000 1 1
75. 000000 1 1 -- Blank out STRING fields in IN^DATA^REC:
76. 000000 1 1 in^data^rec.in^loc^code ':='
77. 000001 1 1 [ $OCCURS(in^data^rec.in^loc^code) * [" "] ];
78. 000013 1 1 in^data^rec.in^partdesc ':='
79. 000013 1 1 [ $OCCURS(in^data^rec.in^partdesc) * [" "] ];
80. 000025 1 1
81. 000025 1 1 -- Assign values to the variables in IN^DATA^REC:
82. 000025 1 1 in^data^rec.in^partnum := 4120;
83. 000030 1 1 in^data^rec.in^loc^code ':=' "A80";
84. 000042 1 1 in^data^rec.in^price := 6000000D;
85. 000047 1 1 in^data^rec.in^partdesc ':=' "V8 DISK OPTION";
86. 000061 1 1 in^data^rec.in^qty := 10D;
87. 000066 1 1
88. 000066 1 1 --Assign a value for supplier:
89. 000066 1 1 supplier^of^parts := 8;
90. 000070 1 1
91. 000070 1 1 -- Write first message to the terminal:
92. 000070 1 1 CALL MYTERM(home^term);
93. 000073 1 1 CALL OPEN(home^term, home^term^num);
94. 000103 1 1 sbuf ':=' "START PROGRAM NEWPART ***** "->@buf^end;
95. 000114 1 1 CALL WRITE(home^term^num,ibuf,@buf^end '-' @sbuf);
96. 000126 1 1
97. 000126 1 1 -- SQL error handling:
98. 000126 1 1 EXEC SQL WHENEVER SQLERROR CALL :SQLERROR;
99. 000126 1 1 EXEC SQL WHENEVER SQLWARNING CALL :SQLERROR;
100. 000126 1 1 EXEC SQL WHENEVER NOT FOUND CALL :NOT^FOUND;
101. 000126 1 1
102. 000126 1 1 -- Begin TMF transaction:
103. 000126 1 1 EXEC SQL BEGIN WORK;
104. 000165 1 1
105. 000165 1 1 END; -- end of START^OPERATIONS
106. 000000 0 0

HP NonStop SQL Programming Manual for TAL—527887-001


B-5
Examples of Static NonStop SQL Programs Insertion Program

J Page 4 [1] $VOL1.S04.TALTEST 1991-10-15 13:40:20

108. 000000 0 0 PROC CHECK^SUPPLIER;


109. 000000 1 0 BEGIN
110. 000000 1 1 -- Open the cursor at value of host variable
SUPPLIER^OF^PARTS:
111. 000000 1 1 EXEC SQL OPEN get_supplier_cursor;
112. 000046 1 1
113. 000046 1 1 -- Perform cursor FETCH:
114. 000046 1 1 EXEC SQL
115. 000046 1 1 FETCH get_supplier_cursor INTO
116. 000046 1 1 :supplier^rec.suppnum,
117. 000046 1 1 :supplier^rec.suppname,
118. 000046 1 1 :supplier^rec.street,
119. 000046 1 1 :supplier^rec.city,
120. 000046 1 1 :supplier^rec.state,
121. 000046 1 1 :supplier^rec.postcode;
122. 000207 1 1
123. 000207 1 1 -- A not-found condition goes to abort^transaction;
otherwise,
124. 000207 1 1 -- the supplier record is present.
125. 000207 1 1
126. 000207 1 1 sbuf ':=' "SUPPLIER IS "&supplier^rec.suppname
127. 000207 1 1 FOR $OCCURS(supplier^rec.suppname) ->@buf^end;
128. 000225 1 1 CALL WRITE(home^term^num,ibuf,@buf^end '-' @sbuf);
129. 000237 1 1
130. 000237 1 1 END; --end of CHECK^SUPPLIER
131. 000000 0 0

Page 5 [1] $VOL1.S04.TALTEST 1991-10-15 13:40:20

133. 000000 0 0 PROC DO^ADD^TO^PARTS;


134. 000000 1 0 BEGIN
135. 000000 1 1 parts^rec.partnum := in^data^rec.in^partnum;
136. 000003 1 1 parts^rec.partdesc ':=' in^data^rec.in^partdesc
137. 000003 1 1 FOR $OCCURS(parts^rec.partdesc);
138. 000013 1 1 parts^rec.price := in^data^rec.in^price;
139. 000016 1 1 parts^rec.qty^available := in^data^rec.in^qty;
140. 000023 1 1
141. 000023 1 1 sbuf ':=' "BEGIN INSERT ON PARTS *******"->@buf^end;
142. 000034 1 1 CALL WRITE(home^term^num,ibuf,@buf^end '-' @sbuf);
143. 000046 1 1
144. 000046 1 1 --Insert the record. Use SETSCALE to communicate a scale
145. 000046 1 1 --of 2 to SQL (SETSCALE is used because you are using the
146. 000046 1 1 --INVOKE generated descriptions; otherwise, you could
define
147. 000046 1 1 --the PRICE column as FIXED(2).
148. 000046 1 1 EXEC SQL
149. 000046 1 1 INSERT INTO =PARTS
150. 000046 1 1 VALUES ( :parts^rec.partnum,
151. 000046 1 1 :parts^rec.partdesc,
152. 000046 1 1 SETSCALE (:parts^rec.price, 2),
153. 000046 1 1 :parts^rec.qty^available);
154. 000140 1 1 END;
155. 000000 0 0 --End of DO^ADD^TO^PARTS
156. 000000 0 0

HP NonStop SQL Programming Manual for TAL—527887-001


B-6
Examples of Static NonStop SQL Programs Insertion Program

Page 6 [1] $VOL1.S04.TALTEST 1991-10-15 13:40:20


158. 000000 0 0 PROC DO^ADD^TO^PARTLOC;
159. 000000 1 0 BEGIN
160. 000000 1 1 partloc^rec.loc^code ':=' in^data^rec.in^loc^code
161. 000001 1 1 FOR $OCCURS(partloc^rec.loc^code);
162. 000010 1 1 --Length of PARTLOC^REC.LOC^CODE is used because it's the
smaller
163. 000010 1 1 --size.
164. 000010 1 1
165. 000010 1 1 partloc^rec.partnum := in^data^rec.in^partnum;
166. 000013 1 1 partloc^rec.qty^on^hand := in^data^rec.in^qty;
167. 000021 1 1
168. 000021 1 1 sbuf ':=' "BEGIN INSERT ON PARTLOC *******"->@buf^end;
169. 000032 1 1 CALL WRITE(home^term^num,ibuf,@buf^end '-' @sbuf);
170. 000044 1 1
171. 000044 1 1 EXEC SQL
172. 000044 1 1 INSERT INTO =PARTLOC
173. 000044 1 1 VALUES ( :partloc^rec.loc^code,
174. 000044 1 1 :partloc^rec.partnum,
175. 000044 1 1 :partloc^rec.qty^on^hand );
176. 000127 1 1
177. 000127 1 1 END; --end of DO^ADD^TO^PARTLOC
178. 000000 0 0
179. 000000 0 0

Page 7 [1] $VOL1.S04.TALTEST 1991-10-15 13:40:20

181. 000000 0 0 PROC CLOSE^CURSOR;


182. 000000 1 0 BEGIN
183. 000000 1 1 EXEC SQL CLOSE get_supplier_cursor;
184. 000046 1 1 END;
185. 000000 0 0
186. 000000 0 0
187. 000000 0 0 PROC COMMIT^TRANSACTION;
188. 000000 1 0 BEGIN
189. 000000 1 1 EXEC SQL COMMIT WORK;
190. 000040 1 1 sbuf ':=' "COMMIT TRANSACTION"->@buf^end;
191. 000051 1 1 CALL WRITE(home^term^num,ibuf,@buf^end '-' @sbuf);
192. 000063 1 1 END;
193. 000000 0 0

HP NonStop SQL Programming Manual for TAL—527887-001


B-7
Examples of Static NonStop SQL Programs Insertion Program

Page 8 [1] $VOL1.S04.TALTEST 1991-10-15 13:40:20


195. 000000 0 0 PROC NOT^FOUND;
196. 000000 1 0 BEGIN
197. 000000 1 1 CALL CLOSE^CURSOR;
198. 000002 1 1 sbuf ':=' "SUPPLIER NOT FOUND: SUPPNUM IS "->@buf^end;
199. 000013 1 1
200. 000013 1 1 --Call DNUMOUT to convert INTeger supplier^of^parts value
to
201. 000013 1 1 --ASCII characters for display on the terminal. DNUMOUT is
202. 000013 1 1 --used (with $DBL) instead of using NUMOUT because DNUMOUT
203. 000013 1 1 --suppresses leading zeroes while NUMOUT does not.
204. 000013 1 1 @buf^end := @buf^end '+' DNUMOUT(buf^end,
205. 000013 1 1 $DBL(supplier^of^parts), 10, -1);
206. 000034 1 1 CALL WRITE(home^term^num,ibuf,@buf^end '-' @sbuf);
207. 000046 1 1 CALL ABORT^TRANSACTION;
208. 000047 1 1 CALL ABEND;
209. 000054 1 1
210. 000054 1 1 END; --end of NOT^FOUND
211. 000000 0 0
212. 000000 0 0
213. 000000 0 0 PROC SQLERROR;
214. 000000 1 0 BEGIN
215. 000000 1 1 -- Local variable for SQLCODE. Since we might be changing
216. 000000 1 1 -- the sign of SQLCODE for display, we want to preserve the
217. 000000 1 1 -- global SQLCODE value for future debugging.
218. 000000 1 1 INT errcode;
219. 000000 1 1 errcode := sqlcode;
220. 000003 1 1
221. 000003 1 1 -- Test for negative value in SQLCODE. If the value is an
SQL
222. 000003 1 1 -- error and not a warning, it will be negative. We must
then
223. 000003 1 1 -- change the value to positive in order to display it with
224. 000003 1 1 -- DNUMOUT, because DNUMOUT expects an unsigned number.
225. 000003 1 1 IF errcode < 0 THEN
226. 000006 1 1 BEGIN
227. 000006 1 2 sbuf ':=' "SQL ERROR: -"->@buf^end;
228. 000017 1 2 errcode := -errcode;
229. 000022 1 2 END
230. 000022 1 1 ELSE IF errcode > 0 THEN
231. 000026 1 1 sbuf ':=' "SQL WARNING: "->@buf^end;
232. 000037 1 1
233. 000037 1 1 @buf^end := @buf^end '+' DNUMOUT(buf^end, $DBL(errcode),
10, -1);
234. 000060 1 1 CALL WRITE(home^term^num,ibuf,@buf^end '-' @sbuf);
235. 000072 1 1 CALL ABORT^TRANSACTION;
236. 000073 1 1 CALL ABEND;
237. 000100 1 1 END;
238. 000000 0 0
239. 000000 0 0

HP NonStop SQL Programming Manual for TAL—527887-001


B-8
Examples of Static NonStop SQL Programs Insertion Program

Page 9 [1] $VOL1.S04.TALTEST 1991-10-15 13:40:20


241. 000000 0 0 PROC ABORT^TRANSACTION;
242. 000000 1 0 BEGIN
243. 000000 1 1 EXEC SQL ROLLBACK WORK;
244. 000040 1 1 sbuf ':=' "TRANSACTION ABORTED"->@buf^end;
245. 000051 1 1 CALL WRITE(home^term^num,ibuf,@buf^end '-' @sbuf);
246. 000063 1 1 END;
247. 000000 0 0
248. 000000 0 0
249. 000000 0 0 PROC SUCCESSFUL^COMPLETION;
250. 000000 1 0 BEGIN
251. 000000 1 1 sbuf ':=' "PART ADDED. PROGRAM ENDS"->@buf^end;
252. 000012 1 1 CALL WRITE(home^term^num,ibuf,@buf^end '-' @sbuf);
253. 000024 1 1 END;
254. 000000 0 0

Page 10 [1] $VOL1.S04.TALTEST 1991-10-15 13:40:20

256. 000000 0 0 --Main program code:


257. 000000 0 0 PROC DRIVER MAIN;
258. 000000 1 0 BEGIN
259. 000000 1 1
260. 000000 1 1 --Read the system startup message:
261. 000000 1 1 CALL INITIALIZER;
262. 000006 1 1
263. 000006 1 1 CALL START^OPERATIONS;
264. 000007 1 1 CALL CHECK^SUPPLIER;
265. 000010 1 1 CALL DO^ADD^TO^PARTS;
266. 000011 1 1 CALL DO^ADD^TO^PARTLOC;
267. 000012 1 1 CALL CLOSE^CURSOR;
268. 000013 1 1 CALL COMMIT^TRANSACTION;
269. 000014 1 1 CALL SUCCESSFUL^COMPLETION;
270. 000015 1 1
271. 000015 1 1 END; --end of DRIVER

HP NonStop SQL Programming Manual for TAL—527887-001


B-9
Examples of Static NonStop SQL Programs Date-Time Program

Page 11 [1] $VOL1.S04.TALTEST 1991-10-15 13:40:20


BINDER AND COMPILER STATISTICS

BINDER - OBJECT FILE BINDER - T9621C30 - (01NOV91) SYSTEM \SYS1.


Copyright Tandem Computers Incorporated 1982-1989, 1991

Object file $VOL1.S04.TALS1O


TIMESTAMP 1991-10-15 13:40:20

1 Code page

11 Primary data words


193 Secondary data words
64 Data pages
0 Resident code pages
1 Extended data page

204 Top of stack location in words


1 Code segment

0 Binder Warnings
0 Binder Errors

TAL - Transaction Application Language - T9250C30 - (01NOV91)


Number of compiler errors = 0
Number of unsuppressed compiler warnings = 0
Number of warnings suppressed by NOWARN = 0
Maximum symbol table space used was = 24692 bytes
Number of source lines = 3031
Compile cpu time = 00:00:03
Total Elapsed time = 00:00:40

Date-Time Program
The date-time sample program (TALDT) inserts values into the PROJECTS table,
which you can create using this CREATE TABLE statement.:
CREATE TABLE PROJECTS
( PROJECT_NAME CHAR( 10 ) NO DEFAULT NOT NULL
, START_DATE DATETIME YEAR TO MINUTE NO DEFAULT NOT NULL
, END_DATE DATETIME YEAR TO MINUTE NO DEFAULT NOT NULL
, WAIT_TIME INTERVAL DAY(2) NO DEFAULT NOT NULL
) CATALOG =PROJ ;
TALDT refers to the PROJECTS table using the DEFINE name =PROJECTS and the
catalog using the DEFINE name =PROJ. The commands to add these DEFINE names
are:
SET DEFINE CLASS MAP
ADD DEFINE =PROJECTS, FILE PROJ.PROJECTS
SET DEFINE CLASS CATALOG
ADD DEFINE =PROJ, SUBVOL PROJ
TALDT can perform these functions:

HP NonStop SQL Programming Manual for TAL—527887-001


B-10
Examples of Static NonStop SQL Programs Date-Time Program

• Insert a new project name, start date, end date, and wait time.
• Add more wait time to a project by updating the WAIT_TIME column in the
PROJECTS table. The original dates in the START_DATE and END_DATE
columns in the PROJECTS table remain unchanged.
• Print a report showing the original dates and the new dates. The report function
computes the new dates by adding wait time to both the start date and end date.
TALDT also shows these error handling techniques:
• A temporary variable to save the SQLCODE value within an error handling routine,
which allows the program to use the value after handling the error
• The temporary disabling of WHENEVER SQLERROR checking to avoid a possible
infinite loop if an error should occur in the error handling routine
• The temporary disabling of WHENEVER NOT FOUND checking for a cursor
FETCH operation
• The use of the SQLCODE value to make processing decisions and to make certain
operations conditional upon the absence of any errors
Figure B-2 shows a sample run of TALDT. The object file is TALDTO. The data entered
by the user is shown in bold type. Figure B-2 also includes SQLCI sessions, displaying
the contents of the PROJECTS table before and after the program updates the table.

HP NonStop SQL Programming Manual for TAL—527887-001


B-11
Examples of Static NonStop SQL Programs Date-Time Program

Figure B-2. Date-Time Program Run (page 1 of 3)

14> SQLCI
>>select * from =projects;

PROJECT_NAME START_DATE END_DATE WAIT_TIME

920 1988-02-21:20:30 1989-03-21:20:30 30


134 1970-01-01:00:00 1978-03-21:20:30 30
- - - 2 row(s) selected.
>>exit;

End of SQLCI Session


15> RUN TALDTO
START PROJECTS UPDATE PROGRAM
PLEASE ENTER:
1 -- to insert new project data
2 -- to add wait time to a project
3 -- to report original and new project dates
4 -- to exit the program

Please enter selection:1


Enter a project name of up to 10 characters:777
Enter a start date-time as YYYY-MM-DD:HH:MM:1989-07-15:06:30
Enter an end date-time as YYYY-MM-DD:HH:MM:1989-10-31:23:58
Wait time for the new project is set at 0.
***** RECORD INSERTED *****
PLEASE ENTER:

1 -- to insert new project data


2 -- to add wait time to a project
3 -- to report original and new project dates
4 -- to exit the program

Please enter selection:2

Enter a project name of up to 10 characters:777


Enter number of days of wait time to add:092 VSTB02.vsd
***** WAIT TIME ADDED *****

HP NonStop SQL Programming Manual for TAL—527887-001


B-12
Examples of Static NonStop SQL Programs Date-Time Program

Figure B-2. Date-Time Program Run (page 2 of 3)

PLEASE ENTER:
1 - - to insert new project data
2 - - to add wait time to a project
3 - - to report original and new project dates
4 - - to exit the program
Please enter selection:3
*************************************************
ORIGINAL DATES:
*************************************************
PROJECT NAME: 920
START DATE: 1988-02-21:20:30
END DATE: 1989-03-21:20:30

PROJECT NAME: 134


START DATE: 1970-01-01:00:00
END DATE: 1978-03-21:20:30

PROJECT NAME: 777


START DATE: 1989-07-15:06:30
END DATE: 1989-10-31:23:58
*************************************************
NEW DATES:
*************************************************
PROJECT NAME: 920
START DATE: 1988-03-22:20:30
END DATE: 1989-04-20:20:30
WAIT TIME: 30 DAYS
PROJECT NAME: 134
START DATE: 1970-01-31:00:00
END DATE: 1978-04-20:20:30
WAIT TIME: 30 DAYS
PROJECT NAME: 777
START DATE: 1989-10-15:06:30
END DATE: 1990-01-31:23:58 VSTB02.vsd
WAIT TIME: 92 DAYS

HP NonStop SQL Programming Manual for TAL—527887-001


B-13
Examples of Static NonStop SQL Programs Date-Time Program

Figure B-2. Date-Time Program Run (page 3 of 3)

PLEASE ENTER:
1 - - to insert new project data
2 - - to add wait time to a project
3 - - to report original and new project dates
4 - - to exit the program
Please enter selection:4
TERMINATING PROJECTS UPDATE PROGRAM

16> SQLCI
>>select * from =projects;
PROJECT_NAME START_DATE END_DATE WAIT_TIME

920 1988-02-21:20:30 1989-03-21:20:30 30


134 1970-01-01:00:00 1978-03-21:20:30 30
777 1989-07-15:06:30 1989-10-31:23:58 92
--- 3 row(s) selected. VSTB02.vsd

HP NonStop SQL Programming Manual for TAL—527887-001


B-14
Examples of Static NonStop SQL Programs Date-Time Program

The TAL compiler listing for TALDT is shown on the following pages.

Page 1 [1] $VOL1.S04.TALDT 1991-10-15 13:41:07

TAL - T9250C30 - (01NOV91)


Copyright Tandem Computers Incorporated 1976, 1978, 1981-83, 1985, 1987-91

1. 000000 0 0 ?SQL NOWHENEVERLIST


2. 000000 0 0 ?SYMBOLS, INSPECT, SAVEABEND, NOMAP, NOCODE, NOGMAP, NOLMAP,
DATAPAGES 64
3. 000000 0 0 ?SEARCH \SYS1.$SYSTEM.SYSTEM.TALLIB
Search file: \SYS1.$SYSTEM.XTALC30.TALLIB 1991-08-30 11:14:19
4. 000000 0 0
5. 000000 0 0 -- Variables for terminal I/O:
6. 000000 0 0 INT .HOME^TERM[0:11],
7. 000014 0 0 HOME^TERM^NUM,
8. 000014 0 0 NUM^READ,
9. 000014 0 0 .IBUF[0:99];
10. 000160 0 0 STRING .SBUF := @IBUF '<<' 1;
11. 000160 0 0
12. 000160 0 0 -- Pointer to end of the I/O buffer:
13. 000160 0 0 STRING .BUF^END;
14. 000160 0 0
15. 000160 0 0
16. 000160 0 0 -- Invoke the PROJECTS table into 3 record areas for:
17. 000160 0 0 -- -storing the current dates
18. 000160 0 0 -- -storing the original dates
19. 000160 0 0 -- -storing the values entered by the user as search
criteria
20. 000160 0 0 -- The original dates will be used in the report function.
21. 000160 0 0 --
22. 000160 0 0 -- The TYPE description for the PROJECTS table from INVOKE is:
23. 000160 0 0 --
24. 000160 0 0 -- STRUCT PROJECTS^TYPE(*);
25. 000160 0 0 -- BEGIN
26. 000160 0 0 -- STRING PROJECT^NAME[0 : 9];
27. 000160 0 0 -- STRING START^DATE[0 : 15];
28. 000160 0 0 -- STRING END^DATE[0 : 15];
29. 000160 0 0 -- STRING WAIT^TIME[0 : 2];
30. 000160 0 0 -- END;
31. 000160 0 0 -- Note that INVOKE generates an extra byte for INTERVAL
values,
32. 000160 0 0 -- to accommodate a possible negative sign.
33. 000160 0 0
34. 000160 0 0 EXEC SQL BEGIN DECLARE SECTION;
35. 000160 0 0 EXEC SQL INVOKE =PROJECTS AS PROJECTS^TYPE;
35. 000160 0 0 EXEC SQL INVOKE =PROJECTS AS PROJECTS^TYPE;
Source file: [2] $SYSTEM.#3187 1991-10-15 13:41:24
1. 000160 0 0 ! Record Definition for table \TSII.$BOOKS1.S04.PROJECTS
2. 000160 0 0 ! Definition current at 13:41:24 - 10/15/91
3. 000160 0 0 struct projects^type(*);
4. 000160 0 0 BEGIN
5. 000160 0 1 string project^name[0:9];
6. 000160 0 1 string start^date[0:15];
7. 000160 0 1 string end^date[0:15];
8. 000160 0 1 string wait^time[0:2];
9. 000160 0 1 END;
Source file: [1] $VOL1.S04.TALDT 1991-10-15 13:35:04
36. 000160 0 0
37. 000160 0 0 STRUCT .USER^PROJECTS^REC(PROJECTS^TYPE);
38. 000207 0 0 STRUCT .OLD^PROJECTS^REC(PROJECTS^TYPE);
39. 000236 0 0 STRUCT .NEW^PROJECTS^REC(PROJECTS^TYPE);
40. 000265 0 0

HP NonStop SQL Programming Manual for TAL—527887-001


B-15
Examples of Static NonStop SQL Programs Date-Time Program

Page 2 [1] $VOL1.S04.TALDT 1991-10-15 13:41:07


41. 000265 0 0 EXEC SQL END DECLARE SECTION;
42. 000265 0 0
43. 000265 0 0 INT SQLCODE;
44. 000265 0 0
45. 000265 0 0 STRING SEL^INDEX;
46. 000265 0 0 -- for user's choice from menu
47. 000265 0 0
48. 000265 0 0 EXEC SQL INCLUDE SQLCA;
48. 000265 0 0 EXEC SQL INCLUDE SQLCA;
Source file: [3] $SYSTEM.#3188 1991-10-15 13:41:27
1. 000265 0 0 struct .SQLCA;
2. 000265 0 0 BEGIN
3. 000265 0 1 STRING filler^[0:429];
4. 000265 0 1 END; -- SQLCA
Source file: [1] $VOL1.S04.TALDT 1991-10-15 13:35:04
49. 000614 0 0 -- for SQLCADISPLAY
50. 000614 0 0
51. 000614 0 0 -- Declare cursors for report function :
52. 000614 0 0
53. 000614 0 0 EXEC SQL
54. 000614 0 0 DECLARE OLD_DATES_CURSOR CURSOR FOR
55. 000614 0 0 SELECT PROJECT_NAME,
56. 000614 0 0 START_DATE,
57. 000614 0 0 END_DATE
58. 000614 0 0 FROM =PROJECTS;
59. 000614 0 0
60. 000614 0 0 EXEC SQL
61. 000614 0 0 DECLARE NEW_DATES_CURSOR CURSOR FOR
62. 000614 0 0 SELECT PROJECT_NAME,
63. 000614 0 0 START_DATE + WAIT_TIME,
64. 000614 0 0 END_DATE + WAIT_TIME,
65. 000614 0 0 WAIT_TIME
66. 000614 0 0 FROM =PROJECTS;
67. 000614 0 0
68. 000614 0 0 -- Copy declarations from EXTDECS file for:
69. 000614 0 0 -- MYTERM, INITIALIZER, SQLCADISPLAY, OPEN, WRITE, WRITEREAD,
and STOP
70. 000614 0 0
71. 000614 0 0 ?NOLIST, SOURCE $SYSTEM.SYSTEM.EXTDECS (
75. 000000 0 0
76. 000000 0 0 -- SQL error handling:
77. 000000 0 0 PROC SQL^ERROR; FORWARD;
78. 000000 0 0 PROC NOT^FOUND; FORWARD;
79. 000000 0 0 EXEC SQL WHENEVER NOT FOUND CALL :NOT^FOUND;
80. 000000 0 0
81. 000000 0 0 -- Treat warnings the same as errors for simplicity
82. 000000 0 0 EXEC SQL WHENEVER SQLWARNING CALL :SQL^ERROR;
83. 000000 0 0
84. 000000 0 0 EXEC SQL
85. 000000 0 0 WHENEVER SQLERROR CALL :SQL^ERROR;
86. 000000 0 0 -- Forward declaring these procedures for clarity in later
calls
87. 000000 0 0 PROC FETCH^AND^DISPLAY^OLD; FORWARD;
88. 000000 0 0 PROC FETCH^AND^DISPLAY^NEW; FORWARD;
89. 000000 0 0
90. 000000 0 0
91. 000000 0 0 PROC NOT^FOUND;
92. 000000 1 0
93. 000000 1 0 BEGIN

HP NonStop SQL Programming Manual for TAL—527887-001


B-16
Examples of Static NonStop SQL Programs Date-Time Program

Page 3 [1] $VOL1.S04.TALDT 1991-10-15 13:41:07


94. 000000 1 1
95. 000000 1 1 -- Temporary variable to save the value of SQLCODE for
later
96. 000000 1 1 -- checking. ROLLBACK WORK sets SQLCODE to 0.
97. 000000 1 1 INT TEMP^SQLCODE;
98. 000000 1 1
99. 000000 1 1 TEMP^SQLCODE := SQLCODE;
100. 000003 1 1
101. 000003 1 1 SBUF ':=' " RECORD NOT FOUND ***** "->@BUF^END;
102. 000014 1 1 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF);
103. 000026 1 1
104. 000026 1 1 EXEC SQL ROLLBACK WORK;
105. 000074 1 1
106. 000074 1 1 SBUF ':=' " TRANSACTION ABORTED ***** "->@BUF^END;
107. 000105 1 1 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF);
108. 000117 1 1
109. 000117 1 1 SQLCODE := TEMP^SQLCODE;
110. 000121 1 1 END;
111. 000000 0 0
112. 000000 0 0 PROC SQL^ERROR;
113. 000000 1 0 BEGIN
114. 000000 1 1
115. 000000 1 1 -- Temporary variable to save the value of SQLCODE for
later
116. 000000 1 1 -- checking. ROLLBACK WORK sets SQLCODE to 0.
117. 000000 1 1 INT TEMP^SQLCODE;
118. 000000 1 1
119. 000000 1 1 TEMP^SQLCODE := SQLCODE;
120. 000003 1 1
121. 000003 1 1 -- Turn off WHENEVER checking to avoid infinite loop:
122. 000003 1 1 EXEC SQL WHENEVER SQLERROR CONTINUE;
123. 000003 1 1
124. 000003 1 1 CALL SQLCADISPLAY( SQLCA );
125. 000015 1 1 EXEC SQL ROLLBACK WORK;
126. 000057 1 1
127. 000057 1 1 SBUF ':=' " TRANSACTION ABORTED ***** "->@BUF^END;
128. 000070 1 1 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF);
129. 000102 1 1
130. 000102 1 1 -- re-enable WHENEVER checking:
131. 000102 1 1 EXEC SQL WHENEVER SQLERROR CALL :SQL^ERROR;
132. 000102 1 1
133. 000102 1 1 SQLCODE := TEMP^SQLCODE;
134. 000104 1 1 END;
135. 000000 0 0
136. 000000 0 0 PROC INSERT^PROJECT;
137. 000000 1 0 BEGIN
138. 000000 1 1
139. 000000 1 1 EXEC SQL BEGIN WORK;
140. 000047 1 1
141. 000047 1 1 SBUF ':=' "Enter a project name of up to 10 characters: "
->@BUF^END;
142. 000060 1 1 CALL WRITEREAD(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF,20,
NUM^READ);
143. 000073 1 1 USER^PROJECTS^REC.PROJECT^NAME ':=' SBUF FOR NUM^READ;
144. 000100 1 1
145. 000100 1 1 SBUF ':=' "Enter a start date-time as YYYY-MM-DD:HH:MM "
->@BUF^END;
146. 000111 1 1 CALL WRITEREAD(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF,26,
NUM^READ);
147. 000124 1 1 USER^PROJECTS^REC.START^DATE ':=' SBUF FOR NUM^READ;
148. 000132 1 1
149. 000132 1 1 SBUF ':=' "Enter an end date-time as YYYY-MM-DD:HH:MM "
->@BUF^END;
150. 000143 1 1 CALL WRITEREAD(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF,26,
NUM^READ);

HP NonStop SQL Programming Manual for TAL—527887-001


B-17
Examples of Static NonStop SQL Programs Date-Time Program

Page 4 [1] $VOL1.S04.TALDT 1991-10-15 13:41:07


151. 000156 1 1 USER^PROJECTS^REC.END^DATE ':=' SBUF FOR NUM^READ;
152. 000164 1 1
153. 000164 1 1 SBUF ':=' "Wait time for the new project is set at 0
"->@BUF^END;
154. 000175 1 1 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF);
155. 000214 1 1
156. 000214 1 1 USER^PROJECTS^REC.WAIT^TIME ':=' "00";
157. 000226 1 1
158. 000226 1 1 EXEC SQL
159. 000226 1 1 INSERT INTO =PROJECTS
160. 000226 1 1 (PROJECT_NAME, START_DATE, END_DATE,
161. 000226 1 1 WAIT_TIME)
162. 000226 1 1 VALUES
163. 000226 1 1 ( :USER^PROJECTS^REC.PROJECT^NAME,
164. 000226 1 1 :USER^PROJECTS^REC.START^DATE
165. 000226 1 1 TYPE AS DATETIME YEAR TO MINUTE,
166. 000226 1 1 :USER^PROJECTS^REC.END^DATE
167. 000226 1 1 TYPE AS DATETIME YEAR TO MINUTE,
168. 000226 1 1 :USER^PROJECTS^REC.WAIT^TIME
169. 000226 1 1 TYPE AS INTERVAL DAY(2) );
170. 000327 1 1
171. 000327 1 1 IF SQLCODE = 0 THEN
172. 000331 1 1 BEGIN
173. 000331 1 2 SBUF ':=' "***** RECORD INSERTED ***** "->@BUF^END;
174. 000342 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF);
175. 000354 1 2 EXEC SQL COMMIT WORK;
176. 000422 1 2 END;
177. 000422 1 1
178. 000422 1 1
179. 000422 1 1 END; -- insert^project
180. 000000 0 0
181. 000000 0 0
182. 000000 0 0 PROC ADD^WAIT^TIME;
183. 000000 1 0 --
184. 000000 1 0 --"Wait time" is assumed to express a delay in starting the
185. 000000 1 0 -- project. The report function will add the wait time to
the
186. 000000 1 0 -- start and end dates and report the new dates. Here, we
187. 000000 1 0 -- simply update the wait time column in the database. The
188. 000000 1 0 -- database always stores the original dates.
189. 000000 1 0
190. 000000 1 0 BEGIN
191. 000000 1 1 EXEC SQL BEGIN WORK;
192. 000047 1 1
193. 000047 1 1 SBUF ':=' "Enter a project name of up to 10 characters:
"->@BUF^END;
194. 000060 1 1 CALL WRITEREAD(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF,20,
NUM^READ);
195. 000073 1 1 USER^PROJECTS^REC.PROJECT^NAME ':=' SBUF FOR NUM^READ;
196. 000100 1 1
197. 000100 1 1 SBUF ':=' "Enter number of days of wait time to add: "
->@BUF^END;
198. 000111 1 1 CALL WRITEREAD(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF,20,
NUM^READ);
199. 000124 1 1 USER^PROJECTS^REC.WAIT^TIME ':=' SBUF FOR NUM^READ;
200. 000132 1 1
201. 000132 1 1 EXEC SQL
202. 000132 1 1 UPDATE =PROJECTS
203. 000132 1 1 SET WAIT_TIME = WAIT_TIME
204. 000132 1 1 + :USER^PROJECTS^REC.WAIT^TIME TYPE AS INTERVAL DAY(2)
205. 000132 1 1 WHERE PROJECT_NAME = :USER^PROJECTS^REC.PROJECT^NAME;
206. 000232 1 1
207. 000232 1 1 IF SQLCODE = 0 THEN

HP NonStop SQL Programming Manual for TAL—527887-001


B-18
Examples of Static NonStop SQL Programs Date-Time Program

Page 5 [1] $VOL1.S04.TALDT 1991-10-15 13:41:07


208. 000234 1 1 BEGIN
209. 000234 1 2 SBUF ':=' "***** WAIT TIME ADDED ***** "->@BUF^END;
210. 000245 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF);
211. 000257 1 2 EXEC SQL COMMIT WORK;
212. 000325 1 2 END;
213. 000325 1 1
214. 000325 1 1 END; -- add^wait^time
215. 000000 0 0
216. 000000 0 0 -- Disable WHENEVER NOT FOUND checking so NOT^FOUND code
217. 000000 0 0 -- is not triggered at the end of the FETCH, and so
218. 000000 0 0 -- the program does not stop after fetching the old
219. 000000 0 0 -- records.
220. 000000 0 0 EXEC SQL WHENEVER NOT FOUND CONTINUE;
221. 000000 0 0
222. 000000 0 0 PROC PRINT^REPORT;
223. 000000 1 0 BEGIN
224. 000000 1 1
225. 000000 1 1 EXEC SQL BEGIN WORK;
226. 000043 1 1
227. 000043 1 1 EXEC SQL
228. 000043 1 1 OPEN OLD_DATES_CURSOR;
229. 000105 1 1
230. 000105 1 1 EXEC SQL
231. 000105 1 1 OPEN NEW_DATES_CURSOR;
232. 000147 1 1
233. 000147 1 1 IF SQLCODE = 0 THEN
234. 000151 1 1 BEGIN
235. 000151 1 2 SBUF ':=' "*********************************** "
->@BUF^END;
236. 000162 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF);
237. 000174 1 2 SBUF ':=' "ORIGINAL DATES: "->@BUF^END;
238. 000222 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,0);
239. 000232 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF);
240. 000244 1 2 SBUF ':=' "*********************************** "
->@BUF^END;
241. 000255 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF);
242. 000267 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,0);
243. 000277 1 2
244. 000277 1 2 DO
245. 000277 1 2 CALL FETCH^AND^DISPLAY^OLD
246. 000277 1 2 UNTIL SQLCODE <> 0;
247. 000302 1 2 END;
248. 000302 1 1
249. 000302 1 1 -- Check for NOT FOUND -- came to the end of the records
250. 000302 1 1 IF SQLCODE = 100 THEN
251. 000305 1 1 BEGIN
252. 000305 1 2
253. 000305 1 2 SBUF ':=' "*********************************** "
->@BUF^END;
254. 000316 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF);
255. 000330 1 2 SBUF ':=' "NEW DATES: "->@BUF^END;
256. 000341 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF);
257. 000353 1 2 SBUF ':=' "*********************************** "
->@BUF^END;
258. 000364 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF);
259. 000376 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,0);
260. 000406 1 2
261. 000406 1 2 -- FETCH sets SQLCODE back to 0
262. 000406 1 2 DO
263. 000406 1 2 CALL FETCH^AND^DISPLAY^NEW
264. 000406 1 2 UNTIL SQLCODE <> 0;

HP NonStop SQL Programming Manual for TAL—527887-001


B-19
Examples of Static NonStop SQL Programs Date-Time Program

Page 6 [1] $VOL1.S04.TALDT 1991-10-15 13:41:07


265. 000411 1 2 END;
266. 000411 1 1
267. 000411 1 1 IF SQLCODE = 100 THEN
268. 000414 1 1 EXEC SQL COMMIT WORK;
269. 000456 1 1
270. 000456 1 1 END; -- print^report
271. 000000 0 0
272. 000000 0 0
273. 000000 0 0 -- FETCH^AND^DISPLAY^OLD does not access WAIT^TIME, while
274. 000000 0 0 -- FETCH^AND^DISPLAY^NEW accesses and reports WAIT^TIME.
275. 000000 0 0
276. 000000 0 0 PROC FETCH^AND^DISPLAY^OLD;
277. 000000 1 0 BEGIN
278. 000000 1 1 EXEC SQL
279. 000000 1 1 FETCH OLD_DATES_CURSOR INTO
280. 000000 1 1 :OLD^PROJECTS^REC.PROJECT^NAME,
281. 000000 1 1 :OLD^PROJECTS^REC.START^DATE
282. 000000 1 1 TYPE AS DATETIME YEAR TO MINUTE,
283. 000000 1 1 :OLD^PROJECTS^REC.END^DATE
284. 000000 1 1 TYPE AS DATETIME YEAR TO MINUTE;
285. 000067 1 1
286. 000067 1 1 IF (SQLCODE <> 100) AND (SQLCODE >= 0) THEN
287. 000075 1 1 BEGIN
288. 000075 1 2 SBUF ':=' "PROJECT NAME: "->@BUF^END;
289. 000106 1 2 BUF^END ':=' OLD^PROJECTS^REC.PROJECT^NAME FOR 10
->@BUF^END;
290. 000114 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF);
291. 000126 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,0);
292. 000136 1 2
293. 000136 1 2 SBUF ':=' "START DATE: "->@BUF^END;
294. 000147 1 2 BUF^END ':=' OLD^PROJECTS^REC.START^DATE FOR 16
->@BUF^END;
295. 000156 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF);
296. 000170 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,0);
297. 000200 1 2
298. 000200 1 2 SBUF ':=' "END DATE: "->@BUF^END;
299. 000224 1 2 BUF^END ':=' OLD^PROJECTS^REC.END^DATE FOR 16
->@BUF^END;
300. 000233 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF);
301. 000245 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,0);
302. 000255 1 2
303. 000255 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,0);
304. 000265 1 2
305. 000265 1 2 END;
306. 000265 1 1 END; -- fetch^and^display^old
307. 000000 0 0
308. 000000 0 0
309. 000000 0 0 PROC FETCH^AND^DISPLAY^NEW;
310. 000000 1 0 BEGIN
311. 000000 1 1 EXEC SQL
312. 000000 1 1 FETCH NEW_DATES_CURSOR INTO
313. 000000 1 1 :NEW^PROJECTS^REC.PROJECT^NAME,
314. 000000 1 1 :NEW^PROJECTS^REC.START^DATE
315. 000000 1 1 TYPE AS DATETIME YEAR TO MINUTE,
316. 000000 1 1 :NEW^PROJECTS^REC.END^DATE
317. 000000 1 1 TYPE AS DATETIME YEAR TO MINUTE,
318. 000000 1 1 :NEW^PROJECTS^REC.WAIT^TIME
319. 000000 1 1 TYPE AS INTERVAL DAY(2);
320. 000076 1 1
321. 000076 1 1 IF (SQLCODE <> 100) AND (SQLCODE >= 0) THEN

HP NonStop SQL Programming Manual for TAL—527887-001


B-20
Examples of Static NonStop SQL Programs Date-Time Program

Page 7 [1] $VOL1.S04.TALDT 1991-10-15 13:41:07


322. 000104 1 1 BEGIN
323. 000104 1 2 SBUF ':=' "PROJECT NAME: "->@BUF^END;
324. 000115 1 2 BUF^END ':=' NEW^PROJECTS^REC.PROJECT^NAME FOR 10
->@BUF^END;
325. 000123 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF);
326. 000135 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,0);
327. 000145 1 2
328. 000145 1 2 SBUF ':=' "START DATE: "->@BUF^END;
329. 000156 1 2 BUF^END ':=' NEW^PROJECTS^REC.START^DATE FOR 16
->@BUF^END;
330. 000165 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF);
331. 000177 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,0);
332. 000224 1 2
333. 000224 1 2 SBUF ':=' "END DATE: "->@BUF^END;
334. 000235 1 2 BUF^END ':=' NEW^PROJECTS^REC.END^DATE FOR 16
->@BUF^END;
335. 000244 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF);
336. 000256 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,0);
337. 000266 1 2
338. 000266 1 2 SBUF ':=' "WAIT TIME: "->@BUF^END;
339. 000301 1 2 BUF^END ':=' NEW^PROJECTS^REC.WAIT^TIME FOR 3
->@BUF^END;
340. 000310 1 2 BUF^END ':=' " ";
341. 000320 1 2 BUF^END ':=' "DAYS";
342. 000330 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF);
343. 000342 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,0);
344. 000352 1 2
345. 000352 1 2 END;
346. 000352 1 1 END; -- fetch^and^display^new
347. 000000 0 0
348. 000000 0 0
349. 000000 0 0 -- Re-enable NOT FOUND checking:
350. 000000 0 0 EXEC SQL
351. 000000 0 0 WHENEVER NOT FOUND CALL :NOT^FOUND;
352. 000000 0 0
353. 000000 0 0 PROC TERMINATE^PROG;
354. 000000 1 0 BEGIN;
355. 000001 1 1 SBUF ':=' "TERMINATING PROJECTS UPDATE PROGRAM "
->@BUF^END;
356. 000012 1 1 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF);
357. 000024 1 1 CALL STOP;
358. 000031 1 1 END;
359. 000000 0 0
360. 000000 0 0
361. 000000 0 0 PROC DRIVER MAIN;
362. 000000 1 0
363. 000000 1 0 BEGIN
364. 000000 1 1 --Read the system startup message:
365. 000000 1 1 CALL INITIALIZER;
366. 000006 1 1
367. 000006 1 1 -- Open the terminal for I/O:
368. 000006 1 1 CALL MYTERM(HOME^TERM);
369. 000011 1 1 CALL OPEN(HOME^TERM, HOME^TERM^NUM);
370. 000021 1 1
371. 000021 1 1 SBUF ':=' "START PROJECTS UPDATE PROGRAM "->@BUF^END;
372. 000032 1 1 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF);
373. 000044 1 1
374. 000044 1 1 -- Blank out fields in USER^PROJECTS^REC:
375. 000044 1 1 USER^PROJECTS^REC.PROJECT^NAME ':='
376. 000044 1 1 [ $OCCURS(USER^PROJECTS^REC.PROJECT^NAME) * [" "] ];
377. 000055 1 1 USER^PROJECTS^REC.START^DATE ':='
378. 000055 1 1 [ $OCCURS(USER^PROJECTS^REC.START^DATE) * [" "] ];

HP NonStop SQL Programming Manual for TAL—527887-001


B-21
Examples of Static NonStop SQL Programs Date-Time Program

Page 8 [1] $VOL1.S04.TALDT 1991-10-15 13:41:07


379. 000067 1 1 USER^PROJECTS^REC.END^DATE ':='
380. 000067 1 1 [ $OCCURS(USER^PROJECTS^REC.END^DATE) * [" "] ];
381. 000101 1 1 USER^PROJECTS^REC.WAIT^TIME ':='
382. 000101 1 1 [ $OCCURS(USER^PROJECTS^REC.WAIT^TIME) * [" "] ];
383. 000113 1 1
384. 000113 1 1 SEL^INDEX ':=' " ";
385. 000124 1 1
386. 000124 1 1 WHILE SEL^INDEX <> "4" DO
387. 000127 1 1 BEGIN
388. 000127 1 2 SBUF ':=' "PLEASE ENTER: "->@BUF^END;
389. 000140 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF);
390. 000152 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,0);
391. 000162 1 2
392. 000162 1 2 SBUF ':=' "1 -- to insert new project data: "
->@BUF^END;
393. 000173 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF);
394. 000205 1 2
395. 000205 1 2 SBUF ':=' "2 -- to add wait time to a project: "
->@BUF^END;
396. 000216 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF);
397. 000230 1 2
398. 000230 1 2 SBUF ':=' "3 -- to report original and new project
dates: "->@BUF^END;
399. 000241 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF);
400. 000253 1 2
401. 000253 1 2 SBUF ':=' "4 -- to exit the program "->@BUF^END;
402. 000264 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF);
403. 000276 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,0);
404. 000306 1 2
405. 000306 1 2 SBUF ':=' "Please enter selection: "->@BUF^END;
406. 000317 1 2 CALL WRITEREAD(HOME^TERM^NUM,IBUF,@BUF^END '-'
@SBUF,10,NUM^READ);
407. 000334 1 2 SEL^INDEX ':=' SBUF FOR NUM^READ;
408. 000341 1 2
409. 000341 1 2 CASE SEL^INDEX OF
410. 000343 1 2 BEGIN
411. 000343 1 3 "1" -> CALL INSERT^PROJECT;
412. 000344 1 3 "2" -> CALL ADD^WAIT^TIME;
413. 000346 1 3 "3" -> CALL PRINT^REPORT;
414. 000350 1 3 "4" -> CALL TERMINATE^PROG;
415. 000352 1 3 OTHERWISE ->
416. 000353 1 3 SBUF ':=' "Incorrect entry "->@BUF^END;
417. 000364 1 3 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '
-' @SBUF);
418. 000376 1 3 END; -- case statement
419. 000415 1 2
420. 000415 1 2 END; -- while sel^index <> 4
421. 000416 1 1
422. 000416 1 1 END; -- end of main

HP NonStop SQL Programming Manual for TAL—527887-001


B-22
Examples of Static NonStop SQL Programs Date-Time Program

Page 9 [1] $VOL1.S04.TALDT 1991-10-15 13:41:07


BINDER AND COMPILER STATISTICS

BINDER - OBJECT FILE BINDER - T9621C30 - (01NOV91) SYSTEM \PRUNE


Copyright Tandem Computers Incorporated 1982-1989, 1991

Object file $VOL1.S04.TALS2O


TIMESTAMP 1991-10-15 13:41:07

3 Code pages
12 Primary data words
396 Secondary data words
64 Data pages
0 Resident code pages
1 Extended data page
408 Top of stack location in words
1 Code segment
0 Binder Warnings
0 Binder Errors

TAL - Transaction Application Language - T9250C30 - (01NOV91)


Number of compiler errors = 0
Number of unsuppressed compiler warnings = 0
Number of warnings suppressed by NOWARN = 0
Maximum symbol table space used was = 24512 bytes
Number of source lines = 3186
Compile cpu time = 00:00:05
Total Elapsed time = 00:00:40

HP NonStop SQL Programming Manual for TAL—527887-001


B-23
Examples of Static NonStop SQL Programs Date-Time Program

HP NonStop SQL Programming Manual for TAL—527887-001


B-24
C
Examples of Dynamic NonStop SQL
Programs
This appendix describes these sample dynamic SQL programs:
• Simple program (TALDYNEZ)
TALDYNEZ processes a SELECT statement that is partially coded into the
program; the user supplies the WHERE clause. The SQLDA structures and data
buffers are allocated at compile time using the INCLUDE SQLDA directive.
• Detailed program (TALDYN)
TALDYN allows the user to enter any SQL statement from a terminal. The SQLDA
structures and data buffers are allocated at run time.
These programs use the NonStop SQL sample database, which is described in
Appendix A, Sample NonStop SQL Database.

Dynamic SQL Program


The TALDYNEZ program uses a SELECT statement to find the average salary for a
selection of rows in the employee table. The program prompts the user for the
selection criteria and then constructs the statement by adding a WHERE clause.
TALDYNEZ has no input parameters and only one output variable. The expression
AVG(SALARY) is the only element described in the output SQLDA structure, and the
average salary is the only value output. Because no parameter names or column
headings are required, names buffers are not necessary. TALDYNEZ also assumes
that the query will never return a null value.
TALDYNEZ allocates memory during compilation using the INCLUDE SQLDA directive
and specifying one output variable. You can specify one output variable because you
know you are only reporting data for one column. You must still assign the memory
location of the value to be output (in this case, the average) to the VAR^PTR field.
TALDYNEZ uses the TACL DEFINE name =EMPLOYEE for the EMPLOYEE table in
the sample database. The commands to add this DEFINE name are:
SET DEFMODE ON
SET DEFINE CLASS MAP
ADD DEFINE =EMPLOYEE, FILE PERSNL.EMPLOYEE
Figure C-1 shows the output for the TALDYNEZ program with the data entered by the
user shown in bold type. The object file name is TALDEZO.

HP NonStop SQL Programming Manual for TAL—527887-001


C-1
Examples of Dynamic NonStop SQL Programs Dynamic SQL Program

Figure C-1. Output for the Dynamic SQL Program

10> RUN TALDEZO


PLEASE ENTER:
1 -- To find average salary based on employee #
2 -- To find average salary based on job code
3 -- To find average salary based on department #
Please enter selection: 1
Please specify the comparison criteria:
(for example: > 500, = 1000, <= 250)
Enter the comparison criteria now: > 500
THE AVERAGE SALARY IS: 52250
VSTC01.vsd
11>

HP NonStop SQL Programming Manual for TAL—527887-001


C-2
Examples of Dynamic NonStop SQL Programs Dynamic SQL Program

The TAL compiler listing for TALDYNEZ is shown on the following pages.

Page 1 [1] $VOL1.S04.TALDYNEZ 1991-10-15 13:41:54


TAL - T9250C30 - (01NOV91)
Copyright Tandem Computers Incorporated 1976, 1978, 1981-83, 1985, 1987-91

1. 000000 0 0 ?SQL NOWHENEVERLIST


2. 000000 0 0 ?SYMBOLS, INSPECT, SAVEABEND, NOMAP, NOCODE, NOGMAP,
NOLMAP, DATAPAGES 64
3. 000000 0 0 ?SEARCH \SYS1.$SYSTEM.SYSTEM.TALLIB
Search file: \SYS1.$SYSTEM.SYSTEM.TALLIB 1991-08-30 11:14:19
4. 000000 0 0
5. 000000 0 0 !--------------------------------------------------------
6. 000000 0 0 ! This program finds the average salary for employees
7. 000000 0 0 ! according to criteria established by the user. The
8. 000000 0 0 ! program contains a SELECT statement for the EMPLOYEE
9. 000000 0 0 ! table; the user enters the selection criteria, which
10. 000000 0 0 ! the program concatenates to the SELECT statement as a
11. 000000 0 0 ! WHERE clause.
12. 000000 0 0 !--------------------------------------------------------
13. 000000 0 0
14. 000000 0 0 LITERAL MAXCMD = 1000;
15. 000000 0 0 LITERAL NULL^ADDR = %HFFFC0000%D;
16. 000000 0 0
17. 000000 0 0 -- Variables for terminal I/O:
18. 000000 0 0 INT .HOME^TERM[0:11],
19. 000014 0 0 HOME^TERM^NUM,
20. 000014 0 0 NUM^READ,
21. 000014 0 0 .IBUF[0:99];
22. 000160 0 0 STRING .SBUF := @IBUF '<<' 1;
23. 000160 0 0
24. 000160 0 0 -- Pointer to end of the I/O buffer:
25. 000160 0 0 STRING .BUF^END;
26. 000160 0 0
27. 000160 0 0 --Copy in declarations for data type literals:
28. 000160 0 0 ?NOLIST
31. 000160 0 0
32. 000160 0 0 -- Other necessary declarations:
33. 000160 0 0
34. 000160 0 0 INT SQLCODE; -- for error checking
35. 000160 0 0 INT(32) AVERAGE; -- for output value
36. 000160 0 0 STRING .CMD[0:MAXCMD - 1]; -- array for SQL statement user
enters
37. 001144 0 0 STRING .CMD^END; -- ptr to end of command string
38. 001144 0 0
39. 001144 0 0 EXEC SQL INCLUDE SQLCA;
39. 001144 0 0 EXEC SQL INCLUDE SQLCA;
Source file: [3] $SYSTEM.#3189 1991-10-15 13:42:05
1. 001144 0 0 struct .SQLCA;
2. 001144 0 0 BEGIN
3. 001144 0 1 STRING filler^[0:429];
4. 001144 0 1 END; -- SQLCA
Source file: [1] $VOL1.S04.TALDYNEZ 1991-10-15 13:36:01
40. 001473 0 0 EXEC SQL INCLUDE SQLSA;
40. 001473 0 0 EXEC SQL INCLUDE SQLSA;
Source file: [4] $SYSTEM.#3190 1991-10-15 13:42:07
1. 001473 0 0 STRUCT .sqlsa;
2. 001473 0 0 BEGIN
3. 001473 0 1 STRING eye^catcher[0:1];
4. 001473 0 1 INT version;
5. 001473 0 1 STRUCT dml;

HP NonStop SQL Programming Manual for TAL—527887-001


C-3
Examples of Dynamic NonStop SQL Programs Dynamic SQL Program

Page 2 [4] $SYSTEM.#3190 1991-10-15


13:41:54
6. 001473 0 1 BEGIN
7. 001473 0 2 INT num^tables;
8. 001473 0 2 STRUCT stats[0:15];
9. 001473 0 2 BEGIN
10. 001473 0 3 STRING table^name[0:23];
11. 001473 0 3 INT(32) records^accessed;
12. 001473 0 3 INT(32) records^used;
13. 001473 0 3 INT(32) disc^reads;
14. 001473 0 3 INT(32) messages;
15. 001473 0 3 INT(32) message^bytes;
16. 001473 0 3 INT waits;
17. 001473 0 3 INT escalations;
18. 001473 0 3 STRING sqlsa^reserved[0:3];
19. 001473 0 3 END; -- stats
20. 001473 0 2 END; -- dml
21. 001473 0 1 STRUCT prepare = dml;
22. 001473 0 1 BEGIN
23. 001473 0 2 INT input^num;
24. 001473 0 2 INT input^names^len;
25. 001473 0 2 INT output^num;
26. 001473 0 2 INT output^names^len;
27. 001473 0 2 INT name^map^len;
28. 001473 0 2 INT sql^statement^type;
29. 001473 0 2 END; -- prepare
30. 001473 0 1 END; -- sqlsa
Source file: [1] $VOL1.S04.TALDYNEZ 1991-10-15 13:36:01
41. 002336 0 0
42. 002336 0 0 -- The program will have only one output column, SALARY. Since
43. 002336 0 0 -- we will be generating its average, we do not need to print
44. 002336 0 0 -- the column name; we can therefore omit declaring a names
45. 002336 0 0 -- buffer. We do not plan to allocate memory dynamically, so
we
46. 002336 0 0 -- use the INCLUDE SQLDA statement, specifying one output
47. 002336 0 0 -- variable for our output SQLDA.
48. 002336 0 0
49. 002336 0 0 EXEC SQL BEGIN DECLARE SECTION;
50. 002336 0 0
51. 002336 0 0 EXEC SQL INCLUDE SQLDA(osqlda^type ,1);
51. 002336 0 0 EXEC SQL INCLUDE SQLDA(osqlda^type ,1);
Source file: [5] $SYSTEM.#3191 1991-10-15 13:42:08
1. 002336 0 0 LITERAL SQLDA^EYE^CATCHER = "D1";
2. 002336 0 0 STRUCT osqlda^type (*) ;
3. 002336 0 0 BEGIN
4. 002336 0 1 STRING eye^catcher[0:1];
5. 002336 0 1 INT num^entries;
6. 002336 0 1 struct sqlvar[0:0];
7. 002336 0 1 BEGIN
8. 002336 0 2 INT data^type;
9. 002336 0 2 INT data^len;
10. 002336 0 2 ! fields for NUMBERS:
11. 002336 0 2 ! scale = data^len.<0:7>
12. 002336 0 2 ! length = data^len.<8:15>
13. 002336 0 2 ! fields for DATETIME or INTERVAL:
14. 002336 0 2 ! qualifier = data^len.<0:7>
15. 002336 0 2 ! length = data^len.<8:15>
16. 002336 0 2 INT precision;
17. 002336 0 2 ! fields for DATETIME or INTERVAL:
18. 002336 0 2 ! leading field precision = precision.<0:7>

HP NonStop SQL Programming Manual for TAL—527887-001


C-4
Examples of Dynamic NonStop SQL Programs Dynamic SQL Program

Page 3 [5] $SYSTEM.#3191 1991-10-15


13:41:54
19. 002336 0 2 ! fraction precision = precision.<8:15>
20. 002336 0 2 INT null^info;
21. 002336 0 2 INT(32) var^ptr;
22. 002336 0 2 INT(32) ind^ptr;
23. 002336 0 2 FIXED reserved;
24. 002336 0 2 END;
25. 002336 0 1 END;
Source file: [1] $VOL1.S04.TALDYNEZ 1991-10-15 13:36:01
52. 002336 0 0 STRUCT .OSQLDA(osqlda^type);
53. 002354 0 0
54. 002354 0 0 EXEC SQL END DECLARE SECTION;
55. 002354 0 0
56. 002354 0 0 -- Copy declarations from EXTDECS file for:
57. 002354 0 0 --
MYTERM,INITIALIZER,SQLCADISPLAY,OPEN,WRITE,WRITEREAD,STOP,DNUMOUT
58. 002354 0 0
59. 002354 0 0 ?NOLIST, SOURCE $SYSTEM.SYSTEM.EXTDECS (
63. 000000 0 0
64. 000000 0 0 -- Declare WHENEVER clause for error checking:
65. 000000 0 0 PROC ERROR^HANDLER; FORWARD;
66. 000000 0 0 EXEC SQL WHENEVER SQLERROR CALL :ERROR^HANDLER;
67. 000000 0 0
68. 000000 0 0
69. 000000 0 0 !--------------------------------------------------------
70. 000000 0 0 ! PROC PROCESS^AND^EXECUTE;
71. 000000 0 0 !
72. 000000 0 0 ! Prepares the command; issues DESCRIBE to get description of
73. 000000 0 0 ! the output variable; sets VAR^PTR to point to the memory for
74. 000000 0 0 ! the output variable (average salary); sets up and uses a
75. 000000 0 0 ! cursor to perform the SELECT and output the average.
76. 000000 0 0 !--------------------------------------------------------
77. 000000 0 0
78. 000000 0 0 PROC PROCESS^AND^EXECUTE (CMD);
79. 000000 1 0
80. 000000 1 0 STRING .CMD;
81. 000000 1 0
82. 000000 1 0 BEGIN
83. 000000 1 1 EXEC SQL BEGIN DECLARE SECTION;
84. 000000 1 1
85. 000000 1 1 -- Create an alternate version of CMD that is an array.
86. 000000 1 1 -- We must do this because you cannot put bounds on a
parameter.
87. 000000 1 1 -- In order to pass CMD as a string, we must create this
88. 000000 1 1 -- equivalence. To use CMD as a host variable, we then
reference
89. 000000 1 1 -- CMDX.VAL
90. 000000 1 1
91. 000000 1 1 STRUCT S(*);
92. 000000 1 1 BEGIN
93. 000000 1 2 STRING VAL [0:MAXCMD - 1];
94. 000000 1 2 END;
95. 000000 1 1
96. 000000 1 1 STRING .CMDX(S) = CMD;
97. 000000 1 1
98. 000000 1 1 EXEC SQL END DECLARE SECTION;
99. 000000 1 1
100. 000000 1 1 EXEC SQL PREPARE DYNCMD FROM :CMDX.VAL;
101. 000050 1 1
102. 000050 1 1 OSQLDA.EYE^CATCHER ':=' SQLDA^EYE^CATCHER;
103. 000061 1 1

HP NonStop SQL Programming Manual for TAL—527887-001


C-5
Examples of Dynamic NonStop SQL Programs Dynamic SQL Program

Page 4 [1] $VOL1.S04.TALDYNEZ 1991-10-15 13:41:54


104. 000061 1 1 OSQLDA.NUM^ENTRIES := 1;
105. 000064 1 1
106. 000064 1 1 -- Initialize IND^PTR field to null. You must initialize
107. 000064 1 1 -- IND^PTR even if the program will not handle null values.
108. 000064 1 1 OSQLDA.SQLVAR[0].IND^PTR := NULL^ADDR;
109. 000070 1 1
110. 000070 1 1 EXEC SQL DESCRIBE DYNCMD INTO :OSQLDA;
111. 000140 1 1
112. 000140 1 1 -- SQL tells you what it has to work with; you then
communicate
113. 000140 1 1 -- what your variable is like to SQL. You might want to look
114. 000140 1 1 -- at the DATA^TYPE field and adjust accordingly. Here, we
are
115. 000140 1 1 -- using an INT32 and ignoring scale.
116. 000140 1 1
117. 000140 1 1 -- set DATA^TYPE to INT32:
118. 000140 1 1 OSQLDA.SQLVAR[0].DATA^TYPE := _SQLDT_32BIT_U;
119. 000143 1 1
120. 000143 1 1
121. 000143 1 1 -- set length to 4 bytes; leave scale as 0 in upper byte of
DATA^LEN:
122. 000143 1 1 OSQLDA.SQLVAR[0].DATA^LEN := 4;
123. 000146 1 1
124. 000146 1 1
125. 000146 1 1 -- set VAR^PTR to point to memory where the average
126. 000146 1 1 -- will be output:
127. 000146 1 1 OSQLDA.SQLVAR[0].VAR^PTR := $XADR(AVERAGE);
128. 000153 1 1
129. 000153 1 1 EXEC SQL BEGIN WORK;
130. 000236 1 1
131. 000236 1 1 EXEC SQL DECLARE C1 CURSOR FOR DYNCMD;
132. 000236 1 1 EXEC SQL OPEN C1;
133. 000300 1 1 EXEC SQL FETCH C1 USING DESCRIPTOR :OSQLDA;
134. 000350 1 1
135. 000350 1 1
136. 000350 1 1 IF SQLCODE >= 0 THEN
137. 000353 1 1 BEGIN
138. 000353 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,0);
139. 000363 1 2 SBUF ':=' "THE AVERAGE SALARY IS: "->@BUF^END;
140. 000374 1 2 -- Convert the average for display and place it into the
buffer:
141. 000374 1 2 @BUF^END := @BUF^END '+' DNUMOUT (BUF^END, AVERAGE, 10);
142. 000413 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF);
143. 000425 1 2 CALL WRITE(HOME^TERM^NUM,IBUF,0);
144. 000435 1 2 END;
145. 000435 1 1
146. 000435 1 1 EXEC SQL CLOSE C1;
147. 000512 1 1
148. 000512 1 1 EXEC SQL COMMIT WORK;
149. 000554 1 1
150. 000554 1 1 END; -- process^and^execute
151. 000000 0 0
152. 000000 0 0
153. 000000 0 0 !--------------------------------------------------------
154. 000000 0 0 ! PROC GET^CMD;
155. 000000 0 0 !
156. 000000 0 0 ! Assigns a SELECT statement to the statement buffer.
157. 000000 0 0 ! Gets the WHERE clause from the user and concatenates it to
158. 000000 0 0 ! the SELECT statement.
159. 000000 0 0 !--------------------------------------------------------
160. 000000 0 0

HP NonStop SQL Programming Manual for TAL—527887-001


C-6
Examples of Dynamic NonStop SQL Programs Dynamic SQL Program

Page 5 [1] $VOL1.S04.TALDYNEZ 1991-10-15 13:41:54


161. 000000 0 0 PROC GET^CMD(CMD);
162. 000000 1 0
163. 000000 1 0 STRING .CMD;
164. 000000 1 0
165. 000000 1 0 BEGIN
166. 000000 1 1 STRING COLUMN [0:9]; -- column to be used in
167. 000000 1 1 -- WHERE clause
168. 000000 1 1 STRING SEL^INDEX; -- selects which column to
169. 000000 1 1 -- put in WHERE clause
170. 000000 1 1 STRING PREDICATE [0:9]; -- comparison predicate to
171. 000000 1 1 -- use in WHERE clause
172. 000000 1 1 INT COL^SIZE; -- size of column name
173. 000000 1 1 INT PRED^SIZE; -- size of predicate string
174. 000000 1 1
175. 000000 1 1 -- Pre-load command with blanks:
176. 000000 1 1 CMD ':=' " " & CMD FOR MAXCMD - 1;
177. 000015 1 1
178. 000015 1 1 CMD ':=' "SELECT AVG(SALARY) FROM =EMPLOYEE WHERE " ->
@CMD^END;
179. 000026 1 1
180. 000026 1 1 -- Create a simple menu:
181. 000026 1 1 SBUF ':=' "PLEASE ENTER: "->@BUF^END;
182. 000037 1 1 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF);
183. 000051 1 1 CALL WRITE(HOME^TERM^NUM,IBUF,0);
184. 000061 1 1
185. 000061 1 1 SBUF ':=' "1 -- To find average salary based on
employee #"->@BUF^END;
186. 000072 1 1 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF);
187. 000104 1 1 SBUF ':=' "2 -- To find average salary based on job
code"->@BUF^END;
188. 000115 1 1 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF);
189. 000127 1 1 SBUF ':=' "3 -- To find average salary based on
department #: "->@BUF^END;
190. 000140 1 1 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF);
191. 000152 1 1 CALL WRITE(HOME^TERM^NUM,IBUF,0);
192. 000162 1 1
193. 000162 1 1 SBUF ':=' "Please enter selection: "->@BUF^END;
194. 000173 1 1 CALL WRITEREAD (HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF,
10, NUM^READ);
195. 000206 1 1
196. 000206 1 1 SEL^INDEX ':=' SBUF FOR NUM^READ;
197. 000213 1 1
198. 000213 1 1 CALL WRITE(HOME^TERM^NUM,IBUF,0);
199. 000223 1 1
200. 000223 1 1 CASE SEL^INDEX OF
201. 000225 1 1 BEGIN
202. 000225 1 2 "1" -> COLUMN ':=' "EMPNUM ";
203. 000236 1 2 COL^SIZE := 7;
204. 000240 1 2 "2" -> COLUMN ':=' "JOBCODE ";
205. 000252 1 2 COL^SIZE := 8;
206. 000254 1 2 "3" -> COLUMN ':=' "DEPTNUM ";
207. 000266 1 2 COL^SIZE := 8;
208. 000270 1 2 END;
209. 000313 1 1
210. 000313 1 1 CALL WRITE(HOME^TERM^NUM,IBUF,0);
211. 000323 1 1
212. 000323 1 1 SBUF ':=' "Please specify the comparison criteria:"
->@BUF^END;
213. 000334 1 1 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF);
214. 000346 1 1 SBUF ':=' " (for example: > 500, = 1000, <= 250)" ->
@BUF^END;
215. 000357 1 1 CALL WRITE(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF);
216. 000371 1 1 CALL WRITE(HOME^TERM^NUM,IBUF,0);
217. 000401 1 1

HP NonStop SQL Programming Manual for TAL—527887-001


C-7
Examples of Dynamic NonStop SQL Programs Dynamic SQL Program

Page 6 [1] $VOL1.S04.TALDYNEZ 1991-10-15 13:41:54


218. 000401 1 1 SBUF ':=' "Enter the comparison criteria now: "->@BUF^END;
219. 000412 1 1 CALL WRITEREAD(HOME^TERM^NUM,IBUF,@BUF^END '-' @SBUF,20,
PRED^SIZE);
220. 000425 1 1
221. 000425 1 1 PREDICATE ':=' SBUF FOR PRED^SIZE;
222. 000432 1 1
223. 000432 1 1 -- Construct the SQL statement:
224. 000432 1 1 CMD^END ':=' COLUMN FOR COL^SIZE -> @CMD^END;
225. 000440 1 1 CMD^END ':=' PREDICATE FOR PRED^SIZE -> @CMD^END;
226. 000446 1 1
227. 000446 1 1 END; --get^cmd
228. 000000 0 0
229. 000000 0 0
230. 000000 0 0 !--------------------------------------------------------
231. 000000 0 0 !
232. 000000 0 0 ! ERROR HANDLER
233. 000000 0 0 !
234. 000000 0 0 !--------------------------------------------------------
235. 000000 0 0
236. 000000 0 0 PROC ERROR^HANDLER;
237. 000000 1 0
238. 000000 1 0 BEGIN
239. 000000 1 1 CALL SQLCADISPLAY( SQLCA);
240. 000013 1 1 END;
241. 000000 0 0
242. 000000 0 0
243. 000000 0 0 !--------------------------------------------------------
244. 000000 0 0 !
245. 000000 0 0 ! MAIN PROCEDURE
246. 000000 0 0 !
247. 000000 0 0 !--------------------------------------------------------
248. 000000 0 0
249. 000000 0 0 PROC DRIVER MAIN;
250. 000000 1 0
251. 000000 1 0 BEGIN
252. 000000 1 1 CALL INITIALIZER;
253. 000006 1 1 CALL MYTERM(HOME^TERM);
254. 000011 1 1 CALL OPEN(HOME^TERM, HOME^TERM^NUM);
255. 000021 1 1
256. 000021 1 1 -- Get SQL statement from the user:
257. 000021 1 1 CALL GET^CMD(CMD);
258. 000024 1 1
259. 000024 1 1 -- Compile the statement, access the SQL database, and
260. 000024 1 1 -- report the result:
261. 000024 1 1 CALL PROCESS^AND^EXECUTE(CMD);
262. 000027 1 1
263. 000027 1 1 END;

HP NonStop SQL Programming Manual for TAL—527887-001


C-8
Examples of Dynamic NonStop SQL Programs Detailed Dynamic SQL Program

Page 7 [1] $VOL1.S04.TALDYNEZ 1991-10-15 13:41:54


BINDER AND COMPILER STATISTICS

BINDER - OBJECT FILE BINDER - T9621C30 - (01NOV91) SYSTEM \SYS1


Copyright Tandem Computers Incorporated 1982-1989, 1991

Object file $VOL1.S04.TALD1O


TIMESTAMP 1991-10-15 13:41:54

2 Code pages
14 Primary data words
1260 Secondary data words
64 Data pages
0 Resident code pages
1 Extended data page
1274 Top of stack location in words
1 Code segment
0 Binder Warnings
0 Binder Errors

TAL - Transaction Application Language - T9250C30 - (01NOV91)


Number of compiler errors = 0
Number of unsuppressed compiler warnings = 0
Number of warnings suppressed by NOWARN = 0
Maximum symbol table space used was = 28620 bytes
Number of source lines = 3165
Compile cpu time = 00:00:03
Total Elapsed time = 00:00:29

Detailed Dynamic SQL Program


The TALDYN program allows a user to enter any SQL statement at run time. TALDYN
prepares and executes the statement in a TMF transaction. The program is
independent of a specific database because it does not use database definitions. Only
the dynamic SQL statement refers to a particular database.
TALDYN performs these functions:
1. Declares these SQL structures:
• An SQLSA to determine the number of input parameters or output variables.
• One SQLDA to describe input parameters and another SQLDA to describe
output variables (Because the program allocates memory at run time, it
declares the SQLDA as a template and then allocates the actual structures
dynamically when the query is run.).
2. Defines these items:
• A buffer to store output variables, with storage for column values of different
data types.
• A buffer to store input parameters, with storage for parameter values of
different data types.

HP NonStop SQL Programming Manual for TAL—527887-001


C-9
Examples of Dynamic NonStop SQL Programs Detailed Dynamic SQL Program

3. Prepares the SQL statement and assigns it a statement name (statement and
cursor host variables are not used).
4. Determines the data types of the:
• Input parameters and moves them to the host variables of the corresponding
data types
• Output variables and moves them to the host variables of the corresponding
data types
5. Sets up the SQLDA to point to the storage for the variables referenced by the
query. The storage is allocated at run time.
6. If there are parameters, uses the input SQLDA either to perform a cursor FETCH
for a SELECT statement or to execute a non-SELECT statement.
To run TALDYN, you must enter the TACL ADD DEFINE commands to associate the
ORDERS and ODETAIL tables with the =ORDERS and =ODETAIL DEFINE names:
SET DEFINE CLASS MAP
ADD DEFINE =ORDERS, FILE SALES.ORDERS
ADD DEFINE =ODETAIL, FILE SALES.ODETAIL
Figure C-2 shows the TALDYN output. The prompt is two greater than characters (>>).
The data entered by the user is shown in bold type. A semicolon is required to
terminate the input from the user. The query shown selects order numbers and
customer numbers from the ORDERS table, where the order includes part number
6400. The object file name is TALDYNO.

HP NonStop SQL Programming Manual for TAL—527887-001


C-10
Examples of Dynamic NonStop SQL Programs Detailed Dynamic SQL Program

Figure C-2. Output for the Detailed Dynamic SQL Program

10> RUN TALDYNO


This is DYNAMIC SQL test.
Enter SQL statement or SAME to reuse last statement or END:
>>select ordernum, custnum
from =orders where ordernum in
(select ordernum from =odetail where partnum = 6400);
ORDERS.ORDERNUM 200320
ORDERS.CUSTNUM 21
ORDERS.ORDERNUM 300350
ORDERS.CUSTNUM 543
ORDERS.ORDERNUM 800660
ORDERS.CUSTNUM 3210
ORDERS.ORDERNUM 400410
ORDERS.CUSTNUM 7654
- - - 4 row(s) selected.
Enter SQL statement or SAME to reuse last statement or END:
>>end;
End of current session
11> VSTC02.vsd

HP NonStop SQL Programming Manual for TAL—527887-001


C-11
Examples of Dynamic NonStop SQL Programs Detailed Dynamic SQL Program

The TAL compiler listing for TALDYN is shown on the following pages.

Page 1 [1] $VOL1.S04.TALDYN 1991-10-15 13:42:28

TAL - T9250C30 - (01NOV91)


Copyright Tandem Computers Incorporated 1976, 1978, 1981-83, 1985, 1987-91

1. 000000 0 0 ?SQL NOWHENEVERLIST


2. 000000 0 0 ?SYMBOLS, INSPECT, SAVEABEND, NOMAP, NOCODE, NOGMAP, NOLMAP,
DATAPAGES 64
3. 000000 0 0 ?SEARCH \SYS1.$SYSTEM.SYSTEM.TALLIB
Search file: \SYS1.$SYSTEM.SYSTEM.TALLIB 1991-08-30 11:14:19
4. 000000 0 0
5. 000000 0 0 LITERAL NULL^ADDR = %HFFFC0000%D; ! Guaranteed invalid 32-bit
address.
6. 000000 0 0 LITERAL MAX^COLUMN^NAME^SIZE = 40; ! Maximum size of a SQL
column name.
7. 000000 0 0 LITERAL MAX^SQL^CHAR^LENGTH = 255; ! Maximum length of SQL
char string.
8. 000000 0 0 LITERAL MAX^SQL^STMT^LENGTH = 512; ! Maximum size of SQL
statement we
9. 000000 0 0 ! will accept in this
program.
10. 000000 0 0 !--------------------------------------------------------
11. 000000 0 0 ! Declare SQLCA and SQLSA
12. 000000 0 0 !--------------------------------------------------------
13. 000000 0 0
14. 000000 0 0 EXEC SQL INCLUDE SQLCA;
14. 000000 0 0 EXEC SQL INCLUDE SQLCA;
Source file: [2] $SYSTEM.#3192 1991-10-15 13:42:37
1. 000000 0 0 struct .SQLCA;
2. 000000 0 0 BEGIN
3. 000000 0 1 STRING filler^[0:429];
4. 000000 0 1 END; -- SQLCA
Source file: [1] $VOL1.S04.TALDYN 1991-10-15 13:33:55
15. 000327 0 0
16. 000327 0 0 EXEC SQL INCLUDE SQLSA;
16. 000327 0 0 EXEC SQL INCLUDE SQLSA;
Source file: [3] $SYSTEM.#3193 1991-10-15 13:42:39
1. 000327 0 0 STRUCT .sqlsa;
2. 000327 0 0 BEGIN
3. 000327 0 1 STRING eye^catcher[0:1];
4. 000327 0 1 INT version;
5. 000327 0 1 STRUCT dml;
6. 000327 0 1 BEGIN
7. 000327 0 2 INT num^tables;
8. 000327 0 2 STRUCT stats[0:15];
9. 000327 0 2 BEGIN
10. 000327 0 3 STRING table^name[0:23];
11. 000327 0 3 INT(32) records^accessed;
12. 000327 0 3 INT(32) records^used;
13. 000327 0 3 INT(32) disc^reads;
14. 000327 0 3 INT(32) messages;
15. 000327 0 3 INT(32) message^bytes;
16. 000327 0 3 INT waits;
17. 000327 0 3 INT escalations;
18. 000327 0 3 STRING sqlsa^reserved[0:3];
19. 000327 0 3 END; -- stats
20. 000327 0 2 END; -- dml
21. 000327 0 1 STRUCT prepare = dml;
22. 000327 0 1 BEGIN
23. 000327 0 2 INT input^num;
24. 000327 0 2 INT input^names^len;
25. 000327 0 2 INT output^num;
26. 000327 0 2 INT output^names^len;
27. 000327 0 2 INT name^map^len;

HP NonStop SQL Programming Manual for TAL—527887-001


C-12
Examples of Dynamic NonStop SQL Programs Detailed Dynamic SQL Program

Page 2 [3] $SYSTEM.#3193 1991-10-15


13:42:28
28. 000327 0 2 INT sql^statement^type;
29. 000327 0 2 END; -- prepare
30. 000327 0 1 END; -- sqlsa
Source file: [1] $VOL1.S04.TALDYN 1991-10-15 13:33:55
17. 001172 0 0
18. 001172 0 0 !------------------------------------------------------------
19. 001172 0 0 ! Declare SQLDA for input parameters and output variables.
20. 001172 0 0 !
21. 001172 0 0 !------------------------------------------------------------
22. 001172 0 0
23. 001172 0 0 EXEC SQL INCLUDE SQLDA (sqlda^type, 1);
23. 001172 0 0 EXEC SQL INCLUDE SQLDA (sqlda^type, 1);
Source file: [4] $SYSTEM.#3194 1991-10-15 13:42:41
1. 001172 0 0 LITERAL SQLDA^EYE^CATCHER = "D1";
2. 001172 0 0 STRUCT sqlda^type (*) ;
3. 001172 0 0 BEGIN
4. 001172 0 1 STRING eye^catcher[0:1];
5. 001172 0 1 INT num^entries;
6. 001172 0 1 struct sqlvar[0:0];
7. 001172 0 1 BEGIN
8. 001172 0 2 INT data^type;
9. 001172 0 2 INT data^len;
10. 001172 0 2 ! fields for NUMBERS:
11. 001172 0 2 ! scale = data^len.<0:7>
12. 001172 0 2 ! length = data^len.<8:15>
13. 001172 0 2 ! fields for DATETIME or INTERVAL:
14. 001172 0 2 ! qualifier = data^len.<0:7>
15. 001172 0 2 ! length = data^len.<8:15>
16. 001172 0 2 INT precision;
17. 001172 0 2 ! fields for DATETIME or INTERVAL:
18. 001172 0 2 ! leading field precision = precision.<0:7>
19. 001172 0 2 ! fraction precision = precision.<8:15>
20. 001172 0 2 INT null^info;
21. 001172 0 2 INT(32) var^ptr;
22. 001172 0 2 INT(32) ind^ptr;
23. 001172 0 2 FIXED reserved;
24. 001172 0 2 END;
25. 001172 0 1 END;
Source file: [1] $VOL1.S04.TALDYN 1991-10-15 13:33:55
24. 001172 0 0
25. 001172 0 0 EXEC SQL BEGIN DECLARE SECTION;
26. 001172 0 0
27. 001172 0 0 INT .EXT sda^i (sqlda^type); ! input SQLDA pointer
28. 001172 0 0 INT .EXT sda^o (sqlda^type); ! output SQLDA pointer
29. 001172 0 0
30. 001172 0 0 STRUCT names^template(*); !template for names buffer
31. 001172 0 0 begin
32. 001172 0 1 string val[0:10000];
33. 001172 0 1 end;
34. 001172 0 0
35. 001172 0 0 INT .EXT cname^i(names^template); ! input names buffer
pointer
36. 001172 0 0 INT .EXT cname^o(names^template); ! output names buffer
pointer
37. 001172 0 0
38. 001172 0 0 EXEC SQL END DECLARE SECTION;
39. 001172 0 0
40. 001172 0 0 INT sqlcode; ! Required by SQL; stores SQL error codes.
41. 001172 0 0

HP NonStop SQL Programming Manual for TAL—527887-001


C-13
Examples of Dynamic NonStop SQL Programs Detailed Dynamic SQL Program

Page 3 [1] $VOL1.S04.TALDYN 1991-10-15 13:42:28


42. 001172 0 0
43. 001172 0 0 !--------------------------------
44. 001172 0 0 ! Global declarations for displaying output.
45. 001172 0 0 !--------------------------------
46. 001172 0 0
47. 001172 0 0 LITERAL buffer^size^in^bytes = 200,
48. 001172 0 0 buffer^limit = (buffer^size^in^bytes / 2) - 1;
49. 001172 0 0
50. 001172 0 0 INT .buf[0:buffer^limit]; ! print buffer (word address)
51. 001336 0 0 STRING .ext sbuf; ! print buffer (byte address)
52. 001336 0 0 STRING .ext next^buf;
53. 001336 0 0 INT term; ! file number of home terminal
54. 001336 0 0
55. 001336 0 0
56. 001336 0 0 ! Small pool of memory for dynamic allocation.
57. 001336 0 0 ! Using DEFINEPOOL/GETPOOL for individual variables in
58. 001336 0 0 ! the SQL statements can be somewhat inefficient, but not
seriously
59. 001336 0 0 ! so. It should be suitable for most users.
60. 001336 0 0 ! See the Guardian Procedure Calls Reference Manual for
limitations.
61. 001336 0 0
62. 001336 0 0
63. 001336 0 0 LITERAL POOL^SIZE^IN^BYTES = 8192d;
64. 001336 0 0 INT .pool^head[0:18];
65. 001361 0 0 INT .pool[0:POOL^SIZE^IN^BYTES/2d - 1d];
66. 011361 0 0
67. 011361 0 0
68. 011361 0 0 EXEC SQL BEGIN DECLARE SECTION;
69. 011361 0 0
70. 011361 0 0 STRUCT .host1; ! holds query to be executed
71. 011361 0 0 BEGIN
72. 011361 0 1 INT len;
73. 011361 0 1 STRING str[0:MAX^SQL^STMT^LENGTH];
74. 011361 0 1 END;
75. 011763 0 0
76. 011763 0 0 STRUCT .host2; ! save copy of query for recovery via SAME
77. 011763 0 0 BEGIN
78. 011763 0 1 INT len;
79. 011763 0 1 STRING str[0:MAX^SQL^STMT^LENGTH];
80. 011763 0 1 END;
81. 012365 0 0
82. 012365 0 0 EXEC SQL END DECLARE SECTION;
83. 012365 0 0
84. 012365 0 0 !------------------------------------------------------------
85. 012365 0 0 ! Define template of TAL types which correspond to SQL types
86. 012365 0 0 !------------------------------------------------------------
87. 012365 0 0
88. 012365 0 0 STRUCT sql^types (*);
89. 012365 0 0 BEGIN
90. 012365 0 1 STRING v^char[0:MAX^SQL^CHAR^LENGTH];
91. 012365 0 1 STRUCT v^varchar = v^char;
92. 012365 0 1 BEGIN
93. 012365 0 2 INT len;
94. 012365 0 2 STRING VAL[0:MAX^SQL^CHAR^LENGTH-2];
95. 012365 0 2 END;
96. 012365 0 1 INT v^smallint = v^char;
97. 012365 0 1 INT(32) v^int = v^char;
98. 012365 0 1 FIXED v^largeint = v^char;

HP NonStop SQL Programming Manual for TAL—527887-001


C-14
Examples of Dynamic NonStop SQL Programs Detailed Dynamic SQL Program

Page 4 [1] $VOL1.S04.TALDYN 1991-10-15 13:42:28


99. 012365 0 1 FIXED(3) v^numeric = v^char;
100. 012365 0 1 REAL v^float = v^char;
101. 012365 0 1 REAL(64) v^double = v^char;
102. 012365 0 1 STRING v^decimal[0:18] = v^char;
103. 012365 0 1 STRING v^datetime[0:25] = v^char;
104. 012365 0 1 END;
105. 012365 0 0
106. 012365 0 0 --Copy in declarations for data type literals:
107. 012365 0 0 ?NOLIST, SOURCE $SYSTEM.SYSTEM.TALDECS(SQLDA)
109. 012365 0 0
111. 012365 0 0 -- Copy declarations from EXTDECS file for:
112. 012365 0 0 -- ABEND, CLOSE, DEBUG, DEFINEPOOL, DNUMIN, DNUMOUT,
FILEINFO,
113. 012365 0 0 -- GETPOOL, INITIALIZER, MYTERM, NUMIN, OPEN, PUTPOOL, READ,
114. 012365 0 0 -- READX, SQLCADISPLAY, STOP, WRITE, WRITEX, WRITEREAD,
WRITEREADX
115. 012365 0 0
116. 012365 0 0 ?NOLIST, SOURCE $SYSTEM.SYSTEM.EXTDECS (
122. 000000 0 0
123. 000000 0 0 ! Declare WHENEVER clause for warnings. The WHENEVER clause
for errors
124. 000000 0 0 ! is declared just before the MAIN procedure; the reason is
explained
125. 000000 0 0 ! with that declaration.
126. 000000 0 0 PROC sql^warning^handler; FORWARD;
127. 000000 0 0 EXEC SQL WHENEVER SQLWARNING CALL :sql^warning^handler;
128. 000000 0 0

HP NonStop SQL Programming Manual for TAL—527887-001


C-15
Examples of Dynamic NonStop SQL Programs Detailed Dynamic SQL Program

Page 5 [1] $VOL1.S04.TALDYN 1991-10-15 13:42:28


Output formatting stuff
130. 000000 0 0 !
131. 000000 0 0 ! Here are a few DEFINEs to make it a little easier to format
132. 000000 0 0 ! and print messages.
133. 000000 0 0 !
134. 000000 0 0 ! put a string into the line, starting at beginning of the
line
135. 000000 0 0 DEFINE PUT^STR (s) = @next^buf := @sbuf;
136. 000000 0 0 next^buf ':=' s -> @next^buf #;
137. 000000 0 0
138. 000000 0 0 ! put a string into the line, starting after the beginning
139. 000000 0 0 DEFINE PUT^STR^MID (s) = next^buf ':=' s -> @next^buf #;
140. 000000 0 0
141. 000000 0 0 ! put an integer into the line
142. 000000 0 0 DEFINE PUT^INT (n) = @next^buf := @sbuf;
143. 000000 0 0 @next^buf := @next^buf +
144. 000000 0 0 $DBL(DNUMOUT(next^buf,$DBL(n),10)) #;
145. 000000 0 0
146. 000000 0 0 ! put an integer into the line, starting after the
beginning
147. 000000 0 0 DEFINE PUT^INT^MID (n)= @next^buf := @next^buf +
148. 000000 0 0 $DBL(DNUMOUT(next^buf,$DBL(n),10)) #;
149. 000000 0 0
150. 000000 0 0 ! put an INT(32) into the line
151. 000000 0 0 DEFINE PUT^DBL (n) = @next^buf := @sbuf;
152. 000000 0 0 @next^buf := @next^buf +
153. 000000 0 0 $DBL(DNUMOUT(next^buf,n,10)) #;
154. 000000 0 0
155. 000000 0 0 ! put an INT(32) into the line, starting after the
beginning
156. 000000 0 0 DEFINE PUT^DBL^MID (n) = @next^buf := @next^buf +
157. 000000 0 0 $DBL(DNUMOUT(next^buf,n,10)) #;
158. 000000 0 0
159. 000000 0 0 ! print the line
160. 000000 0 0 DEFINE PRINT^LINE = call WRITE(term,buf,$INT(@next^buf -
@sbuf)) #;
161. 000000 0 0
162. 000000 0 0 ! print a blank line
163. 000000 0 0 DEFINE PRINT^BLANK^LINE = call WRITE(term,buf,0) #;
164. 000000 0 0
165. 000000 0 0

HP NonStop SQL Programming Manual for TAL—527887-001


C-16
Examples of Dynamic NonStop SQL Programs Detailed Dynamic SQL Program

Page 6 [1] $VOL1.S04.TALDYN 1991-10-15 13:42:28


display^result
167. 000000 0 0 PROC display^result (sqlda, cnames);
168. 000000 1 0
169. 000000 1 0 !*********************************************************!
170. 000000 1 0 ! PROC display^result !
171. 000000 1 0 ! displays the current row of a SELECT statement !
172. 000000 1 0 !*********************************************************!
173. 000000 1 0
174. 000000 1 0 STRUCT .ext sqlda(sqlda^type); !IN: Output SQLDA
175. 000000 1 0 STRING .ext cnames; !IN: contains column names of table
176. 000000 1 0
177. 000000 1 0 BEGIN
178. 000000 1 1 INT length;
179. 000000 1 1 INT nameix; ! index into column names string
180. 000000 1 1 INT output^num; ! number of columns to be output
181. 000000 1 1 INT i;
182. 000000 1 1 INT .EXT ind^ptr^;
183. 000000 1 1 INT .EXT param^ (sql^types);
184. 000000 1 1 INT datalen; ! length of column value
185. 000000 1 1
186. 000000 1 1 --
187. 000000 1 1 -- Get number of columns to output in current row.
188. 000000 1 1 --
189. 000000 1 1
190. 000000 1 1 output^num := sqlda.num^entries;
191. 000007 1 1
192. 000007 1 1 nameix := 1;
193. 000011 1 1
194. 000011 1 1 FOR i := 0 TO (output^num - 1) DO
195. 000013 1 1 BEGIN
196. 000013 1 2 --
197. 000013 1 2 -- Get a column name (which are stored sequentially in
array;
198. 000013 1 2 -- each column name is preceded in this array by its
length)
199. 000013 1 2 -- and blank pad to 40 characters.
200. 000013 1 2 --
201. 000013 1 2 @next^buf := @sbuf;
202. 000015 1 2 next^buf ':=' MAX^COLUMN^NAME^SIZE * [" "] & " ";
203. 000041 1 2 IF cnames[nameix] = 0 THEN
204. 000050 1 2 next^buf ':=' ["(EXPR)"] -- Use (EXPR) for the
column name if no
205. 000050 1 2 -- column name appears, as SQLCI does.
206. 000050 1 2 ELSE
207. 000063 1 2 next^buf ':=' cnames[nameix+1] FOR cnames[nameix];
208. 000077 1 2 @next^buf := @next^buf[MAX^COLUMN^NAME^SIZE+1];
209. 000104 1 2
210. 000104 1 2 nameix := cnames[nameix] + 2 + nameix;
211. 000115 1 2
212. 000115 1 2 @param^ := sqlda.sqlvar[i].var^ptr;
213. 000130 1 2 @ind^ptr^ := sqlda.sqlvar[i].ind^ptr;
214. 000143 1 2 datalen := sqlda.sqlvar[i].data^len;
215. 000156 1 2
216. 000156 1 2 IF sqlda.sqlvar[i].null^info = -1 AND ind^ptr^ = -1
THEN
217. 000176 1 2 BEGIN
218. 000176 1 3 PUT^STR^MID ("? (NULL)");
219. 000214 1 3 END ELSE BEGIN
220. 000215 1 3 CASE sqlda.sqlvar[i].data^type OF
221. 000230 1 3 BEGIN
222. 000230 1 4 !-------------------------------------------
223. 000230 1 4 ! data type is character; display first 38
characaters

HP NonStop SQL Programming Manual for TAL—527887-001


C-17
Examples of Dynamic NonStop SQL Programs Detailed Dynamic SQL Program

Page 7 [1] $VOL1.S04.TALDYN 1991-10-15 13:42:28


display^result
224. 000230 1 4 !-------------------------------------------
225. 000230 1 4 _SQLDT_ASCII_F,
226. 000230 1 4 _SQLDT_ASCII_F_UP ->
227. 000230 1 4 PUT^STR^MID (param^.v^char for $MIN(38,datalen));
228. 000243 1 4
229. 000243 1 4 !-------------------------------------------
230. 000243 1 4 ! data type is varchar
231. 000243 1 4 !-------------------------------------------
232. 000243 1 4 _SQLDT_ASCII_V,
233. 000244 1 4 _SQLDT_ASCII_V_UP ->
234. 000244 1 4 PUT^STR^MID (param^.v^varchar.val
235. 000244 1 4 FOR $MIN(38,param^.v^varchar.len));
236. 000263 1 4
237. 000263 1 4 !-------------------------------------------
238. 000263 1 4 ! data type is smallint
239. 000263 1 4 !-------------------------------------------
240. 000263 1 4 _SQLDT_16BIT_S ->
241. 000264 1 4 if param^.v^smallint >= 0 then
242. 000270 1 4 begin
243. 000270 1 5 PUT^INT^MID (param^.v^smallint);
244. 000311 1 5 end else begin
245. 000312 1 5 PUT^STR^MID ("-");
246. 000326 1 5 PUT^INT^MID (-param^.v^smallint);
247. 000350 1 5 end;
248. 000350 1 4
249. 000350 1 4 _SQLDT_16BIT_U ->
250. 000351 1 4 PUT^DBL^MID ($UDBL(param^.v^smallint));
251. 000371 1 4
252. 000371 1 4 !-------------------------------------------
253. 000371 1 4 ! data type is integer
254. 000371 1 4 !-------------------------------------------
255. 000371 1 4 _SQLDT_32BIT_S ->
256. 000372 1 4 if param^.v^int >= 0D then
257. 000377 1 4 begin
258. 000377 1 5 PUT^DBL^MID (param^.v^int);
259. 000422 1 5 end else begin
260. 000424 1 5 PUT^STR^MID ("-");
261. 000440 1 5 PUT^DBL^MID (-param^.v^int);
262. 000461 1 5 end;
263. 000461 1 4
264. 000461 1 4 _SQLDT_32BIT_U ->
265. 000462 1 4 PUT^DBL^MID (param^.v^int);
266. 000502 1 4
267. 000502 1 4 !-------------------------------------------
268. 000502 1 4 ! data type is datetime or interval
269. 000502 1 4 !-------------------------------------------
270. 000502 1 4 _SQLDT_DATETIME .. _SQLDT_INT_D_F ->
271. 000503 1 4 PUT^STR^MID (param^.v^datetime FOR datalen.<8:15>);
272. 000512 1 4
273. 000512 1 4 OTHERWISE ->
274. 000513 1 4 PUT^STR^MID ("This data type is not supported: ");
275. 000527 1 4 PUT^INT^MID (sqlda.sqlvar[i].data^type);
276. 000560 1 4
277. 000560 1 4 END; !end of case
278. 001117 1 3 END; ! end of if
279. 001117 1 2
280. 001117 1 2 PRINT^LINE;

HP NonStop SQL Programming Manual for TAL—527887-001


C-18
Examples of Dynamic NonStop SQL Programs Detailed Dynamic SQL Program

Page 8 [1] $VOL1.S04.TALDYN 1991-10-15 13:42:28


display^result
281. 001132 1 2
282. 001132 1 2 END; ! end FOR loop
283. 001141 1 1
284. 001141 1 1 ! blank line to separate rows
285. 001141 1 1 PRINT^BLANK^LINE;
286. 001151 1 1 END; ! end of proc display^result
287. 000000 0 0
288. 000000 0 0
289. 000000 0 0

HP NonStop SQL Programming Manual for TAL—527887-001


C-19
Examples of Dynamic NonStop SQL Programs Detailed Dynamic SQL Program

Page 9 [1] $VOL1.S04.TALDYN 1991-10-15 13:42:28


request^invars
291. 000000 0 0 INT PROC request^invars (sqlda, cnames);
292. 000000 1 0
293. 000000 1 0 !******************************************************!
294. 000000 1 0 ! PROC request^invars: !
295. 000000 1 0 ! This proc prompts for a value for each input parameter.!
296. 000000 1 0 ! !
297. 000000 1 0 ! Returns 0 if successful, -1 otherwise !
298. 000000 1 0 !*******************************************************!
299. 000000 1 0
300. 000000 1 0 STRUCT .EXT sqlda(sqlda^type); !IN: Input SQLDA
301. 000000 1 0 STRING .EXT cnames; !IN: contains parameter names
302. 000000 1 0
303. 000000 1 0 BEGIN
304. 000000 1 1
305. 000000 1 1 STRING .param^name[0:MAX^COLUMN^NAME^SIZE]; ! current
parameter name
306. 000000 1 1 INT namelen; ! length of current parameter name
307. 000000 1 1 INT nameix; ! index into parameter names string
308. 000000 1 1 INT input^num; ! number of parameters to be
obtained
309. 000000 1 1 INT count^read;
310. 000000 1 1 INT i;
311. 000000 1 1 INT .EXT param^ (sql^types); ! pointer to parameter
value
312. 000000 1 1 INT maxlen; ! maximum length of string parameter
313. 000000 1 1 INT .EXT ind^; ! pointer used to set null indicator
314. 000000 1 1 INT(32) temp; ! hold result from DNUMIN for 16-bit
case
315. 000000 1 1 ! (NUMIN will not accept an extended
address)
316. 000000 1 1
317. 000000 1 1 PRINT^BLANK^LINE;
318. 000015 1 1 PUT^STR ("Please provide data for input params");
319. 000033 1 1 PRINT^LINE;
320. 000046 1 1
321. 000046 1 1 PUT^STR ("------------------------------------");
322. 000064 1 1 PRINT^LINE;
323. 000077 1 1
324. 000077 1 1 PRINT^BLANK^LINE;
325. 000107 1 1
326. 000107 1 1 --
327. 000107 1 1 -- Get number of input variables.
328. 000107 1 1 --
329. 000107 1 1
330. 000107 1 1 input^num := sqlda.num^entries;
331. 000115 1 1
332. 000115 1 1 nameix := 1;
333. 000117 1 1
334. 000117 1 1
335. 000117 1 1 FOR i := 0 TO (input^num - 1) DO
336. 000121 1 1 BEGIN
337. 000121 1 2 !
338. 000121 1 2 ! Get a parameter name
339. 000121 1 2 !
340. 000121 1 2
341. 000121 1 2 namelen := cnames[nameix];
342. 000127 1 2 IF namelen THEN -- Is the parameter named?
343. 000131 1 2 param^name ':=' cnames[nameix+1] FOR namelen;
344. 000142 1 2
345. 000142 1 2 nameix := cnames[nameix] + 2 + nameix;
346. 000153 1 2
347. 000153 1 2 !**********************************************************!

HP NonStop SQL Programming Manual for TAL—527887-001


C-20
Examples of Dynamic NonStop SQL Programs Detailed Dynamic SQL Program

Page 10 [1] $VOL1.S04.TALDYN 1991-10-15 13:42:28


request^invars
348. 000153 1 2 ! Request input value based on data type !
349. 000153 1 2 !***************************************************!
350. 000153 1 2
351. 000153 1 2 @param^ := sqlda.sqlvar[i].var^ptr; ! pointer to storage
for current
352. 000166 1 2 ! parameter
353. 000166 1 2 maxlen := sqlda.sqlvar[i].data^len;
354. 000201 1 2
355. 000201 1 2 CASE sqlda.sqlvar[i].data^type OF
356. 000214 1 2 BEGIN
357. 000214 1 3 _SQLDT_ASCII_F,
358. 000214 1 3 _SQLDT_ASCII_F_UP ->
359. 000214 1 3 PUT^STR ("Please enter max ");
360. 000232 1 3 PUT^INT^MID (maxlen);
361. 000252 1 3 PUT^STR^MID (" characters");
362. 000266 1 3 if namelen then
363. 000270 1 3 begin
364. 000270 1 4 PUT^STR^MID (" for " & param^name for namelen);
365. 000311 1 4 end;
366. 000311 1 3 PUT^STR^MID (": ");
367. 000327 1 3 PRINT^LINE;
368. 000342 1 3
369. 000342 1 3 param^.v^char ':=' " " & param^.v^char for maxlen-1;
370. 000361 1 3 call READX(term,param^.v^char,maxlen);
371. 000372 1 3
372. 000372 1 3 IF (sqlda.sqlvar[i].null^info = -1) AND
373. 000372 1 3 (param^.v^char = "?") THEN
374. 000414 1 3 begin ! got a null value; set null indicator
375. 000414 1 4 @ind^ := sqlda.sqlvar[i].ind^ptr;
376. 000427 1 4 ind^ := -1;
377. 000432 1 4 end;
378. 000432 1 3
379. 000432 1 3 _SQLDT_ASCII_V,
380. 000433 1 3 _SQLDT_ASCII_V_UP ->
381. 000433 1 3 PUT^STR ("Please enter max ");
382. 000451 1 3 PUT^INT^MID (maxlen);
383. 000471 1 3 PUT^STR^MID(" characters");
384. 000505 1 3 if namelen then
385. 000507 1 3 begin
386. 000507 1 4 PUT^STR^MID (" for " & param^name for namelen);
387. 000530 1 4 end;
388. 000530 1 3 PUT^STR^MID (": ");
389. 000544 1 3 PRINT^LINE;
390. 000557 1 3
391. 000557 1 3 callREADX(term,param^.v^varchar.val,maxlen, param^
.v^varchar.len);
392. 000574 1 3
393. 000574 1 3 IF (sqlda.sqlvar[i].null^info = -1) AND
394. 000574 1 3 (param^.v^varchar.val = "?") THEN
395. 000614 1 3 begin ! got a null value; set null indicator
396. 000614 1 4 @ind^ := sqlda.sqlvar[i].ind^ptr;
397. 000627 1 4 ind^ := -1;
398. 000634 1 4 end;
399. 000634 1 3
400. 000634 1 3 _SQLDT_16BIT_S,
401. 000635 1 3 _SQLDT_16BIT_U,
402. 000635 1 3 _SQLDT_32BIT_S,
403. 000635 1 3 _SQLDT_32BIT_U ->
404. 000635 1 3 PUT^STR ("Please enter a numeric value");

HP NonStop SQL Programming Manual for TAL—527887-001


C-21
Examples of Dynamic NonStop SQL Programs Detailed Dynamic SQL Program

Page 11 [1] $VOL1.S04.TALDYN 1991-10-15 13:42:28


request^invars
405. 000653 1 3 if namelen then
406. 000655 1 3 begin
407. 000655 1 4 PUT^STR^MID (" for " & param^name for namelen);
408. 000676 1 4 end;
409. 000676 1 3 PUT^STR^MID (": ");
410. 000712 1 3 call WRITEREAD(term,buf,$INT(@next^buf -
@sbuf),25,count^read);
411. 000726 1 3 sbuf[count^read] := 0; ! terminator for DNUMIN and scan
412. 000731 1 3 @next^buf := @sbuf;
413. 000733 1 3 while next^buf <> 0 and next^buf = " " do @next^buf :=
@next^buf[1];
414. 000750 1 3
415. 000750 1 3 IF (sqlda.sqlvar[i].null^info = -1) AND
416. 000750 1 3 (next^buf = "?") THEN
417. 000770 1 3 begin ! got a null value; set null indicator
418. 000770 1 4 @ind^ := sqlda.sqlvar[i].ind^ptr;
419. 001003 1 4 ind^ := -1;
420. 001006 1 4
421. 001006 1 4 end else begin
422. 001007 1 4
423. 001007 1 4 CASE sqlda.sqlvar[i].data^type OF
424. 001022 1 4 begin
425. 001022 1 5 _SQLDT_16BIT_S,
426. 001022 1 5 _SQLDT_16BIT_U ->
427. 001022 1 5 call DNUMIN(next^buf,temp,10);
428. 001036 1 5 ! Problems:
429. 001036 1 5 ! Unsigned should not allow minus sign.
430. 001036 1 5 ! Should check status for error.
431. 001036 1 5 ! Should check that whole string was
consumed.
432. 001036 1 5 ! Should check that value fits in 16-bits
433. 001036 1 5 param^.v^smallint := $INT(temp);
434. 001042 1 5 _SQLDT_32BIT_S,
435. 001043 1 5 _SQLDT_32BIT_U ->
436. 001043 1 5 call DNUMIN(next^buf,param^.v^int,10);
437. 001055 1 5 ! This isn't completely right for unsigned
438. 001055 1 5 ! should check status for error and should
439. 001055 1 5 ! check that whole string was consumed.
440. 001055 1 5 end;
441. 001101 1 4 end;
442. 001101 1 3
443. 001101 1 3 _SQLDT_DATETIME ->
444. 001102 1 3 PUT^STR ("Please enter a date/time value");
445. 001120 1 3 if namelen then
446. 001122 1 3 begin
447. 001122 1 4 PUT^STR^MID (" for " & param^name for namelen);
448. 001143 1 4 end;
449. 001143 1 3 PUT^STR^MID (": ");
450. 001157 1 3 PRINT^LINE;
451. 001172 1 3 param^.v^datetime ':=' " " & param^.v^datetime
452. 001172 1 3 for $OCCURS(param^.v^datetime)-1;
453. 001210 1 3 call READX (term, param^.v^datetime, $OCCURS
(param^.v^datetime));
454. 001221 1 3
455. 001221 1 3 IF (sqlda.sqlvar[i].null^info = -1) AND
456. 001221 1 3 (param^.v^datetime = "?") THEN
457. 001241 1 3 begin ! got a null value; set null indicator
458. 001241 1 4 @ind^ := sqlda.sqlvar[i].ind^ptr;
459. 001254 1 4 ind^ := -1;
460. 001257 1 4 end;
461. 001257 1 3

HP NonStop SQL Programming Manual for TAL—527887-001


C-22
Examples of Dynamic NonStop SQL Programs Detailed Dynamic SQL Program

Page 12 [1] $VOL1.S04.TALDYN 1991-10-15 13:42:28


request^invars
462. 001257 1 3 _SQLDT_INT_Y_Y .. _SQLDT_INT_D_F ->
463. 001260 1 3 PUT^STR ("Please enter a date/time interval");
464. 001276 1 3 if namelen then
465. 001302 1 3 begin
466. 001302 1 4 PUT^STR^MID (" for " & param^name for namelen);
467. 001323 1 4 end;
468. 001323 1 3 PUT^STR^MID (": ");
469. 001337 1 3 PRINT^LINE;
470. 001352 1 3 param^.v^datetime ':=' " " & param^.v^datetime
471. 001352 1 3 for $OCCURS(param^.v^datetime)-1;
472. 001370 1 3 call READX(term,param^.v^datetime,$OCCURS
(param^.v^datetime));
473. 001401 1 3
474. 001401 1 3 IF (sqlda.sqlvar[i].null^info = -1) AND
475. 001401 1 3 (param^.v^datetime = "?") THEN
476. 001421 1 3 begin ! got a null value; set null indicator
477. 001421 1 4 @ind^ := sqlda.sqlvar[i].ind^ptr;
478. 001434 1 4 ind^ := -1;
479. 001437 1 4 end;
480. 001437 1 3
481. 001437 1 3 OTHERWISE ->
482. 001440 1 3 PUT^STR ("This data type is not supported: ");
483. 001456 1 3 PUT^INT^MID(sqlda.sqlvar[i].data^type);
484. 001507 1 3 PRINT^LINE;
485. 001522 1 3 END; !end of case
486. 002063 1 2
487. 002063 1 2 END; !for
488. 002072 1 1
489. 002072 1 1 return 0;
490. 002074 1 1 END; ! end of proc request^invars
491. 000000 0 0
492. 000000 0 0
493. 000000 0 0

HP NonStop SQL Programming Manual for TAL—527887-001


C-23
Examples of Dynamic NonStop SQL Programs Detailed Dynamic SQL Program

Page 13 [1] $VOL1.S04.TALDYN 1991-10-15 13:42:28


read^query
495. 000000 0 0 INT PROC read^query ;
496. 000000 1 0
497. 000000 1 0 !*********************************************************!
498. 000000 1 0 ! PROC read^query !
499. 000000 1 0 ! reads in a complete SQL statement from the input file. !
500. 000000 1 0 ! A SQL statement is terminated by putting a ";" at !
501. 000000 1 0 ! the end of a line. !
502. 000000 1 0 !**********************************************************!
503. 000000 1 0
504. 000000 1 0 BEGIN
505. 000000 1 1 INT count^read; ! number of bytes read
506. 000000 1 1 INT i; ! index variable
507. 000000 1 1
508. 000000 1 1 host1.len := 0;
509. 000003 1 1 host1.str := 0;
510. 000010 1 1
511. 000010 1 1 PRINT^BLANK^LINE;
512. 000020 1 1
513. 000020 1 1 PUT^STR ("Enter SQL statement or SAME to reuse last
statement or END:");
514. 000036 1 1 PRINT^LINE;
515. 000051 1 1
516. 000051 1 1 !
517. 000051 1 1 ! Loop until an entire SQL statement has been found.
518. 000051 1 1 !
519. 000051 1 1
520. 000051 1 1 while host1.str[host1.len-1] <> ";"
521. 000051 1 1 and host1.len < MAX^SQL^STMT^LENGTH do
522. 000066 1 1 begin
523. 000066 1 2 host1.str[host1.len] ':=' ">>";
524. 000102 1 2 call WRITEREADX(term,host1.str[host1.len],2,
525. 000102 1 2 MAX^SQL^STMT^LENGTH-host1.len,count^read);
526. 000131 1 2 if count^read > 0 then
527. 000134 1 2 begin
528. 000134 1 3 while host1.str[host1.len+count^read-1] = " " do !
trim trailing blanks
529. 000147 1 3 count^read := count^read - 1;
530. 000152 1 3 host1.len := host1.len + count^read;
531. 000154 1 3 end;
532. 000154 1 2 end;
533. 000155 1 1
534. 000155 1 1 ! Drop the semicolon terminator
535. 000155 1 1
536. 000155 1 1 host1.len := host1.len - 1;
537. 000157 1 1
538. 000157 1 1 ! Note: to preserve simplicity, this program does only
skeleton
539. 000157 1 1 ! checking on the contents of the input string. Because the
540. 000157 1 1 ! same buffer is used for the SQL statement and for the
exit/repeat
541. 000157 1 1 ! commands, we cannot UPSHIFT before checking the string.
Actual
542. 000157 1 1 ! programs would copy the input string into a separate
buffer, loop
543. 000157 1 1 ! through the string, and check the contents for correctness.
544. 000157 1 1
545. 000157 1 1 if host1.str = "E" or host1.str = "e" then return -1;
546. 000175 1 1
547. 000175 1 1 if host1.str = "SAME" or host1.str = "same" then
548. 000223 1 1 begin
549. 000223 1 2 host1.str ':=' host2.str for host2.len bytes; ! retrieve
saved query
550. 000233 1 2 host1.len := host2.len;
551. 000235 1 2 PRINT^BLANK^LINE;

HP NonStop SQL Programming Manual for TAL—527887-001


C-24
Examples of Dynamic NonStop SQL Programs Detailed Dynamic SQL Program

Page 14 [1] $VOL1.S04.TALDYN 1991-10-15 13:42:28


read^query
552. 000245 1 2 PUT^STR ("Re-executing query >> ");
553. 000263 1 2 PRINT^LINE;
554. 000276 1 2 call WRITEX(term,host1.str,host1.len);
555. 000312 1 2
556. 000312 1 2 end else begin
557. 000313 1 2
558. 000313 1 2 host2.str ':=' host1.str for host1.len bytes; ! save query
for reuse
559. 000323 1 2 host2.len := host1.len;
560. 000325 1 2 end;
561. 000325 1 1
562. 000325 1 1 return 0;
563. 000327 1 1 END; !end of proc read^query
564. 000000 0 0
565. 000000 0 0
566. 000000 0 0
567. 000000 0 0

HP NonStop SQL Programming Manual for TAL—527887-001


C-25
Examples of Dynamic NonStop SQL Programs Detailed Dynamic SQL Program

Page 15 [1] $VOL1.S04.TALDYN 1991-10-15 13:42:28


adjust^sqlda^scale^types
569. 000000 0 0 PROC adjust^sqlda^scale^types(sqlda);
570. 000000 1 0
571. 000000 1 0 !******************************************************!
572. 000000 1 0 ! PROC adjust^sqlda^scale^types: !
573. 000000 1 0 ! This function takes an SQLDA as a parameter and !
574. 000000 1 0 ! adjusts the recommended (by SQL) data types and !
575. 000000 1 0 ! scales to what TAL supports. !
576. 000000 1 0 ! !
577. 000000 1 0 ! Adjusting for supported data types involves
modifying !
578. 000000 1 0 ! the data^len and data^type of the SQLVAR entry to !
579. 000000 1 0 ! reflect the data attributes that TAL can support. !
580. 000000 1 0 ! !
581. 000000 1 0 ! For example, an input parameter or output variable
with !
582. 000000 0 1 ! data^type = _SQLDT_DEC_LSS and !
583. 000000 0 1 ! data^len = 7 (assuming scale = 0) !
584. 000000 0 1 ! can be modified to have !
585. 000000 0 1 ! data^type = _SQLDT_32BIT_S and !
586. 000000 0 1 ! data^len = 4. !
587. 000000 0 1 ! !
588. 000000 0 1 ! Independently of the data type change, the scale is !
589. 000000 0 1 ! set to 0. This will cause the TAL program to deal !
590. 000000 0 1 ! only with the integer part of the value. More !
591. 000000 0 1 ! sophisticated programs could note the scale value !
592. 000000 0 1 ! from the SQLDA and take it into account in their !
593. 000000 0 1 ! computations. !
594. 000000 0 1 ! !
595. 000000 0 1 ! Although TAL does support scaled values in FIXED !
596. 000000 0 1 ! variables, there are no convenient formatting !
597. 000000 0 1 ! procedures for FIXED values, so this program does !
598. 000000 0 1 ! not used FIXED data. !
599. 000000 0 1 ! !
600. 000000 0 1 !*******************************************************!
601. 000000 0 1
602. 000000 1
0 STRUCT .ext sqlda (sqlda^type); ! IN -- pointer to the SQLDA
603. 000000 0 1
604. 000000 1
0 BEGIN
605. 000000 1 1 INT i;
606. 000000 1 1
607. 000000 1 1 FOR i := 0 TO sqlda.num^entries-1 DO
608. 000003 1 1 BEGIN
609. 000003 2 1 CASE sqlda.sqlvar[i].data^type OF
610. 000016 2 1 BEGIN
611. 000016 3 1 _SQLDT_16BIT_S, ! SMALLINT
612. 000016 3 1 _SQLDT_16BIT_U, ! UNSIGNED SMALLINT
613. 000016 3 1 _SQLDT_32BIT_S, ! INTEGER
614. 000016 3 1 _SQLDT_32BIT_U -> ! UNSIGNED INTEGER
615. 000016 3 1 ! set scale to 0
616. 000016 3 1 sqlda.sqlvar[i].data^len.<0:7> := 0;
617. 000031 3 1
618. 000031 3 1 _SQLDT_64BIT_S -> ! LARGEINT
619. 000032 3 1 ! set scale to 0 and change type to 32-bit integer
620. 000032 3 1 sqlda.sqlvar[i].data^len.<0:7> := 0;
621. 000045 3 1 sqlda.sqlvar[i].data^type := _SQLDT_32BIT_S;
622. 000060 3 1 sqlda.sqlvar[i].data^len.<8:15> := 4; ! length
of 32 bits
623. 000074 1 3
624. 000074 1 3 _SQLDT_DEC_U, ! DECIMAL unsigned
625. 000075 1 3 _SQLDT_DEC_LSS, ! DECIMAL LSS

HP NonStop SQL Programming Manual for TAL—527887-001


C-26
Examples of Dynamic NonStop SQL Programs Detailed Dynamic SQL Program

Page 16 [1] $VOL1.S04.TALDYN 1991-10-15 13:42:28


adjust^sqlda^scale^types
626. 000075 1 3 _SQLDT_DEC_LSE, ! DECIMAL LSE
627. 000075 1 3 _SQLDT_DEC_TSS, ! DECIMAL TSS
628. 000075 1 3 _SQLDT_DEC_TSE -> ! DECIMAL TSE
629. 000075 1 3 ! change DECIMAL type to 32-bit integer and set
scale to 0
630. 000075 1 3 sqlda.sqlvar[i].data^len.<0:7> := 0;
631. 000110 1 3 sqlda.sqlvar[i].data^type := _SQLDT_32BIT_S;
632. 000123 1 3 sqlda.sqlvar[i].data^len.<8:15> := 4; ! length
of 32 bits
633. 000137 1 3
634. 000137 1 3 otherwise -> ; ! nothing to do for other types
635. 000140 1 3 end;
636. 000206 1 2 end;
637. 000221 1 1 END; ! of proc adjust^sqlda^scale^types
638. 000000 0 0
639. 000000 0 0
640. 000000 0 0
641. 000000 0 0

HP NonStop SQL Programming Manual for TAL—527887-001


C-27
Examples of Dynamic NonStop SQL Programs Detailed Dynamic SQL Program

Page 17 [1] $VOL1.S04.TALDYN 1991-10-15 13:42:28


setupvarbuffers
643. 000000 0 0 INT PROC setupvarbuffers(sqlda);
644. 000000 1 0
645. 000000 1 0 !********************************************************!
646. 000000 1 0 ! PROC setupvarbuffers: !
647. 000000 1 0 ! This function takes an SQLDA as a parameter and !
648. 000000 1 0 ! allocates the data and indicator value buffers. !
649. 000000 1 0 ! For each sqlvar, var^ptr is set to point to the !
650. 000000 1 0 ! data buffer and if null^info is set, ind^ptr is !
651. 000000 1 0 ! set to point to the indicator value. !
652. 000000 1 0 ! !
653. 000000 1 0 ! The sqlda is also changed by altering unsupported !
654. 000000 1 0 ! data types to the nearest equivalent data types !
655. 000000 1 0 ! and by setting the scale information to 0. !
656. 000000 1 0 ! !
657. 000000 1 0 ! sqlda.num^entries is assumed to have a valid value. !
658. 000000 1 0 ! !
659. 000000 1 0 ! Returns: 0 if successful !
660. 000000 1 0 ! -1 if failure !
661. 000000 1 0 ! !
662. 000000 1 0 !********************************************************!
663. 000000 1 0
664. 000000 1 0 STRUCT .ext sqlda (sqlda^type); ! IN -- pointer to the SQLDA
665. 000000 1 0
666. 000000 1 0 BEGIN
667. 000000 1 1 INT i;
668. 000000 1 1 INT .EXT ind^ptr^; ! temporary pointer for initializing
IND^PTR
669. 000000 1 1 ! to 0
670. 000000 1 1 INT mem^reqd;
671. 000000 1 1
672. 000000 1 1 !********************************************************!
673. 000000 1 1 ! Handle unsupported types; set scale information to 0. !
674. 000000 1 1 !********************************************************!
675. 000000 1 1 call adjust^sqlda^scale^types(sqlda);
676. 000004 1 1
677. 000004 1 1 FOR i := 0 TO sqlda.num^entries-1 DO
678. 000006 1 1 BEGIN
679. 000006 1 2 !***************************************************!
680. 000006 1 2 ! Determine the amount of memory needed by this entry's
data type. !
681. 000006 1 2 !******************************************************!
682. 000006 1 2 CASE sqlda.sqlvar[i].data^type OF
683. 000021 1 2 BEGIN
684. 000021 1 3 _SQLDT_ASCII_F, ! CHAR datatype
685. 000021 1 3 _SQLDT_ASCII_F_UP ->
686. 000021 1 3 mem^reqd := sqlda.sqlvar[i].data^len;
687. 000034 1 3 _SQLDT_ASCII_V, ! VARCHAR
688. 000035 1 3 _SQLDT_ASCII_V_UP ->
689. 000035 1 3 mem^reqd := sqlda.sqlvar[i].data^len + 2;
690. 000051 1 3 _SQLDT_16BIT_S, ! SMALLINT
691. 000052 1 3 _SQLDT_16BIT_U, ! UNSIGNED SMALLINT
692. 000052 1 3 _SQLDT_32BIT_S, ! INTEGER
693. 000052 1 3 _SQLDT_32BIT_U, ! UNSIGNED INTEGER
694. 000052 1 3 _SQLDT_64BIT_S, ! LARGEINT
695. 000052 1 3 _SQLDT_REAL, ! REAL
696. 000052 1 3 _SQLDT_DOUBLE -> ! DOUBLE PRECISION
697. 000052 1 3 mem^reqd := sqlda.sqlvar[i].data^len.<8:15>;
698. 000066 1 3 _SQLDT_DEC_U, ! DECIMAL unsigned
699. 000067 1 3 _SQLDT_DEC_LSS, ! DECIMAL LSS

HP NonStop SQL Programming Manual for TAL—527887-001


C-28
Examples of Dynamic NonStop SQL Programs Detailed Dynamic SQL Program

Page 18 [1] $VOL1.S04.TALDYN 1991-10-15 13:42:28


setupvarbuffers
700. 000067 1 3 _SQLDT_DEC_LSE, ! DECIMAL LSE
701. 000067 1 3 _SQLDT_DEC_TSS, ! DECIMAL TSS
702. 000067 1 3 _SQLDT_DEC_TSE -> ! DECIMAL TSE
703. 000067 1 3 mem^reqd := sqlda.sqlvar[i].data^len.<8:15>;
704. 000103 1 3 _SQLDT_DATETIME .. _SQLDT_INT_D_F -> ! Date-time
705. 000104 1 3 mem^reqd := sqlda.sqlvar[i].data^len.<8:15>;
706. 000120 1 3 OTHERWISE ->
707. 000121 1 3 PUT^STR ("This data type is not supported: ");
708. 000137 1 3 PUT^INT^MID (sqlda.sqlvar[i].data^len);
709. 000170 1 3 PRINT^LINE;
710. 000203 1 3 return -1;
711. 000210 1 3 END; !end of case
712. 000550 1 2
713. 000550 1 2 !*******************************************************!
714. 000550 1 2 ! Allocate memory for the data value and assign the byte
address !
715. 000550 1 2 ! of the data buffer to var^ptr of sqlvar[i]. !
716. 000550 1 2 !*******************************************************!
717. 000550 1 2 sqlda.sqlvar[i].var^ptr := GETPOOL(pool^head,
$DBL(mem^reqd));
718. 000571 1 2 IF sqlda.sqlvar[i].var^ptr = -1d THEN
719. 000606 1 2 BEGIN
720. 000606 1 3 PUT^STR ("Getpool memory management error");
721. 000624 1 3 PRINT^LINE;
722. 000637 1 3 CALL ABEND;
723. 000644 1 3 END;
724. 000644 1 2
725. 000644 1 2 !*******************************************************!
726. 000644 1 2 ! If null^info is set, allocate a buffer for the indicator
value !
727. 000644 1 2 ! and assign its address to ind^ptr of sqlvar[i]. !
728. 000644 1 2 !*******************************************************!
729. 000644 1 2 IF sqlda.sqlvar[i].null^info = -1 THEN
730. 000660 1 2 BEGIN
731. 000660 1 3 sqlda.sqlvar[i].ind^ptr := GETPOOL(pool^head, $DBL(2));
732. 000701 1 3 IF sqlda.sqlvar[i].ind^ptr = -1d THEN
733. 000716 1 3 BEGIN
734. 000716 1 4 PUT^STR ("Getpool memory management error");
735. 000734 1 4 PRINT^LINE;
736. 000747 1 4 CALL ABEND;
737. 000754 1 4 END;
738. 000754 1 3 @ind^ptr^ := sqlda.sqlvar[i].ind^ptr;
739. 000767 1 3 ind^ptr^ := 0; ! set memory IND^PTR points at to 0
740. 000771 1 3 END;
741. 000771 1 2 END; ! end of for
742. 001004 1 1
743. 001004 1 1 return 0;
744. 001006 1 1 END; ! of proc setupvarbuffers
745. 000000 0 0
746. 000000 0 0
747. 000000 0 0
748. 000000 0 0

HP NonStop SQL Programming Manual for TAL—527887-001


C-29
Examples of Dynamic NonStop SQL Programs Detailed Dynamic SQL Program

Page 19 [1] $VOL1.S04.TALDYN 1991-10-15 13:42:28


allocate^sqlda
750. 000000 0 0 INT(32) PROC allocate^sqlda (num^entries);
751. 000000 1 0
752. 000000 1 0 !******************************************************!
753. 000000 1 0 ! PROC allocate^sqlda: !
754. 000000 1 0 ! This proc allocates an sqlda structure with num^entries
entries. !
755. 000000 1 0 ! It also initializes the sqlda and the sqlvars. !
756. 000000 1 0 ! A names buffer is also allocated. !
757. 000000 1 0 ! !
758. 000000 1 0 ! Returns: address of the sqlda created if successful !
759. 000000 1 0 ! NULL^ADDR if unsuccessful !
760. 000000 1 0 !******************************************************!
761. 000000 1 0
762. 000000 1 0 INT num^entries; ! IN -- number of parameters or columns
763. 000000 1 0 BEGIN
764. 000000 1 1 INT .EXT sqlda(sqlda^type); ! sqlda pointer to return
765. 000000 1 1 INT mem^reqd; ! gets amount of space needed for the sqlda
766. 000000 1 1 INT i; ! loop counter
767. 000000 1 1
768. 000000 1 1 ! Return null if zero entries requested
769. 000000 1 1
770. 000000 1 1 if num^entries = 0 then return NULL^ADDR;
771. 000006 1 1
772. 000006 1 1 ! Compute amount of memory needed for the sqlda
773. 000006 1 1
774. 000006 1 1 mem^reqd := $LEN(sqlda^type) + (num^entries-
1)*$LEN(sqlda^type.sqlvar);
775. 000015 1 1
776. 000015 1 1 ! Allocate the space. If error allocating, return null
address.
777. 000015 1 1
778. 000015 1 1 @sqlda := GETPOOL(pool^head,$DBL(mem^reqd));
779. 000025 1 1 if @sqlda = -1D then return NULL^ADDR;
780. 000034 1 1
781. 000034 1 1 ! Initialize the sqlda eye catcher and number of entries.
782. 000034 1 1
783. 000034 1 1 sqlda.eye^catcher ':=' SQLDA^EYE^CATCHER;
784. 000046 1 1 sqlda.num^entries := num^entries;
785. 000051 1 1
786. 000051 1 1 ! Initialize the pointers to the variable value and to the
787. 000051 1 1 ! null indicator in each sqlvar entry to the null address.
788. 000051 1 1
789. 000051 1 1 for i := 0 to num^entries-1 do
790. 000053 1 1 begin
791. 000053 1 2 sqlda.sqlvar[i].var^ptr := NULL^ADDR;
792. 000067 1 2 sqlda.sqlvar[i].ind^ptr := NULL^ADDR;
793. 000103 1 2 end;
794. 000112 1 1
795. 000112 1 1 ! Return the address of the sqlda allocated.
796. 000112 1 1
797. 000112 1 1 return @sqlda;
798. 000114 1 1 END; ! of proc allocate^sqlda
799. 000000 0 0
800. 000000 0 0
801. 000000 0 0
802. 000000 0 0

HP NonStop SQL Programming Manual for TAL—527887-001


C-30
Examples of Dynamic NonStop SQL Programs Detailed Dynamic SQL Program

Page 20 [1] $VOL1.S04.TALDYN 1991-10-15 13:42:28


free^sqlda
804. 000000 0 0 PROC free^sqlda (sqlda);
805. 000000 1 0
806. 000000 1 0 !*******************************************************!
807. 000000 1 0 ! PROC free^sqlda: !
808. 000000 1 0 ! This proc accepts an sqlda as a parameter and !
809. 000000 1 0 ! frees all memory that was allocated for the data !
810. 000000 1 0 ! buffers (pointed to as sqlvar[i].var^ptr), the !
811. 000000 1 0 ! indicator variables (pointed to as sqlvar[i].ind^ptr), !
812. 000000 1 0 ! and for the sqlda and sqlvar entries. !
813. 000000 1 0 ! !
814. 000000 1 0 ! The proc assumes that if a nonnull sqlda address !
815. 000000 1 0 ! is passed, then sqlda.num^entries has a valid value. !
816. 000000 1 0 ! !
817. 000000 1 0 !******************************************************!
818. 000000 1 0
819. 000000 1 0 STRUCT .ext sqlda (sqlda^type); ! IN--Pointer to SQLDA
820. 000000 1 0
821. 000000 1 0 BEGIN
822. 000000 1 1 INT i;
823. 000000 1 1 INT .EXT ptr; ! temporary pointer for freeing memory
pointed
824. 000000 1 1 ! at by var^ptr or ind^ptr
825. 000000 1 1
826. 000000 1 1 if @sqlda = NULL^ADDR then return;
827. 000007 1 1
828. 000007 1 1 FOR i := 0 TO sqlda.num^entries-1 DO
829. 000011 1 1 BEGIN
830. 000011 1 2 @ptr := sqlda.sqlvar[i].var^ptr;
831. 000024 1 2 if @ptr <> NULL^ADDR then
832. 000031 1 2 begin
833. 000031 1 3 CALL PUTPOOL(pool^head, ptr);
834. 000037 1 3 if <> then
835. 000040 1 3 begin
836. 000040 1 4 PUT^STR ("PUTPOOL memmory management error");
837. 000056 1 4 PRINT^LINE;
838. 000071 1 4 call ABEND;
839. 000076 1 4 end;
840. 000076 1 3 end;
841. 000076 1 2 @ptr := sqlda.sqlvar[i].ind^ptr;
842. 000111 1 2 if @ptr >= 0D then ! ***** don't know why <>
NULL^ADDR doesn't work ****
843. 000114 1 2 begin
844. 000114 1 3 CALL PUTPOOL(pool^head, ptr);
845. 000122 1 3 if <> then
846. 000123 1 3 begin
847. 000123 1 4 PUT^STR ("PUTPOOL memory management error");
848. 000141 1 4 PRINT^LINE;
849. 000154 1 4 call ABEND;
850. 000161 1 4 end;
851. 000161 1 3 end;
852. 000161 1 2 END;
853. 000174 1 1
854. 000174 1 1 call PUTPOOL (pool^head, sqlda);
855. 000202 1 1 if <> then
856. 000203 1 1 begin
857. 000203 1 2 PUT^STR ("PUTPOOL memory management error");
858. 000221 1 2 PRINT^LINE;
859. 000234 1 2 call ABEND;
860. 000241 1 2 end;

HP NonStop SQL Programming Manual for TAL—527887-001


C-31
Examples of Dynamic NonStop SQL Programs Detailed Dynamic SQL Program

Page 21 [1] $VOL1.S04.TALDYN 1991-10-15 13:42:28


free^sqlda
861. 000241 1 1
862. 000241 1 1 END; ! of proc free^sqlda
863. 000000 0 0
Page 22 [1] $VOL1.S04.TALDYN 1991-10-15 13:42:28
cleanup
865. 000000 0 0 PROC cleanup;
866. 000000 1 0 !***************************************************!
867. 000000 1 0 ! PROC cleanup: !
868. 000000 1 0 ! This proc frees up the allocated memory for the input
and !
869. 000000 1 0 ! output sqldas and names buffers and the data buffers
allocated !
870. 000000 1 0 ! for the sqldas. !
871. 000000 1 0 !***************************************************!
872. 000000 1 0 BEGIN
873. 000000 1 1 call free^sqlda(sda^i);
874. 000004 1 1 call free^sqlda(sda^o);
875. 000007 1 1 @sda^i := @sda^o := NULL^ADDR;
876. 000014 1 1
877. 000014 1 1 if @cname^i <> NULL^ADDR then
878. 000021 1 1 begin
879. 000021 1 2 call PUTPOOL(pool^head,cname^i);
880. 000027 1 2 if <> then
881. 000030 1 2 begin
882. 000030 1 3 PUT^STR ("PUTPOOL memory management error");
883. 000046 1 3 PRINT^LINE;
884. 000061 1 3 call ABEND;
885. 000066 1 3 end;
886. 000066 1 2 @cname^i := NULL^ADDR;
887. 000071 1 2 end;
888. 000071 1 1 if @cname^o <> NULL^ADDR then
889. 000076 1 1 begin
890. 000076 1 2 call PUTPOOL(pool^head,cname^o);
891. 000104 1 2 if <> then
892. 000105 1 2 begin
893. 000105 1 3 PUT^STR ("PUTPOOL memory management error");
894. 000123 1 3 PRINT^LINE;
895. 000136 1 3 call ABEND;
896. 000143 1 3 end;
897. 000143 1 2 @cname^o := NULL^ADDR;
898. 000146 1 2 end;
899. 000146 1 1 END;
900. 000000 0 0
901. 000000 0 0

HP NonStop SQL Programming Manual for TAL—527887-001


C-32
Examples of Dynamic NonStop SQL Programs Detailed Dynamic SQL Program

Page 23 [1] $VOL1.S04.TALDYN 1991-10-15 13:42:28


startup^and^define^pool
903. 000000 0 0 PROC startup^and^define^pool;
904. 000000 1 0
905. 000000 1 0 !******************************************************!
906. 000000 1 0 ! PROC startup^and^define^pool !
907. 000000 1 0 ! reads startup message, opens terminal, and defines
memory pool !
908. 000000 1 0 !********************************************************!
909. 000000 1 0
910. 000000 1 0 BEGIN
911. 000000 1 1 INT error; ! definepool error
912. 000000 1 1 INT termname[0:11]; ! gets home terminal name from
MYTERM
913. 000000 1 1
914. 000000 1 1 !
915. 000000 1 1 ! Read startup message.
916. 000000 1 1 !
917. 000000 1 1
918. 000000 1 1 call INITIALIZER;
919. 000006 1 1
920. 000006 1 1 !
921. 000006 1 1 ! Open terminal for output.
922. 000006 1 1 !
923. 000006 1 1
924. 000006 1 1 CALL MYTERM(termname);
925. 000011 1 1 CALL OPEN(termname, term);
926. 000021 1 1 IF <> THEN CALL DEBUG;
927. 000023 1 1
928. 000023 1 1 !
929. 000023 1 1 ! Initialize memory pool.
930. 000023 1 1 !
931. 000023 1 1
932. 000023 1 1 error := DEFINEPOOL(pool^head, pool, POOL^SIZE^IN^BYTES);
933. 000036 1 1 IF error <> 0 THEN
934. 000040 1 1 BEGIN
935. 000040 1 2 PUT^STR ("Definepool error: ");
936. 000056 1 2 PUT^INT^MID (error);
937. 000076 1 2 PRINT^LINE;
938. 000111 1 2 CALL ABEND;
939. 000116 1 2 END;
940. 000116 1 1 END; !end of proc startup^and^define^pool
941. 000000 0 0

HP NonStop SQL Programming Manual for TAL—527887-001


C-33
Examples of Dynamic NonStop SQL Programs Detailed Dynamic SQL Program

Page 24 [1] $VOL1.S04.TALDYN 1991-10-15 13:42:28


sql^warning^handler
943. 000000 0 0 PROC sql^warning^handler;
944. 000000 1 0 !******************************************************!
945. 000000 1 0 ! Displays an SQL warning.
946. 000000 1 0 !******************************************************!
947. 000000 1 0 BEGIN
948. 000000 1 1 PRINT^BLANK^LINE;
949. 000011 1 1 call SQLCADISPLAY (sqlca);
950. 000023 1 1 END;
951. 000000 0 0
Page 25 [1] $VOL1.S04.TALDYN 1991-10-15 13:42:28
memory^error^handler
953. 000000 0 0 PROC memory^error^handler(rollback^flag);
954. 000000 1 0 !******************************************************!
955. 000000 1 0 ! Prints a message and either terminates or returns.
Called !
956. 000000 1 0 ! on failure of memory allocation for SQLDAs or names
buffers. !
957. 000000 1 0 !******************************************************!
958. 000000 1 0 INT rollback^flag;! IN: 0--no ROLLBACK WORK, program
should stop.
959. 000000 1 0 ! 1--ROLLBACK WORK, program will re-enter
960. 000000 1 0 ! the input loop (outside this
procedure).
961. 000000 1 0 BEGIN
962. 000000 1 1 PRINT^BLANK^LINE;
963. 000011 1 1 PUT^STR^MID ("**** memory allocation failure *** ");
964. 000025 1 1
965. 000025 1 1 if rollback^flag then
966. 000027 1 1 EXEC SQL ROLLBACK WORK ! when we return from here, the
967. 000027 1 1 ! program re-enters the input
loop.
968. 000027 1 1 else
969. 000075 1 1 begin
970. 000075 1 2 PRINT^LINE;
971. 000110 1 2 PUT^STR (" Process stopped.");
972. 000126 1 2 PRINT^LINE;
973. 000141 1 2 PRINT^BLANK^LINE;
974. 000151 1 2 PUT^STR^MID ("End of current session");
975. 000165 1 2 PRINT^LINE;
976. 000200 1 2 call STOP;
977. 000205 1 2 end;
978. 000205 1 1 END;
979. 000000 0 0
980. 000000 0 0

HP NonStop SQL Programming Manual for TAL—527887-001


C-34
Examples of Dynamic NonStop SQL Programs Detailed Dynamic SQL Program

Page 26 [1] $VOL1.S04.TALDYN 1991-10-15 13:42:28


dyn^tal main procedure
982. 000000 0 0
983. 000000 0 0 ! Declare WHENEVER clauses for error checking on SQL
statements.
984. 000000 0 0 ! Note: Code that allocates memory and checks the input
query must
985. 000000 0 0 ! do separate error checking, because such code does not
involve
986. 000000 0 0 ! statements that set the SQLCODE variable.
987. 000000 0 0
988. 000000 0 0 ! Errors are handled at a label within the main
procedure because
989. 000000 0 0 ! the error handling code itself uses GO TO to return to
990. 000000 0 0 ! enter^input.
991. 000000 0 0 ! We use GO TO for errors because it makes the example
992. 000000 0 0 ! easier to read than the alternative (boolean variable
with
993. 000000 0 0 ! IF checking); however, using GO TO makes it necessary
to
994. 000000 0 0 ! put the WHENEVER clause here instead of in the global
variable
995. 000000 0 0 ! declarations, to avoid inserting an implicit GO TO in
code that
996. 000000 0 0 ! appears before sql^error^handler.
997. 000000 0 0
998. 000000 0 0 EXEC SQL WHENEVER SQLERROR GO TO :sql^error^handler;
999. 000000 0 0
1000. 000000 0 0 PROC dyn^tal MAIN;
1001. 000000 1 0
1002. 000000 1 0 !*****************************************************!
1003. 000000 1 0 ! PROC dyn^tal MAIN !
1004. 000000 1 0 ! Interactively reads SQL statements and dynamically
processes !
1005. 000000 1 0 ! them. Result is sent to the home terminal. !
1006. 000000 1 0 !*****************************************************!
1007. 000000 1 0
1008. 000000 1 0 BEGIN
1009. 000000 1 1 INT in^numvars; ! Number of parameters
1010. 000000 1 1 INT in^nameslen; ! Size of input names buffer
1011. 000000 1 1 INT out^numvars; ! Number of output columns
1012. 000000 1 1 INT out^nameslen; ! Size of output names buffer
1013. 000000 1 1 INT(32) num^fetches; ! count number of fetches per
query
1014. 000000 1 1 INT status;
1015. 000000 1 1 INT temp^sqlcode; ! Saves the value of SQLCODE for
later
1016. 000000 1 1 ! in cases where SQLCODE is set
to 0.
1017. 000000 1 1 ! See sql^error^handler at the end
1018. 000000 1 1 ! of this main procedure
1019. 000000 1 1
1020. 000000 1 1 INT rollback^flag; ! boolean for passing to memory-
1021. 000000 1 1 ! allocation error handler --
decides
1022. 000000 1 1 ! whether we want to re-enter the
1023. 000000 1 1 ! input loop or terminate the
program
1024. 000000 1 1
1025. 000000 1 1 rollback^flag := 0;! initialize to FALSE
1026. 000003 1 1
1027. 000003 1 1 CALL startup^and^define^pool;
1028. 000004 1 1
1029. 000004 1 1 @sbuf := $XADR(buf);
1030. 000010 1 1 @sda^i := @sda^o := NULL^ADDR;
1031. 000015 1 1 @cname^i := @cname^o := NULL^ADDR;
1032. 000022 1 1

HP NonStop SQL Programming Manual for TAL—527887-001


C-35
Examples of Dynamic NonStop SQL Programs Detailed Dynamic SQL Program

1033. 000022 1 1 PUT^STR ("This is DYNAMIC SQL test.");


1034. 000040 1 1 PRINT^LINE;
1035. 000053 1 1
1036. 000053 1 1 !*****************************************************!
1037. 000053 1 1 ! Input SQL query from terminal. !
1038. 000053 1 1 !*****************************************************!

Page 27 [1] $VOL1.S04.TALDYN 1991-10-15 13:42:28


dyn^tal main procedure
1039. 000053 1 1
1040. 000053 1 1 enter^input:
1041. 000053 1 1 !
1042. 000053 1 1 ! Free the memory taken by the sda^i, sda^o, cname^i,
and cname^o
1043. 000053 1 1 !
1044. 000053 1 1 call cleanup;
1045. 000054 1 1
1046. 000054 1 1 status := read^query ; ! READ^QUERY gets the SQL
statement and
1047. 000056 1 1 ! stores the statement in variable HOST1
1048. 000056 1 1
1049. 000056 1 1 if status < 0 then
1050. 000061 1 1 begin
1051. 000061 1 2 PRINT^BLANK^LINE;
1052. 000071 1 2 PUT^STR ("End of current session");
1053. 000107 1 2 PRINT^LINE;
1054. 000122 1 2 call STOP;
1055. 000127 1 2 end;
1056. 000127 1 1
1057. 000127 1 1 !*****************************************************!
1058. 000127 1 1 ! BEGIN TRANSACTION !
1059. 000127 1 1 !*****************************************************!
1060. 000127 1 1 EXEC SQL BEGIN WORK;
1061. 000200 1 1
1062. 000200 1 1 !*****************************************************!
1063. 000200 1 1 ! PREPARE the SQL statement !
1064. 000200 1 1 !*****************************************************!
1065. 000200 1 1
1066. 000200 1 1 EXEC SQL PREPARE s1 FROM :host1; ! HOST1 is a global
variable that
1067. 000271 1 1 ! contains the SQL statement obtained
1068. 000271 1 1 ! in READ^QUERY
1069. 000271 1 1
1070. 000271 1 1 ! Save the values of some useful SQLSA fields. We must
save these values
1071. 000271 1 1 ! because each SQL statement clears the SQLSA.
1072. 000271 1 1
1073. 000271 1 1 in^numvars := sqlsa.prepare.input^num;
1074. 000274 1 1 in^nameslen := sqlsa.prepare.input^names^len;
1075. 000277 1 1 out^numvars := sqlsa.prepare.output^num;
1076. 000302 1 1 out^nameslen := sqlsa.prepare.output^names^len;
1077. 000305 1 1
1078. 000305 1 1 !*****************************************************!
1079. 000305 1 1 ! Allocate input and output sqlda and names buffers. !
1080. 000305 1 1 !*****************************************************!
1081. 000305 1 1
1082. 000305 1 1 if in^numvars > 0 then
1083. 000310 1 1 begin
1084. 000310 1 2 @sda^i := allocate^sqlda (in^numvars);
1085. 000314 1 2 if @sda^i = NULL^ADDR then
1086. 000321 1 2 begin
1087. 000321 1 3 PUT^STR ("Input SQLDA ");
1088. 000337 1 3 call memory^error^handler(rollback^flag);
1089. 000342 1 3 end;
1090. 000342 1 2 end;
1091. 000342 1 1
1092. 000342 1 1 if out^numvars > 0 then

HP NonStop SQL Programming Manual for TAL—527887-001


C-36
Examples of Dynamic NonStop SQL Programs Detailed Dynamic SQL Program

1093. 000345 1 1 begin


1094. 000345 1 2 @sda^o := allocate^sqlda (out^numvars);
1095. 000351 1 2 if @sda^o = NULL^ADDR then

Page 28 [1] $VOL1.S04.TALDYN 1991-10-15 13:42:28


dyn^tal main procedure
1096. 000356 1 2 begin
1097. 000356 1 3 PUT^STR ("Output SQLDA ");
1098. 000376 1 3 call memory^error^handler(rollback^flag);
1099. 000401 1 3 end;
1100. 000401 1 2 end;
1101. 000401 1 1
1102. 000401 1 1 if in^nameslen > 0 then
1103. 000404 1 1 begin
1104. 000404 1 2 @cname^i := GETPOOL (pool^head, $DBL(in^nameslen));
1105. 000414 1 2 if <> then
1106. 000415 1 2 begin
1107. 000415 1 3 PUT^STR ("Input names buffer ");
1108. 000433 1 3 call memory^error^handler(rollback^flag);
1109. 000436 1 3 end;
1110. 000436 1 2 end;
1111. 000436 1 1
1112. 000436 1 1 if out^nameslen > 0 then
1113. 000441 1 1 begin
1114. 000441 1 2 @cname^o := GETPOOL (pool^head,
$DBL(out^nameslen));
1115. 000451 1 2 if <> then
1116. 000452 1 2 begin
1117. 000452 1 3 PUT^STR ("Output names buffer ");
1118. 000470 1 3 call memory^error^handler(rollback^flag);
1119. 000473 1 3 end;
1120. 000473 1 2 end;
1121. 000473 1 1
1122. 000473 1 1 !-----------------------------------------------
1123. 000473 1 1 ! Get information on input variables.
1124. 000473 1 1 !-----------------------------------------------
1125. 000473 1 1
1126. 000473 1 1 IF in^numvars > 0 THEN
1127. 000476 1 1 BEGIN
1128. 000476 1 2 EXEC SQL DESCRIBE INPUT s1 INTO :sda^i
1129. 000476 1 2 NAMES INTO :cname^i.val;
1130. 000557 1 2
1131. 000557 1 2 !-------------------------------------------------------!
1132. 000557 1 2 ! Initialize SQLDA var^ptr to point to input data
buffer. !
1133. 000557 1 2 ! Input parameter values from terminal. !
1134. 000557 1 2 !-------------------------------------------------------!
1135. 000557 1 2
1136. 000557 1 2 if setupvarbuffers(sda^i) then
1137. 000563 1 2 begin
1138. 000563 1 3 rollback^flag := 1;
1139. 000565 1 3 PUT^STR("Input parameter buffers ");
1140. 000603 1 3 call memory^error^handler(rollback^flag);
1141. 000606 1 3 goto enter^input;
1142. 000607 1 3 end;
1143. 000607 1 2
1144. 000607 1 2 if request^invars (sda^i, cname^i) then
1145. 000614 1 2 begin
1146. 000614 1 3 EXEC SQL ROLLBACK WORK;
1147. 000702 1 3 goto enter^input;
1148. 000703 1 3 end;
1149. 000703 1 2 END;

HP NonStop SQL Programming Manual for TAL—527887-001


C-37
Examples of Dynamic NonStop SQL Programs Detailed Dynamic SQL Program

1150. 000703 1 1
1151. 000703 1 1 !--------------------------------------!
1152. 000703 1 1 ! Get information on output variables. !

Page 29 [1] $VOL1.S04.TALDYN 1991-10-15 13:42:28


dyn^tal main procedure
1153. 000703 1 1 !--------------------------------------!
1154. 000703 1 1
1155. 000703 1 1 IF out^numvars > 0 THEN
1156. 000706 1 1 BEGIN
1157. 000706 1 2 EXEC SQL DESCRIBE s1 INTO :sda^o NAMES INTO
:cname^o.val;
1158. 001000 1 2
1159. 001000 1 2 !*******************************************************!
1160. 001000 1 2 ! Allocate output data buffers and update output SQLDA. !
1161. 001000 1 2 ! Initialize SQLDA var^ptr to point to output data buffers!
1162. 001000 1 2 !*******************************************************!
1163. 001000 1 2
1164. 001000 1 2 if setupvarbuffers(sda^o) then
1165. 001004 1 2 begin
1166. 001004 1 3 rollback^flag := 1;
1167. 001006 1 3 PUT^STR("Output buffers ");
1168. 001024 1 3 call memory^error^handler(rollback^flag);
1169. 001027 1 3 goto enter^input;
1170. 001030 1 3 end;
1171. 001030 1 2 END;
1172. 001030 1 1
1173. 001030 1 1 if out^numvars > 0 then
1174. 001033 1 1 begin
1175. 001033 1 2 !*****************************************************!
1176. 001033 1 2 ! SELECT statement !
1177. 001033 1 2 !*****************************************************!
1178. 001033 1 2
1179. 001033 1 2 !------------------------------------------------------
1180. 001033 1 2 ! Define a cursor name for the statement S1, to be
1181. 001033 1 2 ! used later in OPEN, FETCH, and CLOSE statements.
1182. 001033 1 2 !------------------------------------------------------
1183. 001033 1 2
1184. 001033 1 2 EXEC SQL DECLARE c1 CURSOR FOR s1;
1185. 001033 1 2
1186. 001033 1 2 !------------------------------------------------------
1187. 001033 1 2 ! Open the cursor. By this point, all input
1188. 001033 1 2 ! parameters must have valid values.
1189. 001033 1 2 !------------------------------------------------------
1190. 001033 1 2 IF in^numvars > 0 THEN
1191. 001036 1 2 EXEC SQL OPEN c1 USING DESCRIPTOR :sda^i
1192. 001036 1 2 ELSE
1193. 001122 1 2 EXEC SQL OPEN c1;
1194. 001201 1 2
1195. 001201 1 2 !*****************************************************!
1196. 001201 1 2 ! FETCH loop !
1197. 001201 1 2 !*****************************************************!
1198. 001201 1 2
1199. 001201 1 2 sqlcode := 0;
1200. 001203 1 2 num^fetches := 0D;

HP NonStop SQL Programming Manual for TAL—527887-001


C-38
Examples of Dynamic NonStop SQL Programs Detailed Dynamic SQL Program

Page 30 [1] $VOL1.S04.TALDYN 1991-10-15 13:42:28


dyn^tal main procedure
1210. 001267 1 3 begin
1211. 001267 1 4 PRINT^BLANK^LINE;
1212. 001277 1 4 PUT^STR ("--- ");
1213. 001315 1 4 PUT^DBL^MID (num^fetches);
1214. 001334 1 4 PUT^STR^MID (" row(s) selected.");
1215. 001350 1 4 PRINT^LINE;
1216. 001363 1 4 EXEC SQL CLOSE C1;
1217. 001435 1 4 EXEC SQL COMMIT WORK;
1218. 001506 1 4 goto enter^input;
1219. 001507 1 4 end;
1220. 001507 1 3
1221. 001507 1 3 ! Re-enable warning checking:
1222. 001507 1 3 EXEC SQL WHENEVER SQLWARNING CALL :sql^warning^handler;
1223. 001507 1 3
1224. 001507 1 3 CALL display^result (sda^o, cname^o); !Display one row
1225. 001513 1 3 num^fetches := num^fetches + 1D;
1226. 001517 1 3
1227. 001517 1 3 end; ! end WHILE loop
1228. 001520 1 2
1229. 001520 1 2 !*****************************************************!
1230. 001520 1 2 ! Not a SELECT statement. !
1231. 001520 1 2 ! EXECUTE the statement with USING DESCRIPTOR if there were
input !
1232. 001520 1 2 ! parameters; otherwise, EXECUTE the statement. !
1233. 001520 1 2 !*****************************************************!
1234. 001520 1 2
1235. 001520 1 2 IF in^numvars > 0 THEN
1236. 001523 1 2 EXEC SQL EXECUTE s1 USING DESCRIPTOR :sda^i
1237. 001523 1 2 ELSE
1238. 001601 1 2 EXEC SQL EXECUTE s1;
1239. 001664 1 2
1240. 001664 1 2 PRINT^BLANK^LINE;
1241. 001674 1 2 PUT^STR ("--- SQL Operation Complete.");
1242. 001715 1 2 PRINT^LINE;
1243. 001730 1 2 end;
1244. 001730 1 1
1245. 001730 1 1 EXEC SQL COMMIT WORK;
1246. 002001 1 1 goto enter^input; ! Get the next query
1247. 002002 1 1
1248. 002002 1 1
1249. 002002 1 1 sql^error^handler:
1250. 002002 1 1 !*****************************************************!
1251. 002002 1 1 ! The WHENEVER SQLERROR clause sends the program to this
code if an !
1252. 002002 1 1 ! SQL error is encountered. !
1253. 002002 1 1 !*****************************************************!
1254. 002002 1 1
1255. 002002 1 1 ! Save the value of SQLCODE. ROLLBACK WORK sets SQLCODE to
0.
1256. 002002 1 1 temp^sqlcode := sqlcode;
1257. 002004 1 1
1258. 002004 1 1 ! Disable WHENEVER checking to avoid an infinite loop if
an error
1259. 002004 1 1 ! should occur in this code. See discussion under WHENEVER
1260. 002004 1 1 ! in Section 3.
1261. 002004 1 1 EXEC SQL WHENEVER SQLERROR CONTINUE;
1262. 002004 1 1 PRINT^BLANK^LINE;
1263. 002014 1 1 call SQLCADISPLAY (sqlca);
1264. 002026 1 1 EXEC SQL ROLLBACK WORK;
1265. 002073 1 1 goto enter^input;
1266. 002104 1 1

HP NonStop SQL Programming Manual for TAL—527887-001


C-39
Examples of Dynamic NonStop SQL Programs Detailed Dynamic SQL Program

1201. 001205 1 2
1202. 001205 1 2 ! Disable SQL warning checking
1203. 001205 1 2 EXEC SQL WHENEVER SQLWARNING CONTINUE;
1204. 001205 1 2
1205. 001205 1 2 WHILE sqlcode >= 0 do ! continue fetching rows as
long as
1206. 001210 1 2 ! there are no errors or only warnings
1207. 001210 1 2 begin
1208. 001210 1 3 EXEC SQL FETCH c1 USING DESCRIPTOR :sda^o;
1209. 001264 1 3 if sqlcode = 100 then ! We've fetched all the rows

Page 31 [1] $VOL1.S04.TALDYN 1991-10-15 13:42:28


dyn^tal main procedure
1267. 002104 1 1 sqlcode := temp^sqlcode;
1268. 002106 1 1
1269. 002106 1 1 ! Re-enable WHENEVER checking:
1270. 002106 1 1 EXEC SQL WHENEVER SQLERROR GO TO :sql^error^handler;
1271. 002106 1 1
1272. 002106 1 1 END; !main

Page 32 [1] $VOL1.S04.TALDYN 1991-10-15 13:42:28


BINDER AND COMPILER STATISTICS
BINDER - OBJECT FILE BINDER - T9621C30 - (01NOV91) SYSTEM \SYS1
Copyright Tandem Computers Incorporated 1982-1989, 1991

Object file $VOL1.S04.TALD2O


TIMESTAMP 1991-10-15 13:42:28

5 Code pages

21 Primary data words


5365 Secondary data words
64 Data pages
0 Resident code pages
1 Extended data page

5386 Top of stack location in words


1 Code segment
0 Binder Warnings
0 Binder Errors

TAL - Transaction Application Language - T9250C30 - (01NOV91)


Number of compiler errors = 0
Number of unsuppressed compiler warnings = 0
Number of warnings suppressed by NOWARN = 0
Maximum symbol table space used was = 40902 bytes
Number of source lines = 4184
Compile cpu time = 00:00:08
Total Elapsed time = 00:00:38

HP NonStop SQL Programming Manual for TAL—527887-001


C-40
D NonStop SQL Version Issues
NonStop SQL release C30 includes features that are incompatible with NonStop SQL
release C10. Usually, these features provide compatibility with ANSI and ISO SQL
standards. This appendix describes these topics:
• Definitions of Version 1 (C10) and Version 2 (C30) catalogs and objects
• Changes in release C30 that are incompatible with release C10
• Migrating a release C10 program to:
° Run on a release C30 system

° Access Version 2 (C30) objects


• Installing migrated programs
• SQL component compatibility
• Programmatic features for handling version control
• Programming techniques for mixed versions
For more information about version issues for NonStop SQL release C10 and NonStop
SQL release C30, see the NonStop SQL Installation and Management Manual.

Version 1 and Version 2 Definitions


NonStop SQL associates a version number with each SQL feature and database
object. NonStop SQL uses this version number to determine whether it can support a
feature or an object. If it cannot support a feature or an object, NonStop SQL also uses
the version number to return an appropriate message. NonStop SQL Version 1 and
Version 2 features and objects are described in the following paragraphs.
The Version 2 data types are:
• FLOAT (includes REAL and DOUBLE PRECISION)
• DATETIME (includes DATE, TIME, and TIMESTAMP)
• INTERVAL
• UPSHIFT CHARACTER or VARCHAR
The Version 2 functions are:
• Exponentiation
• Date-time functions
• UPSHIFT function
The Version 2 features are:
• Version 2 data types and functions (shown above)

HP NonStop SQL Programming Manual for TAL—527887-001


D-1
NonStop SQL Version Issues Version 1 and Version 2 Definitions

• Columns that can contain null values


• Clustering keys
• Constraints with constants using any Version 2 feature
• NO AUDITCOMPRESS, HEADING, and HELP TEXT attributes
• UNION and JOIN clauses of the SELECT statement
Table D-1 shows the Version 2 entities and their descriptions.

Table D-1. Version 2 Items and Descriptions


Version 2 Entity Description
Table A table that uses any Version 2 feature.
Index An index that includes any column with a Version 2 data type or
that uses any Version 2 feature.
Protection or A view whose underlying table is a Version 2 table or whose
shorthand view selection expression includes a Version 2 feature such as a
Version 2 constant, or UNION or JOIN.
Object A Version 2 table, index, or view.
Catalog A catalog with release C30 format. It can be created by NonStop
SQL C30 software, or it can be created by C10 software and
then upgraded with the C30 UPGRADE CATALOG command.
Both Version 1 and Version 2 objects can be registered in a
Version 2 catalog.

Table D-2 shows the Version 1 entities and their descriptions.

Table D-2. Version 1 Items and Descriptions


Version 1 Entity Description
Object A table, index, or view that does not include any Version 2
features. NonStop SQL release C10 always creates Version 1
objects, but NonStop SQL release C30 can create Version 1 and
Version 2 objects.
Catalog A catalog with NonStop SQL release C10 format. Only Version 1
objects can be registered in a Version 1 catalog. However,
programs compiled by either the release C10 or C30 SQL
compiler can be registered in a Version 1 catalog.

To determine a version number, a program can call the SQLGETCATALOGVERSION,


SQLGETOBJECTVERSION, or SQLGETSYSTEMVERSION system procedure. The
procedures are described in Section 4, System Procedures
A Version 2 catalog has more columns and column values than a Version 1 catalog.
Table D-3 summarizes the new columns in Version 2 catalogs. For the column values,
see the NonStop SQL Installation and Management Manual.

HP NonStop SQL Programming Manual for TAL—527887-001


D-2
NonStop SQL Version Issues Summary of Incompatible Changes

Table D-3. Summary of New Columns in Version 2 Catalogs


Catalog Table/Column
Name Column Declaration Column Description
COLUMNS Catalog Table
DATETIMESTARTFIELD SMALLINT Date-time starting field
DATETIMEENDFIELD SMALLINT Date-time ending field
DATETIMEQUALIFIER VARCHAR (28) Date-time/INTERVAL field
UPSHIFT CHAR (1) Upshifted Y,N
HEADING CHAR (1) Heading Y,N
HEADINGTEXT VARCHAR (132) Heading text
FILES Catalog Table
AUDITCOMPRESS CHAR(1) Audit compression Y,N

Note. Object version and catalog version do not necessarily match the NonStop SQL release
version of the system where they reside. NonStop SQL C10 software can only create Version 1
objects and Version 1 catalogs. Version 1 objects and catalogs, however, can reside on both
NonStop SQL C10 and C30 systems. NonStop SQL C30 software creates only Version 2
catalogs and creates either Version 1 or 2 objects depending on the features used in the
objects.

Summary of Incompatible Changes


Table D-4 on page D-4 summarizes the NonStop SQL release C30 features that are
incompatible with NonStop SQL release C10. These features can affect programs
running in a mixed-version environment and C10 programs that are migrated to a C30
system. These features are described on subsequent pages in this section.

HP NonStop SQL Programming Manual for TAL—527887-001


D-3
NonStop SQL Version Issues Migrating a C10 Program to Run on a C30 System

Table D-4. Incompatible NonStop SQL Release C30 Features


C10 Program Operation Required Change
DDL statements that Explicitly include the NOT NULL and SYSTEM DEFAULT
create column definitions clauses in the CREATE TABLE or ALTER TABLE ADD
and omit the NOT NULL COLUMN statements to ensure the same column definition
clause or the SYSTEM produced by C10.
DEFAULT clause.
Programs that test for error Change the test for an empty set to a test for:
100 to determine if an
aggregate function (AVG,
• A NULL value (in this case, you must also supply a NULL
indicator variable).
MAX, MIN, or SUM)
returned an empty set. • Error 8423.
Programs that use new Change all names that use INNER, JOIN, or LEFT.
C30 reserved words
INNER, JOIN, and LEFT
as column names,
constraint names,
correlation names, cursor
names, or statement
names.
Programs that query To access Version 2 catalogs, change the queries affected by
catalog tables COLUMNS, new columns or new column information in these catalog
COMMENTS, and FILES. tables.
Static SQL programs that To access Version 2 tables or views that have Version 2 data
access tables. types, language compile and SQL compile to get internal
structures to handle the data.
To access Version 2 tables or views that allow null values,
add code to handle the possible null values.
Dynamic SQL programs To access Version 2 tables or views, initialize and use the
that initialize the SQLDA. release C30 SQLDA structure; add code to handle possible
null values.

Migrating a C10 Program to Run on a C30


System
The following NonStop SQL C30 enhancements can affect migrated C10 programs.
You need to be aware of these differences to develop programs that can run in a
mixed-version environment or to migrate a C10 program to a C30 system.
• Column definition
The default column definition has changed to allow null values. This change
applies to the CREATE TABLE and ALTER TABLE ADD COLUMN statements. The
C10 column defaults were SYSTEM DEFAULT and NOT NULL. The C30 column

HP NonStop SQL Programming Manual for TAL—527887-001


D-4
NonStop SQL Version Issues Migrating a C10 Program to Run on a C30 System

default is DEFAULT NULL. For example, these column definitions result in these
default definitions for the indicated release:
col1 CHAR(10)
Under C10: col1 CHAR(10) DEFAULT SYSTEM NOT NULL
Under C30: col1 CHAR(10) DEFAULT NULL NULL allowed
col2 CHAR(10) DEFAULT "XZ"
Under C10: col2 CHAR(10) DEFAULT "XZ" NOT NULL
Under C30: col2 CHAR(10) DEFAULT "XZ" NULL allowed
To ensure that tables created with C10 software retain their current definition if re-
created with C30 software, add the :
• NOT NULL clause to all CREATE TABLE column definitions if the clause is not
already included
• DEFAULT SYSTEM clause to all CREATE TABLE column definitions if a
DEFAULT clause is not already included
Make these changes to programs that create tables or to SQLCI OBEY command files
that create the tables that a migrated program uses. If you do not make these changes:
• NonStop SQL creates the tables as Version 2 tables, which are not accessible
from a C10 system.
• If null data is entered into the table and a program tries to retrieve a null value
without using an indicator variable, NonStop SQL returns error 8423.
• Result of aggregate functions
The result returned in a SELECT statement of the aggregate functions AVG, MAX,
MIN, or SUM operating on an empty set is NULL. To be ANSI compatible, this
result has changed from error 100 (no rows selected or modified) to NULL for
release C10.
To migrate programs that use the AVG, MAX, MIN, or SUM aggregate functions,
recode the programs to determine if a null value is returned. Consider using use
one of these methods:
• Check an indicator variable to handle a returned null value.
• Check for error 8423 as well as error 100 for the result of the aggregate
function. Error 8423 indicates that the query is attempting to return a null value
but there is no indicator variable along with the host variable to receive the null
value.
• New SQL reserved words for release C30 are INNER, JOIN, and LEFT.
Check for the use of these words as column names in tables or views or as
constraint names. Re-create any tables or views that use these names as column
names or constraint names.

HP NonStop SQL Programming Manual for TAL—527887-001


D-5
NonStop SQL Version Issues Migrating a C10 Program to Run on a C30 System

Check your programs for these words in SQL statements and change any that are
present as correlation names, cursor names, SQL statement names, and column
names. The TAL compiler detects the use of these reserved words and issues a
syntax error.

Caution. A table or view created with NonStop SQL C10 and having INNER, JOIN, or LEFT
as a column name or constraint name will not be available to an SQL program that references
these columns or constraints and is SQL compiled with the C30 SQL compiler. The SQL
compiler detects references to C30 reserved words and issues an error.

• Result of subqueries
If a subquery in a WHERE clause returns no rows, NULL is returned to the
subquery. To be ANSI compatible, this result has changed from error 100 (no rows
selected or modified) to NULL for the NonStop SQL C10 implementation.
For example, consider this SELECT statement from tables TABLE1 and TABLE2,
with the SELECT from TABLE2 being a subquery that returns no rows:
SELECT * FROM table1 WHERE a = (SELECT a FROM table2)
Because the subquery returns no rows, the WHERE clause is evaluated as equal
to NULL and fails. The evaluation is: WHERE a = NULL.
To migrate programs affected by the change in the result of subqueries, you do not
have to code extra checking in the program. Be aware, however, that C30
programs might retrieve more rows than C10 programs, because the C10
programs would have received error 100 (no rows selected or modified).
• Querying the NULLP value in the SQLDA structure
NULLP means null pointer. For C10, the system returns a system-defined value for
NULLP in the VAR^PTR field of the SQLDA structure if the names buffer is not
large enough.
A C30 system returns a negative value in the VAR^PTR field instead of NULLP.
Programs should check for a value less than zero instead of checking for NULLP.
NULLP is an internal constant and can change; therefore, its actual value is not
documented.
• Additional SQLDA fields
Using a C30 SQLDA structure is necessary only if the program might encounter null
values or the new C30 data types FLOAT, REAL, DOUBLE PRECISION, DATETIME,
DATE, TIME, TIMESTAMP, and INTERVAL. The SQLDA structure for C30 has
additional fields that can contain information about these new C30 features. You can
use a release C10 SQLDA on a C30 system if the program does not encounter these
C30 features.

Note. A program can sometimes encounter null values even if there are no null values in the
database.

HP NonStop SQL Programming Manual for TAL—527887-001


D-6
NonStop SQL Version Issues Migrating a C10 Program to Access Version 2
Objects

To use a C10 SQLDA structure, specify the RELEASE1 option either in the
INCLUDE SQLDA directive or in the SQL directive for the TAL compiler.

Migrating a C10 Program to Access Version 2


Objects
If a release C10 program needs to access Version 2 objects or catalogs, consider
these issues:
• Dynamic SQL operations
• Static SQL operations
• Catalog tables

Dynamic SQL Operations


Dynamic SQL programs use the SQLDA to specify input and output variables used in
dynamic SQL statements.
The release C30 SQLDA has a new field named PRECISION that supplies precision
information when a column of FLOAT, REAL, DOUBLE PRECISION, DATETIME,
DATE, TIME, TIMESTAMP, or INTERVAL data type is accessed. If the program
accesses columns of these data types, the program must provide a release C30
SQLDA structure. When the release C30 structure is provided, precision information is
also returned when columns of other data types are accessed.
In addition to the PRECISION field, two other significant changes have been made to
the release C30 SQLDA for null support:
• The NULL^INFO field, unused in the release C10 SQLDA, is now set to -1 if a null
value is allowed in the corresponding SELECT column. The value is allowed to be
null only if the column definition permits a null value.
• The RESERVED field has been renamed IND^PTR. The IND^PTR field is similar
to the VAR^PTR field, but is for the extended address of a null indicator variable.
The extended address is not returned by NonStop SQL; the program must initialize
IND^PTR to point to the input and output indicator variables that it has declared
and allocated.
Dynamic SQL programs accessing null values or Version 2 data types can either use
the INCLUDE SQLDA directive to generate an SQLDA structure or include the SQLDA
declaration code in the source file. Existing programs that include the SQLDA
declaration code must use the release C30 SQLDA structure to access columns with
Version 2 data types.
If program code initializes the SQLDA structure, the code must set the correct version
value in the SQLDA EYE^CATCHER field to match the SQLDA version. The value
“DA” indicates a release C10 SQLDA; the value “D1” indicates a release C30 SQLDA.

HP NonStop SQL Programming Manual for TAL—527887-001


D-7
NonStop SQL Version Issues Static SQL Operations

If the dynamic SQL program is designed to handle null values, the program must
allocate indicator variables and initialize the IND^PTR field in addition to the VAR^PTR
field. To migrate a C10 program to access columns defined to allow null values or use
Version 2 data types, you must TAL compile and SQL compile the program with
release C30 compilers.

Static SQL Operations


The SQLDA structure is generated automatically by the language compiler for static
SQL operations. The SQLDA has additional fields for C30 to accommodate new data
types. To migrate a C10 program to access columns defined with the new data types,
add code to manage null values and host variables for new data types. Then compile
the program with the C30 TAL compiler and the C30 SQL compiler.

Catalog Tables
The COLUMNS and FILES catalog tables have new columns in Version 2. To migrate
programs that query these catalog tables, you might need to recode to accommodate
the new columns. For the new columns, see Table D-3 on page D-3 earlier in this
appendix; for detailed information about the catalog tables, see the NonStop SQL
Installation and Management Manual.

Summary
Table D-5 summarizes the points in the preceding discussion.

Table D-5. Accessing Version 2 Objects from a C10 Program


Situation Action To Take
Dynamic SQL Generate a RELEASE2 SQLDA structure. If handling null
statements values, allocate indicator variables and initialize the IND^PTR
field for each SQLVAR entry in the SQLDA. TAL and SQL
compile with C30.
Static SQL statements Add code to manage null values and to manage host variables
for new data types. TAL and SQL compile with C30 software.
Statements that query If necessary, recode to accommodate new columns and new
catalog table COLUMNS column values. TAL and SQL compile with C30.
or FILES

Installing Migrated Programs


You can upgrade a release C10 system to release C30 system and continue executing
existing programs. The recommended procedure for installing programs includes SQL
compiling all SQL program object files with the C30 SQL compiler. SQL compilation
performs error checking for potential version problems.
The steps to install migrated programs are:

HP NonStop SQL Programming Manual for TAL—527887-001


D-8
NonStop SQL Version Issues SQL Component Compatibility

1. Alter all source program modules affected by incompatible C30 features.


2. TAL compile the programs that contain embedded SQL statements.
3. Bind object files if this step applies. Binding multiple C10 and C30 object files is
discussed later in this appendix.
4. Optionally, run the Accelerator on the object file generated from Step 2 or 3 if you
plan to run the object file on a TNS/R system.
5. SQL compile all SQL program object files with the C30 SQL compiler.
6. Install the program object file on the C30 system.

SQL Component Compatibility


All software on a system should be a single release version: either NonStop SQL
release C10 or NonStop SQL release C30. NonStop SQL installation procedures warn
against mixing SQL system components from different versions because of the risk of
unpredictable errors.
If NonStop SQL release C30 is installed on a network with NonStop SQL release C10
systems, all release C10 systems that are to communicate with the C30 systems must
be running the SQL C10 Versioning PVU (or any later PVUs that supersede the
Versioning PVU).
The Versioning PVU contains enhancements for handling compatibility between SQL
system components and SQL objects. The components and PVU numbers are listed in
the Table D-6.

Table D-6. Release C10 Versioning IPM Summary


Component Name IPM Numbers Component Identification
BACKUP/RESTORE T9074C10^06MAR89 T9074AAM
TSQL T9095C10^06MAR89 T9095AAG
TSQLCI T9191C10^06MAR89 T9191AAC
TSQLCOB T9192AAD^06MAR89 T9192AAD
TSQLEXE T9193C10^15MAR89 T9193AAF
TSQLCAT T9194C10^06MAR89 T9194AAD
TSQLUTI T9195C10^06MAR89 T9195AAD
TSQLMSG T9197C10^06MAR89 T9197AAC
TSQLCI2 T9198C10^06MAR89 T9198AAA
FASTSORT T9620C10^14FEB89 T9620AAB

HP NonStop SQL Programming Manual for TAL—527887-001


D-9
NonStop SQL Version Issues Developing C10 Programs with C30 Software

Note. For a node running the release C10 NonStop Kernel operating system with NonStop
SQL release C10, the above PVUs must be explicitly installed. For a node running the release
C20 NonStop Kernel operating system with NonStop SQL release C10, these PVUs are
included with the C20 Guardian software, except for the BACKUP/RESTORE PVU, which does
not apply.

Developing C10 Programs with C30 Software


In a network, different nodes are often running different versions of NonStop SQL. If
you are developing NonStop SQL release C10 programs using NonStop SQL release
C30 software, specify the RELEASE1 option of the SQL directive. The RELEASE1
option causes the C30 TAL compiler to generate code that can be SQL compiled and
executed on either a system running either NonStop SQL release C10 or NonStop
SQL release C30.
Programs compiled with the RELEASE1 option cannot use NonStop SQL release C30
features. The TAL compiler, however, does not make a check for the use of these
features. The use of NonStop SQL release C30 features is not detected until the
program is SQL compiled on a node running NonStop SQL release C10 software.
To ensure that a program using the RELEASE1 option is error free, SQL compile and
test the program on the NonStop SQL release C10 system where it will be installed. To
install a program on a NonStop SQL release C10 system, duplicate the program object
file on the C10 system and then SQL compile the program object file.
For more information about the RELEASE1 option of the SQL directive, see Section 3,
NonStop SQL Statements and Directives.

Binding C10 and C30 Object Files


Several object files that have been compiled by different versions of the TAL compiler
(C10 and C30) can be bound together as a single unit and then SQL compiled. The
resulting object file is assigned the version of the SQL compiler. This version
information is used internally by SQL software components.
To migrate existing C10 programs that consist of multiple object files bound together to
a C30 system, follow these steps:
1. Using the C30 TAL compiler, compile only the source program files that are
modified. Adding release C30 functionality to a single module of an existing
program does not require recompiling all source modules with the TAL compiler.
2. Bind all the object files.
3. SQL compile the resulting object file with the C30 SQL compiler.
Do not pass:
• C10 SQLDA structures from C10/C30 modules to C30 modules.
• C30 SQLDA structures from C10/C30 modules to C10 modules.

HP NonStop SQL Programming Manual for TAL—527887-001


D-10
NonStop SQL Version Issues Mixed-Version Programmatic Features

Mixed-Version Programmatic Features


The NonStop SQL programming interface provides several features to assist you in
developing programs to handle mixed versions. These features include release
specification options and procedures that report the version of various SQL objects.

Release Specification Options


Release specification options are available in the SQL directive. When a program
specifies the RELEASE1 or RELEASE2 option, the C30 host language compiler
generates code that is intended to be executed on a C10 or C30 system, respectively.
A program compiled with the RELEASE2 specification can be executed only on a C30
system. A program compiled with the RELEASE1 specification can be executed on a
C10 or C30 system because of upward compatibility.
Release specification options are also available in the INCLUDE SQLDA directive.
RELEASE1 and RELEASE2 options are valid.
By default, the generated SQLDA structure is compatible with the version of the TAL
compiler or the version specified in the SQL directive. You can, however, specify
another release version in the INCLUDE SQLDA directive. You can include two
INCLUDE SQLDA directives with each specifying a different release option as
appropriate for program logic. For the descriptions of the different SQLDA structures,
see the INCLUDE SQLDA directive in Section 6.

System Procedures
In a NonStop SQL mixed-version environment, a program might need to determine the
version of SQL objects. Use these procedures to determine version information:

SQLGETCATALOGVERSION
Returns a value that indicates the version of an SQL catalog.

SQLGETOBJECTVERSION
Returns a value that indicates the version of an SQL object. This value represents
the earliest SQL release that can perform all DML and most DDL operations
defined for a given SQL table, index, or view.

SQLGETSYSTEMVERSION
Returns a value that indicates the version of the SQL file system and disk process
components on a given system. All other NonStop SQL components are
considered to be the same version.
See Section 4, System Procedures, for the descriptions of these procedures.
For C10 programs to use these procedures, the program must include the procedure
declarations. For information about including the declarations, see the TSQLEXE

HP NonStop SQL Programming Manual for TAL—527887-001


D-11
NonStop SQL Version Issues Techniques for Mixed-Version Programming

(T9193C10^15MAR89, T9193AAF) component SOFTDOC for the C10 versioning


PVUs.
For C30 programs, external declarations for these procedures are included in the
EXTDECS system file for TAL programs.

Techniques for Mixed-Version Programming


A generic release program can run on multiple release levels of NonStop SQL and
handle Version 1 and Version 2 catalogs and objects. The techniques for developing a
generic release program is:
• Running on multiple NonStop SQL releases
• Handling mixed-version objects
• Using the single-code thread design

Handling Mixed-Version-Objects
Both generic release programs and programs that run only on NonStop SQL C30
systems can use these techniques to handle objects of mixed versions:
• Use the SQL system procedures to determine the NonStop SQL object version or
catalog version. Then, execute code depending on information returned by each
procedure.
• Include two sets of catalog queries if the program queries the catalogs and is
sensitive to the difference between Version 1 and Version 2 catalogs. Before
executing a catalog query, the program can use the SQLGETCATALOGVERSION
procedure to check the SQL catalog version. The program executes the
appropriate query depending on the catalog version. For example, if a program
wants to determine whether a user table contains date-time columns and the
attributes of those columns, the program must first determine whether the catalog
in which the table is registered is a Version 2 catalog.
• Check the version of an object before reading information from the catalog tables.
If the version of the object is unknown, do not try to read the catalog information.
Otherwise, you might encounter unknown column values.
• Consider querying the VERSIONS catalog table as an alternative test to determine
catalog version. The value of the VERSIONS column represents the catalog
version as follows:

° “A010” Version 1 catalog


° “A011” Version 2 catalog
• Check the catalog version before executing certain DDL statements. You must be
sure to register objects in Version 2 catalogs for these operations:
° Create Version 2 tables, views, indexes, or constraints

HP NonStop SQL Programming Manual for TAL—527887-001


D-12
NonStop SQL Version Issues Running on Multiple NonStop SQL Releases

° Create partitions for Version 2 tables or indexes

° Add a column that has a Version 2 data type


For the last operation, you would have to issue an error if the table intended to get the
new column was registered in a Version 1 catalog. For all of the above operations, the
system returns an error if a program attempts to register a Version 2 object in a Version
1 catalog.

Running on Multiple NonStop SQL Releases


Programs that run on multiple NonStop SQL releases and use Version 2 features
whenever possible must determine the SQL release level. Typically, these programs
handle objects of multiple versions by using dynamic SQL. Some coding techniques,
however, enable static SQL statements to handle multiple versions.
When developing generic release programs, you should consider these techniques:
• Maintain two code threads in a single set of source programs and use conditional
compilation to build two different object files depending on the version of the
NonStop SQL software release. This technique requires parallel build and release
cycles to install the program on nodes of different versions.
Advantages of this technique are:
° Dynamic SQL is not necessary.

° Program logic is simpler than in the single-code thread design.


• Maintain a single-code thread by using IF/THEN/ELSE statements in the source
program; the statements test for the appropriate SQL version and choose between
two code branches at run time. This technique contrasts with the two-code thread
technique by performing version checking at run time instead of at compile time;
the use of the single-code thread technique precludes the use of the two-code
thread technique.
Typically, the single-code thread technique uses dynamic SQL and can require
extensive mixed-version code. The resulting single object file, however, needs only
a single build and release cycle to install the program on nodes of different
versions.
• If you have a choice, use static SQL rather than dynamic SQL. Static SQL has
better performance than dynamic SQL because the SQL statements do not require
compilation at run time. Many generic release programs, however, require dynamic
SQL for other reasons.
• Include the SQLGETSYSTEMVERSION procedure in program code to test for
system version. Then determine which code to execute depending on the version.

HP NonStop SQL Programming Manual for TAL—527887-001


D-13
NonStop SQL Version Issues Using the Single-Code Thread Design

Using the Single-Code Thread Design


To develop a program that can run on a node running NonStop SQL release C10 and a
node running NonStop SQL release C30 software and use Version 2 features, follow
these steps:
1. In static SQL statements, do not use Version 2 features and objects. Static SQL
statements will be processed by both the release C10 and C30 SQL compilers.
2. Use Version 2 features and objects only in dynamic SQL statements.
In dynamic SQL operations, only the host variables that contain the SQL
statements are processed by the TAL compiler. The actual SQL statements are
represented as text in the host variables and therefore are not explicitly SQL
compiled.
3. For dynamic SQL statements:
• Generate both NonStop SQL release C10 and C30 SQLDA structures.
• When your program first begins executing (that is, before you issue an SQL
query), check the NonStop SQL software version using an SQL system
procedure. Then, depending on this version, initialize and use the appropriate
SQLDA structure.
• Ensure that a dynamic SQL statement that uses VersionÊ2 features executes
only within a code branch that handles VersionÊ2 features. For example:
IF sw^version = version^2 THEN
host^var ':=' "SELECT * FROM t1 UNION SELECT * FROM t2"
ELSE
host^var ':=' "SELECT * FROM t1";
EXEC SQL PREPARE statement FROM :host^var;
4. Compile your TAL source statements using a release C30 TAL compiler. Specify
the SQL directive with the RELEASE1 option as the first line of your primary
source file or in the RUN command line for the TAL compiler.
The RELEASE1 option causes the TAL compiler to generate release C10 SQLDA
structures and object code that is compatible with both the release C10 and C30
SQL compilers. (Object code and structures generated with the RELEASE2 option
are not compatible with the release C10 SQL compiler.)
5. SQL compile and distribute the program for installation and use on production
nodes as follows:
• For C30 nodes, SQL compile and test the program on a C30 node and then
distribute the program object file to any other C30 nodes.
• For C10 nodes, SQL compile and test the program on a C10 node and then
distribute the program object file to any other C10 nodes.

HP NonStop SQL Programming Manual for TAL—527887-001


D-14
NonStop SQL Version Issues Using the Single-Code Thread Design

Figure D-1. Developing a Program For Mixed-Version Nodes

Node \DEVEL – Development Node

Release C30 NonStop SQL System


Release C30 TAL Compiler (RELEASE1 Option)

Node \PRODR1 – Production Node 1

Release C10 NonStop SQL System


Release C10 NonStop SQL Compiler

Node \PRODR2 – Production Node 2

Release C30 NonStop SQL System


Release C30 NonStop SQL Compiler
VSTD01.vsd

HP NonStop SQL Programming Manual for TAL—527887-001


D-15
NonStop SQL Version Issues Using the Single-Code Thread Design

HP NonStop SQL Programming Manual for TAL—527887-001


D-16
E Enforcing Data Integrity
Data integrity requires that certain data conditions must be true within a database.
Examples of these conditions are:
• Data format, such as numeric only
• Value ranges, such as between 500 and 1000
• A relationship between items within a row
• A relationship between items in different rows of a table or between rows in
different tables (Referential Integrity)
The data format is controlled by the data type definition in the CREATE TABLE
statement. NonStop SQL implicitly checks the data type whenever data is added to or
updated in a table. For example, if a column is defined as numeric, the insertion of a
character string is not allowed.
Value ranges and relationships with other columns within the same row are controlled
by constraints. (See Using Constraints on page E-1.)
A relationship between items in different rows of a table or between rows in different
tables is called referential integrity. You can include code in your program to enforce
referential integrity.
For example, two tables exist and contain data about employees and work
departments. Inconsistencies can be introduced through coding errors, or through
operations performed with SQLCI. For example, the program should not delete a
department from the DEPT table if any row in the EMPLOYEE table refers to that
department. You should check for such inconsistencies. (See “Managing Referential
Integrity on page E-2.)

Note. Logical operations, such as checking for referential integrity, should be performed within
a TMF transaction in order to ensure consistency. If the referential integrity constraint is not
satisfied, the transaction can be rolled back.

Using Constraints
NonStop SQL supports constraints to protect the integrity of base tables. A constraint
is a condition that must be met before data is added to a row in the base table to which
the condition applies.
NonStop SQL ensures that all modifications to rows satisfy all current constraints. This
means that you cannot add a row or change a row when the new data does not meet
the constraint specification. A new constraint is disallowed if any rows currently in the
table do not satisfy it.
You can create or drop constraints at any time. Creating or dropping a constraint,
however, causes the system to invalidate all SQL program files that use the underlying

HP NonStop SQL Programming Manual for TAL—527887-001


E-1
Enforcing Data Integrity Managing Referential Integrity

table. You should ensure that these files are explicitly SQL compiled to avoid automatic
recompilation every time a program runs.

Note. When you add a constraint, NonStop SQL checks all rows in the table. For large tables,
the CREATE CONSTRAINT operation might run for a long time.

Constraints are also a replacement for program code; they operate for all programs
that refer to a table to which constraints apply. For example, constraints can be used to
establish value ranges for columns, true or false conditions, and so forth.
Consider this example:
CREATE CONSTRAINT MGRNUM_CONST
ON DEPT
CHECK MANAGER BETWEEN 0001 AND 5000 ;
This constraint on the DEPT table restricts the value of the column MANAGER to the
range shown. Your programs do not have to check the value for each insertion or
update to this table. SQL ensures the value is within the range. If the value is not within
the range, SQL returns an error message and aborts any current TMF transaction. This
is a database protection mechanism. When constraints exist, programs do not have to
perform such checks to avoid corrupting the database.
This example illustrates a constraint that examines two columns within the same row:
CREATE CONSTRAINT VALIDATE_CONST
ON EMPLOYEE
CHECK TERM_DATE >= HIRE_DATE ;
This constraint ensures that the employee termination date is equal to or greater than
the date of hire.

Managing Referential Integrity


Referential integrity is a user test to ensure that any foreign key values that exist in a
table also exist as primary key values in the same or another table. A foreign key is a
column in a table that is a primary key in that table or in another table. The rule for
referential integrity is that every foreign key value must have a corresponding primary
key value.
You can check for referential integrity through a program or with SQLCI.
These examples use SQLCI to illustrate methods for checking and maintaining
referential integrity.

HP NonStop SQL Programming Manual for TAL—527887-001


E-2
Enforcing Data Integrity Managing Referential Integrity

Referential Integrity: Example 1


In this example, every department must report to another valid department in the table.
To verify this rule, you can use this SELECT statement to check the DEPT table:
SELECT DEPTNUM, RPTDEPT
FROM DEPT
WHERE RPTDEPT
NOT IN (SELECT DEPTNUM FROM DEPT) ;
The query returns this result:
DEPTNUM RPTDEPT
------- -------
--- 0 row(s) selected.
The absence of selected rows indicates the integrity of the database is intact. If any
department contained an invalid report-to department, it would have been selected and
shown, for example, as:
DEPTNUM RPTDEPT
------- -------
1320 999
--- 1 row(s) selected.
Such an error could be corrected with this statement:
UPDATE DEPT SET RPTDEPT = 1120
WHERE DEPTNUM = 1320;
--- 1 row(s) updated.
Repeating the previous SELECT verifies the correction.

Referential Integrity: Example 2


In this example, the CLASS table has a primary key of CLASSNUM and a foreign key
of CLASS_COURSE--each class is one offering of the course. The COURSE table has
a primary key of COURSENUM. This code determines whether each class row does
indeed point to a valid course:
SELECT CLASSNUM, CLASS_COURSE
FROM CLASS
WHERE CLASS_COURSE
NOT IN (SELECT COURSENUM FROM COURSE) ;

HP NonStop SQL Programming Manual for TAL—527887-001


E-3
Enforcing Data Integrity Managing Referential Integrity

The query returns this result:


CLASSNUM CLASS_COURSE
-------- ------------
--- 0 row(s) selected.
The result of zero rows selected indicates that each class points to a valid course. The
result does not prove that the class points to the correct course.

HP NonStop SQL Programming Manual for TAL—527887-001


E-4
Index
A Automatic SQL recompilation (continued)
performance considerations 5-24
Accelerator predicting 5-24
effect on SQL validity 5-22
AVG function
running on object file 1-7, 5-5, D-9 for C10 program migration D-5
using SQL object file for 5-12
Access path
EXPLAIN utility 5-18
B
local autonomy 5-28 BACKUP/RESTORE program
RECOMPILE option 5-9 version issues D-9
SQL compiler function 5-5 BEGIN DECLARE SECTION Directive,
SQL 3-6
unavailable 5-26
BEGIN DECLARE SECTION directive,
using EXPLAIN with 5-17 SQL 1-3, 2-2
valid programs 5-22 BEGIN WORK statement, SQL 7-13
Access privileges Binder program 1-7, 5-12
for SQL compiler 5-10 ADD command 5-5
ADD Command, Binder 5-5 binding mixed-version object files D-11
ADD DEFINE command, TACL 5-19 binding object files 5-4
Aggregate functions BUILD command 5-5
for C10 program migration D-5 effect on SQL validity 5-22
using in a program 6-7 SELECT command 5-5
ALLOCATESEGMENT system STRIP command 5-4
procedure 3-41
using with TALLIB 5-4
Allocating memory
BINSERV
for indicator variables 7-37
option in PARAM command 5-13
Altering SQL file attribute, effect of 5-23
process 7-8
ANYWHERE clause
with INSERT statement 3-20 BROWSE ACCESS clause
with SELECT statement 3-32
APPEND clause
with INSERT statement 3-20 BUILD command, Binder 5-5
Array as host variable 2-11
ASSIGN command, TACL C
for SQL program file 5-30 C programming language 1-1
Attributes, SQL file C10 program, migrating to C30 D-4
effect of altering 5-23 C30 features, migrating program for D-3
Authority CALL format of WHENEVER 6-7
for program file execution 5-30 CATALOG clause
Automatic SQL recompilation for SQL compiler 5-7
functions of 5-24 CATALOG TACL DEFINE 5-7

HP NonStop SQL Programming Manual for TAL—527887-001


Index-1
Index C

Catalog, SQL Conversational interface, NonStop SQL 1-1


access for program file execution 5-7 CONVERTTIMESTAMP SQL function 3-22
handling mixed versions D-12 CONVERTTIMESTAMP system
version 1 D-2 procedure 3-22
version 2 D-2, D-8 Copying SQL files, effect on SQL
validity 5-22
with CREATE INDEX statement, SQL 5-23
SQLGETCATALOGVERSION 4-19
CREATE TABLE statement, SQL 2-20, 7-2
Circumflex (^)
version compatibility D-4
in host variable names 2-2
CURRENTDEFINES option, SQL
CLOSE statement, SQL 3-7, 3-8, 3-34 compiler 5-7
CLOSE system procedure 1-3 Cursor
COBOL85 programming language 1-1 CLOSE statement 3-7
Colon (:) with host variable 1-3 closing for dynamic SQL 7-13
Colon(:) with host variable 2-6 declaration 3-11
COLUMNS catalog tables
DECLARE CURSOR statement,
version 2 features D-8 SQL 3-11
Column, SQL declaring for dynamic SQL 7-12
definition for versions D-4 deleting 3-15
for C10 program migration D-4 dynamic 3-16
Comments, in SQL statements 3-2 dynamic CLOSE 3-16
COMMIT WORK statement, SQL 7-14
dynamic OPEN 3-29
Compatibility of SQL components D-9
dynamic operation 3-30
Compiler directives
FETCH statement 3-18, 3-29
for TAL compiler 5-4
guidelines for using 3-45
Compiling
automatic SQL recompilation 5-24 in SELECT statement 3-34
dynamic SQL statements 5-14 initializing WHERE variable 3-33
explicit SQL 5-10 opening for dynamic SQL 7-13
TAL program 1-7, 5-2 static 3-7
Components, SQL static CLOSE 3-7
version compatibility of D-9 static OPEN 3-29
Compound TAL statement 3-2 UPDATE WHERE CURRENT
statement, SQL 3-45
Constraints
changes and program file validity 5-22 using with dynamic SQL 7-31
creating E-1 when to close 3-35
using for data integrity E-1 when to initialize 3-35
CONTROL directives 3-8 with OPEN statement 3-29
CONTROL EXECUTOR directive, SQL 3-9
CONTROL QUERY directive, SQL 3-10
CONTROL TABLE directive, SQL 3-10

HP NonStop SQL Programming Manual for TAL—527887-001


Index-2
Index D

D DATAPAGES directive, TAL compiler 7-8


DATA^LEN field
Data in SQLDA structure 7-5
advantages of NonStop SQL 1-1 literals for 6-19
conversion between SQL and TAL 2-4 DATA^TYPE field
enforcing integrity E-1 in SQLDA structure 7-5
using INSERT statement with 3-19 literals for 6-18
using SELECT statement with 3-31 DATEFORMAT clause 2-17
Data Control Language (DCL) SQL with INVOKE directive 3-24
statements 1-2
Date-time
Data declarations
data types for 2-4
BEGIN DECLARE SECTION directive,
SQL 3-6 data types for host variables 2-15
END DECLARE SECTION directive, literals for 6-19
SQL 3-6 static SQL example B-10
tables and views 3-22 Debugging
Data Definition Language (DDL) SQL using SQLCOMP FORCE option 5-8,
statements 1-2 5-14
Data Manipulation Language (DML) SQL with RUND command 5-30
statements 1-2 DECLARE CURSOR statement, SQL 3-11
Data structures, SQL Declare Section 2-2
placing in memory 3-37 declaration 3-6
Data types multiple use 2-2
conversion between SQL and TAL 2-4 Declare section 1-3
correspondence (SQL and TAL) 2-2 DEFAULT clause, version
date-INTERVAL 2-11 incompatibility D-4
date-time 2-4, 2-11 DEFAULT SYSTEM clause
default for dynamic SQL for C10 program migration D-4
parameters 2-26 DEFINEPOOL system procedure 7-17
FIXED 2-13 DEFINES option
INTERVAL 2-4 for EXPLAIN utility 5-8
literal declarations for 7-21 for SQL compiler 5-8
mapping DEFINEs, TACL
with INVOKE 2-20, 3-23 EXPLAIN report format 5-18
overriding default types 2-5 for automatic SQL recompilation 5-25
SQL 2-2 for catalog name 5-7
TAL 2-2 for SQL compilation 5-15
version compatibility D-1 for SQL program execution 5-32
Database, NonStop SQL for SQL program file 5-30
sample A-2 in sample program C-1, C-10
using embedded SQL 1-1 propagating 5-32

HP NonStop SQL Programming Manual for TAL—527887-001


Index-3
Index E

DEFINEs, TACL (continued) Dynamic SQL operations (continued)


set by RECOMPILE option 5-9 getting information about 6-13
using for SQL compilation 5-8 overview 7-1
using to maximize local autonomy 5-28 programming techniques 7-7
using with INSERT statement 3-20 sample program C-1, C-9
using with SQL compiler 5-32 single-code thread design for D-14
using with TAL compiler 5-31 specifying input parameters 7-4
DEFINE, TAL declaration 3-2 specifying output parameters 7-4
DEFMODE option, TACL 5-32 SQLDA version format D-14
Delete operation using a parameter 2-23
multiple rows 3-14 using a parameter list 2-24
set of rows 3-15 using DESCRIBE and DESCRIBE
single row 3-14 INPUT 3-16
DELETE statement, SQL 3-13 using EXECUTE IMMEDIATE 3-18
DESCRIBE INPUT statement, SQL 3-16 version issues D-7
DESCRIBE statement, SQL 3-16 writing a Pathway server 7-3
DETAIL option, FILEINFO command 5-22
Directives
BEGIN DECLARE SECTION 3-6
E
END DECLARE SECTION 3-6 ELSE TAL keyword in SQL statements 3-1
Embedded SQL statements
NonStop SQL
advantages 1-1
table of 1-3
in TAL source file 1-2, 3-1, 3-2
TAL compiler 5-4
END DECLARE SECTION directive,
Disk process (DP2) 4-3, 4-9, 4-14 SQL 1-3, 2-2, 3-6
Distributed database, maximizing local End of line, in SQL statement 3-2
autonomy 5-28
END TAL keyword in SQL statements 1-2
DROP statement, SQL 3-17
Enscribe database
DUPLICATE command, FUP 5-22
data file for 2-13
Duplicating SQL files, effect on SQL
validity 5-22 memory use by program 5-32
Dynamic memory allocation 7-14 utilities protection for SQL objects 5-22
Dynamic operations Equivalenced local structure as host
SQL compilation 5-14 variable 2-12
Dynamic SQL operations Error processing
applications for 7-2 using SQL procedures for 4-1
compilation 5-14 using SQLCODE for 6-1
conversational interface for 7-2 using WHENEVER for 6-4
declaring the names buffer 7-5 Errors and error messages
for DELETE statement 3-13
declaring the SQLDA 7-5
for FETCH statement 3-18
description 1-5
for INSERT statement 3-19

HP NonStop SQL Programming Manual for TAL—527887-001


Index-4
Index F

Errors and error messages (continued) File number


for UPDATE statement 3-42 of SQLMSG file 4-3, 4-15
run-time SQL recompilation 5-28 FILEINFO command
SQL compiler 5-14 FUP 5-22
Example programs SQLCI 5-22
static program B-10 FILEINQUIRE system procedure 4-1
static SQL program B-1 FILES catalog tables
Exclamation point (!) for TAL comments 3-2 version 2 features D-8
EXEC SQL keywords 1-2, 3-1 File-system errors 2-4
EXECUTE IMMEDIATE statement, displaying
SQL 1-5, 3-18 with SQLCADISPLAY 4-2
EXECUTE statement, SQL 1-5, 3-18, 7-13 with SQLCAFSCODE 4-7
Executing a TAL program 1-7 with SQLCAGETINFOLIST 4-8
Execution plan with SQLCATOBUFFER 4-13
EXPLAIN report 5-18
First error flag
optimized by SQL compiler 5-11 in SQLCAFSCODE procedure 4-8
optimized by statistics 5-11 FIXED TAL data type
SQL compiler function 5-11 in TYPE AS clause 2-7
EXPLAIN option, SQL compiler 5-5 with host variable 2-12
EXPLAIN report with SETSCALE SQL function 3-21
execution plan 5-18
FOR UPDATE OF clause
query decomposition 5-17 UPDATE statement 3-45
Explicit SQL compilation 1-7, 5-4 FORCE option
EXT option, SQLMEM directive 3-38 error messages with 5-14
EXTDECS file 1-3, 3-22, 3-39, 4-1, 7-3
SQL compiler 5-8
Extended data segment
FREE RESOURCES statement
estimating memory for 5-32
and cursors 3-35
managing 3-42
Functions, aggregate, SQL
specifying the default 3-38
for C10 program migration D-5
EYE^CATCHER field in SQLDA,
initializing 6-18, 7-6, 7-18 FUP
DUPLICATE command 5-22
FILEINFO command 5-22
F
FASTSORT program 4-2, 4-8, 4-14
FETCH statement, SQL 3-34, 7-5
G
Fields in structures as host variables 2-8 Generic release program
File attributes, SQL description of D-12
effect of altering 5-23 GETPOOL system procedure 7-10, 7-17
File label Global area, user 3-38
SQL program file validation 5-22 GOTO format of WHENEVER 6-7

HP NonStop SQL Programming Manual for TAL—527887-001


Index-5
Index H

Guardian 90 operating system 4-2, 4-7, INCLUDE SQLSA directive 3-19, 6-11, 7-8
4-8, 4-14 Incompatible features
C10 description D-4
H C30 enhancements D-1
HEADING attribute 4-20 Index, SQL
HELP TEXT attribute 4-20 changes and program file validity 5-23
Host variable version 2 D-2
array as 2-11 INDICATOR clause
associated indicator variable for 2-13 in SETSCALE function 2-13
creating with INVOKE 2-20 with host variable 2-7
date-time data types as 2-15 Indicator parameter
declaration of 1-3, 3-6 function 2-25
declaring 2-2 in names buffer 7-38
fields in a structure as 2-8 syntax for 2-23
in expressions 2-2 Indicator variable
INDICATOR clause 2-7 allocating memory for 7-37
initializing in cursor 3-35 using for null value 2-17
INTERVAL data types as 2-15 with aggregate function 6-7
multiple DECLARE sections for 2-2 with host variable 2-7
naming conventions 2-2 with INVOKE directive 3-27
null values in 2-7 IND^PTR field
pointer as 2-9 in SQLDA structure 7-5
scale in 2-12 IND^PTR, initializing 7-18
string parameter as 2-11 Initializing a cursor 3-35
INNER function
structure as 2-8
reserved word for C30 D-5
syntax for using 2-7
Input host variable
TYPE AS clause 2-7
with DESCRIBE and DESCRIBE
type STRING array as 2-10 INPUT 3-16
using colon (:) with 1-3 Input parameter
using INSERT with 3-19 for dynamic SQL operations 7-4, 7-10
with DELETE statement 3-13 Insert operation
HP NonStop Transaction Management timestamp value 3-21
Facility (TMF) 1-1, 7-13
with a null value 3-20
Hyphen, double (--) for SQL comments 3-2
INSERT statement, SQL 3-19
Insertion program, static SQL B-1
I Installing migrated programs D-8
INCLUDE SQLCA directive 3-19, 4-2, 6-9, INT (32) TAL data type
7-8 with SETSCALE SQL function 3-21
INCLUDE SQLDA directive 3-19, 6-14

HP NonStop SQL Programming Manual for TAL—527887-001


Index-6
Index J

INTERVAL data types Local autonomy


conversion of 2-4 maximizing for distributed
inserting 2-16, 3-26 database 5-28
literals for 6-19 program execution 5-24
selecting 3-25 program file validity 5-23
with INVOKE directive 3-24 skipping unavailable partitions to
INTO clause maximize 5-28
with SELECT command 3-32 using current statistics 5-29
INVALIDATE option, CREATE INDEX using TACL DEFINEs 5-29
statement 5-23 Local partition
INVOKE directive, SQL 2-8, 2-17, 2-20, using to maximize local autonomy 5-28
3-22, A-1 Loops, infinite
Item codes avoiding with WHENEVER 6-5
for SQLCAGETINFOLIST (table) 4-10
SQLCAGETINFOLIST parameter 4-8
M
MAPPED option, SQLMEM directive 3-39
J Measure program 3-37
JOIN function Memory management
for C10 program migration D-4 dynamic allocation 7-14
reserved word for C30 D-5 estimating use 5-32
JULIANTIMESTAMP system using SQLMEM directive 3-37
procedure 3-22 Migration, C10 program to C30 D-4
Modifying data
L DELETE statement 3-13
LEFT function UPDATE statement 3-43
for C10 program migration D-4 MOVEX system procedure 3-39
reserved word for C30 D-5 Moving SQL files, effect on SQL
Library procedures, system 1-3 validity 5-22
List file MULTILAN
SQL compiler 5-6 with dynamic SQL programs 7-2
TAL compiler 5-3 Multiple SQL releases
Listing, SQL compiler 5-15 running program on D-13
Literal declarations Multi-row
for data types 7-21 delete 3-14
for DATA^TYPE field 6-18 retrieval 3-33
for date-time values 6-19 update 3-44
for INTERVAL data types 6-19
for PRECISION field 6-18 N
SQLDA^EYE^CATCHER 6-18 Names buffer
Load time, SQL 5-25 and indicator parameters 7-38

HP NonStop SQL Programming Manual for TAL—527887-001


Index-7
Index N

Names buffer (continued) NonStop SQL statements (continued)


declaring for dynamic SQL 7-8 CREATE TABLE 2-20, 7-2
estimating size of 7-15 DECLARE CURSOR 3-11
for dynamic SQL 7-23 DELETE 3-13
using with a parameter 2-25 DESCRIBE 3-16
NAMES INTO clause DESCRIBE INPUT 3-16
of DESCRIBE INPUT statement 7-23 DROP 3-17
NEWPROCESS system procedure 5-30 dynamically preparing 3-30
NO AUDITCOMPRESS attribute 4-20 EXECUTE 1-5, 3-18, 7-13
NO INVALIDATE option, CREATE INDEX EXECUTE IMMEDIATE 1-5, 3-18
statement 5-23
FETCH 3-18
NOEXPLAIN option, SQL compiler 5-9
INSERT 3-19, 3-26
NOFORCE option, SQL compiler 5-8
locating information about 3-4
NonStop SQL database
overview 1-1 OPEN 3-29, 3-34
sample of A-1 placing in source file 3-2
using embedded SQL for 1-1 PREPARE 3-30, 7-10, 7-15
NonStop SQL directives RELEASE 3-31
BEGIN DECLARE SECTION 1-3, 2-2 SELECT 2-15, 3-25, 3-31
coding of 3-1 table of 1-2, 3-4
comments in 3-2 UPDATE 3-42
CONTROL EXECUTOR 3-8 UPDATE STATISTICS 5-11, 5-14,
5-23, 5-29
CONTROL QUERY 3-8
WHENEVER 7-9
CONTROL TABLE 3-8
NonStop SQL system procedures
END DECLARE SECTION 1-3, 2-2
SQLCADISPLAY 1-3, 2-4, 4-2, 6-9
INCLUDE SQLCA 3-19, 4-22, 6-9, 7-8
SQLCAFSCODE 4-7, 6-9
INCLUDE SQLDA 3-19, 6-14
SQLCAGETINFOLIST 4-8, 6-9
INCLUDE SQLSA 3-19, 6-10, 7-8
SQLCATOBUFFER 4-13, 6-9
INVOKE 2-8, 2-17, 2-20, 3-22, A-1
SQLGETCATALOGVERSION 4-19,
locating information about 3-4 D-11
placing in source file 3-2 SQLGETOBJECTVERSION 4-19, D-11
table of 1-3, 3-4 SQLGETSYSTEMVERSION 4-21,
WHENEVER 6-4 D-11
NonStop SQL statements SQLSADISPLAY 4-22
BEGIN WORK 7-13 table of 4-1
CLOSE 3-7, 3-34 NOOBJECT option, SQL compiler 5-9
coding of 3-2 NORECOMPILE option, SQL
comments in 3-2 compiler 5-10, 5-24
COMMIT WORK 7-14 NOSQLMAP option, SQL directive 3-37
CREATE INDEX 5-23 Not found condition, WHENEVER 6-4

HP NonStop SQL Programming Manual for TAL—527887-001


Index-8
Index O

NOT NULL clause Object file (continued)


and version incompatibility D-4 handling mixed versions D-12
for C10 program migration D-4 in TACL RUN command 5-3
NOWHENEVERLIST option, SQL running Accelerator on 5-12
directive 3-36 SQL compilation of 5-32
NULL keyword SQL file format of 5-12
with INSERT statement 2-18, 3-47 validation for 5-22
with UPDATE statement 3-47 OBJECT option, SQL compiler 5-9
Null keyword Object, SQL
with INVOKE directive 2-17 changes and program file validity 5-23
NULL STRUCTURE clause handling mixed versions D-12
with INVOKE directive 3-27 using DROP for 3-17
Null values version 1 D-2
handling 7-36
version 2 D-2
handling for dynamic SQL 7-13
OPEN statement, SQL 3-29
in host variable 2-17 Open statement, SQL 3-34
in input parameters 7-36 OPEN system procedure 7-3
in names buffer 7-38 Open tables, SQL 5-25
in output variables 7-38 Optimized execution plan
version incompatibility D-3 EXPLAIN PLAN report 5-18
with a parameter 2-26 SQL compiler function 5-11
with INSERT statement 3-20 statistics requirement 5-11
with INVOKE directive 3-26, 3-27 OUT file
with UPDATE statement 3-47 SQL compiler 5-7
NULL^INFO field TAL compiler 5-3
in SQLDA structure 7-5 Output host variable
valid and invalid forms 2-1
O Output variable
OBEY command file allocating space for 7-27
for running TAL compiler 5-3 displaying 7-27
format for EXPLAIN report 5-19 handling for dynamic SQL 7-11
SQLCI D-5 specifying for dynamic SQL
operations 7-4
OBEYFORM option
Override data types
for EXPLAIN report 5-18
generated by INVOKE 3-23
for SQL compiler 5-9
INVOKE generated 2-20
Object file
syntax for 2-5
binding using Binder program 5-4
table 2-6
for SQL compiler 5-6
for TAL compiler 5-3

HP NonStop SQL Programming Manual for TAL—527887-001


Index-9
Index P

P Program development, TAL (continued)


using Version 2 features for C10
PAGES option, SQL directive 3-36 program D-8
Pages, allocation of 5-34 Program execution
PARAM command, TACL for SQL program file 5-30
for SQL program file 5-30 using TACL DEFINEs 5-31
with SQL compiler 5-13 Program size, estimating 5-32
Parameters, TACL PROGRAMS tables 5-10
in RUN command for SQL object Program, dynamic SQL example C-1
file 5-30 Program, TAL
Parameter, SQL using embedded SQL 1-2
dynamic SQL default data types 2-26 Propagating TACL DEFINEs 5-32
in dynamic SQL operations 2-23 PUTPOOL system procedure 7-14
indicator 2-25
syntax for 2-23
unnamed 2-23
Q
Query
using a list 2-24
decomposition in EXPLAIN plan 5-17
using in a loop 2-25
using a parameter with 2-23
Partition, local
Question mark (?)
using to maximize local autonomy 5-28
as unnamed parameter 2-23
Pascal programming language 1-1
Quotes
Pathway, dynamic SQL server 7-3
double (") in SQL statements 3-2
Performance, NonStop SQL 5-24, 5-34
getting from SQLSA 6-10 Quotes (’) in SQL statements 3-2
PLAN option for EXPLAIN utility 5-8
Pointer, structure R
as host variable 2-9 READ system procedure 1-3
PRECISION field Reading a row
data type literals for 6-18 using FETCH statement 3-18
in SQLDA structure 7-5 READUPDATE system procedure 7-3
PREFIX clause RECOMPILE option, SQL compiler 5-9,
with INVOKE statement 3-29 5-24
PREPARE statement, SQL 3-30, 7-10, RECOMPILEALL option, SQL
7-15 compiler 5-10, 5-25
Process file segment (PFS) 5-31 RECOMPILEONDEMAND option, SQL
compiler 5-10, 5-25
Program development, C
Referential integrity
using mixed-version features D-12
enforcing E-1
Program development, TAL
example of E-3
for release C10 D-10
managing E-2
overview of 1-2
Relational database management system
using mixed-version features D-11 (RDBMS) 1-1
HP NonStop SQL Programming Manual for TAL—527887-001
Index-10
Index S

Relative table Run option, TACL (continued)


insert into 3-20 for TAL compiler 5-3
RELEASE 2 option RUND command, TACL
in INCLUDE SQLDA directive D-11 for SQL object file 5-30
RELEASE statement, SQL 3-31 Run-time data unit (RTDU) 3-37
RELEASE1 option Run-time memory allocation 7-14
in INCLUDE SQLDA directive D-11 Run-time recompilation errors 5-28
in SQL directive 3-36, D-11, D-14
RELEASE2 option S
in SQL directive 3-36, D-11, D-14 Scale
Renaming program file from DATA^LEN field 7-27
effect on SQL validity 5-23 SEARCH directive, TAL compiler 5-4
REPLY system procedure 7-3 Section location table
Requester, SCREEN COBOL 7-3 (SLT) 3-37
Reserved words, SQL Security attribute, altering
for C10 program migration D-5 effect on SQL validity 5-23
RESTORE/BACKUP SELECT statement, SQL 3-31
version issues D-10 Selecting data, cursor declaration 3-11
Retrieving data Semicolon (;)
multiple rows 3-34 in SQL statements 1-2, 3-1
single row 3-33 Sequential I/O (SIO) procedures 4-2, 4-6,
with cursor 3-35 4-8, 4-14, 4-22, 4-23
RETURNING LASTSYSKEY option, SET DEFINE command, TACL 5-19
INSERT statement 7-6 Set operations
RISC (TNS/R) system 1-7 delete 3-14
Row in SQL table update 3-44
deleting 3-14 SETSCALE SQL function 2-4, 2-5, 2-7,
fetching 3-7, 3-18, 3-29 2-12, 2-13, 3-21
inserting data in 3-19 Shared memory, using 3-41
selecting 3-32, 3-34 Single row in SQL table
updating 3-43, 3-44 deleting 3-14
RTDU selecting 3-32
See Run-time data unit (RTDU) updating 3-43
RUN command Single-code thread design D-13, D-14
for SQL program file 1-7 SIO
RUN command, TACL See Sequential I/O (SIO)
for SQL object file 1-7, 5-30 procedures 4-22
Run option, TACL Sizing SQL data structures 3-41
for SQL object file 5-31 SLT
for SQLCOMP command 5-6 See Section location table (SLT)
Sort operations, using TACL DEFINEs 5-32
HP NonStop SQL Programming Manual for TAL—527887-001
Index-11
Index S

SORTPROG process 4-2, 4-8, 4-14 SQLCATOBUFFER system


SORT_DEFAULTS DEFINE procedure 4-13, 6-9
See=_SORT_DEFAULTS DEFINE SQLCI
Source file, TAL compiler 5-2 See Conversational interface, NonStop
SQL compilation SQL
automatic recompilation 5-24 SQLCODE variable
explicit 1-7 after DELETE statement 3-13
functions of SQL compiler 5-11 after FETCH statement 3-18
insufficient information for 5-15 after INSERT statement 3-20
interpreting error messages 5-14 after UPDATE statement 3-43
listing 5-15 checking 6-2
of dynamic SQL statements 5-14 declaring 6-2
SQL compiler 1-7 declaring for dynamic SQL 7-9
unresolved TACL DEFINEs for 5-15 in data conversion 2-4
using a PARAM command 5-13 used by WHENEVER 6-4
using DEFINEs with 5-32 with automatic SQL recompilation
errors 5-24
using EXPLAIN utility with 5-17
SQLCOMP command 5-24
warning messages for 5-14
SQLDA data structure 6-13, 7-6
with SQLCOMP command 5-6 data type literals for 6-18
SQL directive, TAL compiler 3-1, 3-2, 3-35 EYE^CATCHER field 6-18
SQL SENSITIVE flag 5-22
fields in 6-17
SQL SENSITIVE, SQL 5-22
names buffer 6-14
SQL statements
Release 1 template 6-15
See NonStop SQL statements 1-1
Release 2 template 6-15
SQL statistics area
See SQLSA data structure SQLDA^EYE^CATCHER literal 7-10, 7-11,
7-18
SQLCA data structure 4-7, 4-8, 4-14 SQLGETCATALOGVERSION system
after DELETE statement 3-13 procedure 4-19, D-11
after INSERT statement 3-20 SQLGETOBJECTVERSION system
automatic SQL recompilation procedure 4-19, D-11
errors 5-24 SQLGETSYSTEMVERSION system
declaring 6-9 procedure 4-21, D-11
description of 6-9 SQLIN data structure 3-37
displaying with SQLCADISPLAY 4-2 SQLIVARS data structure 3-37
SQLMAP option, SQL directive 3-37
with UPDATE statement 3-42
SQLMEM directive, TAL compiler 3-1, 3-38
SQLCADISPLAY system procedure 1-4,
2-4, 4-2, 6-9 SQLMSG
SQLCAFSCODE system procedure 4-7, file number 4-3
6-9 SQLMSG file
SQLCAGETINFOLIST system description of 4-6, 4-18
procedure 6-9
HP NonStop SQL Programming Manual for TAL—527887-001
Index-12
Index S

SQLMSG file (continued) SWAPVOL


file number 4-15 option in PARAM command 5-13
with SQLCADISPLAY procedure 4-15 SYMBOLPAGES directive, TAL
with SQLCATOBUFFER compiler 3-1, 3-3, 3-42
procedure 4-15 SYSKEY
SQLOVARS data structure 3-37 with INSERT statement 3-20
SQLSA data structure System procedure
description of 6-1 GETPOOL 7-17
with PREPARE statement 3-31 System procedures
STACK option, SQLMEM compiler ALLOCATESEGMENT 3-41
directive 3-3 CLOSE 1-3
STACK option, SQLMEM directive 3-39 CONVERTTIMESTAMP 3-22
Statements, NonStop SQL DEFINEPOOL 7-17
See also NonStop SQL statements GETPOOL 7-10
table of 1-2 JULIANTIMESTAMP 3-22
Static SQL operations MOVEX 3-39
description 1-4 NEWPROCESS 1-7, 5-30
version issues D-8 OPEN 7-3
Static SQL statements, using 1-4 PUTPOOL 7-14
Statistics READ 1-3
displaying
READUPDATE 7-3
with SQLCATOBUFFER 4-13
REPLY 7-3
for SQL compilation 5-11
table of 4-1
unavailable for maximizing local
USESEGMENT 3-38
autonomy 5-28
WRITEREAD 1-3
Statistics area, SQL
See SQLSA data structure System procedures, NonStop SQL
SQLCADISPLAY 2-4
Status reporting 6-1
STOREDDEFINES option SQLCADISPLAY procedure 1-4
for SQL compiler 5-8 SQLCAGETINFOLIST 4-8
in SQLCOMP command 5-32 SQLGETCATALOGVERSION 4-19,
D-11
STRING parameter as host variable 2-11
SQLGETOBJECTVERSION 4-19, D-11
STRING type array as host variable 2-11
STRIP command, Binder 5-4 SQLGETSYSTEMVERSION 4-21,
D-11
Structure as host variable 2-8
SQLSADISPLAY 4-22
Structure pointer as host variable 2-9
Structure template, by INVOKE 3-23
Suffix clause
with INVOKE statement 3-29
Swap file volume
for SQL compiler 5-13

HP NonStop SQL Programming Manual for TAL—527887-001


Index-13
Index T

T Timestamp
check at table open time 5-25
Table, SQL program validation time 5-22
changes and program file validity 5-23
run-time check 5-26
maximizing local autonomy for
with INSERT statement 3-21
partitions 5-28, 5-30
TNS/R 1-7
open time and automatic SQL
recompilation 5-25 Transaction Application Language (TAL)
using SELECT statement 3-32 compiler
version 2 D-2 running 3-2
TACL using TACL DEFINEs with 5-31
ASSIGN command for SQL program WHENEVER pseudocode 6-4
file 5-30 compiler directives
DEFINEs DATAPAGES 7-8
ADD DEFINE command 5-19 in RUN command 5-4
CLASS CATALOG 5-7 SEARCH 3-3, 5-4
DEFMODE option 5-19, 5-32 SOURCE 3-3
for automatic SQL SQL 3-1, 3-2, 3-40, 5-4
recompilation 5-25 SQLMEM 3-1, 3-42
for SQL program execution 5-32 SYMBOLPAGES 3-1, 3-3, 3-42
for SQL program file 5-30 compiler syntax 5-6
propagating 5-32 ELSE keyword in SQL statements 1-2,
SET DEFINE command 5-19 3-1
using to maximize local END keyword in SQL statements 1-2,
autonomy 5-29 3-1
using with SQL compiler 5-32 program development with 1-2
using with TAL compiler 5-31 TALDECS 6-18, 7-21
in sample program B-1, C-1 TALLIB 1-7, 7-8
PARAM command for SQL program TALLIB file 5-5
file 5-30 UNTIL keyword in SQL statements 1-2,
RUN command 3-1
for SQL object file 5-30 Transaction Manangement Facility (TMF)
for TAL compiler 5-3 See HP NonStop Transaction
parameters for SQL object file 5-30 Manangement Facility
run option TRANSIDS tables 5-10
Two-code thread design D-13
for SQL object file 5-31
TYPE AS clause
for SQLCOMP command 5-7
examples of 2-16
for TAL compiler 5-3
with a parameter 2-24
RUND command
with date-time data 2-16
for SQL object file 5-30
with host variable 2-5, 2-7

HP NonStop SQL Programming Manual for TAL—527887-001


Index-14
Index U

U VARCHAR data type


columns with INVOKE directive 3-24
Uncompiled SQL statements, FORCE VAR^PTR field
option 5-14
in SQLDA structure 7-5
Underscore (_)
in host variable names 2-2 VERIFY utility, SQL 5-22
Version information
UNTIL TAL keyword in SQL
statements 1-2, 3-1 data types D-1
Update operation descriptions D-2
multiple rows 3-14 features D-1
set of rows 3-14 functions D-1
single row 3-14 using
using indicator parameter in 2-23 SQLGETCATALOGVERSION 4-19,
D-2, D-11
using null values in 2-17
using
with null values 3-47 SQLGETOBJECTVERSION 4-19, D-2,
UPDATE statement, SQL 3-42 D-11
Update statistics using
effect on SQL validity 5-23 SQLGETSYSTEMVERSION 4-21, D-2,
optimized execution plan 5-14 D-11, D-13
UPDATE STATISTICS statement, versioning PVU D-9
SQL 5-11, 5-14, 5-23 Version Management, NonStop SQL A-2
UPDATE WHERE CURRENT clause VERSIONS catalog table D-12
for a cursor 7-32 View, SQL
USAGES table 5-11 changes and program file validity 5-23
recorded program dependencies 5-23 version 2 D-2
unrecorded program
dependencies 5-15
Usages table 5-10
W
USER option, SQLMEM directive 3-38 Warning messages
USESEGMENT system procedure 3-38 detecting with WHENEVER 6-4
USING DESCRIPTOR clause for SQL compiler 5-14
for a cursor 7-32 WHENEVER directive, SQL 6-4, B-11
in FETCH statement 7-5 WHENEVERLIST option, SQL
directive 3-36
WHERE clause
V in subquery for C10 program
VALID flag, SQL 5-22 migration D-6
Validation WHERE CURRENT OF
program file 5-22 in DELETE statement 3-15
with error conditions 5-14 WHERE CURRENT OF clause
VARCHAR data type in DELETE statement 3-15
as host variable 2-8 in UPDATE statement 3-45

HP NonStop SQL Programming Manual for TAL—527887-001


Index-15
Index Z

WRITEREAD system procedure 1-3

Z
ZZBInnnn object file 5-4

Special Characters
! (exclamation point) for TAL comment 3-2
" (double quote) in SQL statement 3-2
-- double hyphen in SQL comment 3-2
: (colon) with host variable 1-3
; (semicolon) in SQL statement 3-1
=_DEFAULTS DEFINE, TACL
propagating 5-32
used by EXPLAIN utility 5-18
=_SORT_DEFAULTS DEFINE 5-32
? (question mark) as unnamed
parameter 2-23
’ (single quote) in SQL statement 3-2

HP NonStop SQL Programming Manual for TAL—527887-001


Index-16

You might also like