Sunteți pe pagina 1din 86

IBM Netezza

Release 7.1

IBM Netezza Stored Procedures


Developer's Guide



IBM Netezza
Release 7.1

IBM Netezza Stored Procedures


Developer's Guide



Note
Before using this information and the product it supports, read the information in Notices on page C-1

Revised: January 10, 2014


This edition applies to IBM Netezza Release 7.1 and to all subsequent releases until otherwise indicated in new
editions.
Copyright IBM Corporation 2009, 2014.
US Government Users Restricted Rights Use, duplication or disclosure restricted by GSA ADP Schedule Contract
with IBM Corp.

Contents
Electronic emission notices . . . . . . . . . . . . . . . . . . . . . . . . . . . v
Regulatory and compliance . . . . . . . . . . . . . . . . . . . . . . . . . . . ix
About this publication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi
If you need help . . . . .
How to send your comments

.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

. xi
. xi

Chapter 1. Introduction to stored procedures . . . . . . . . . . . . . . . . . . . 1-1


Stored procedures . . . . . . . . . . . . . . . . .
NZPLSQL language . . . . . . . . . . . . . . .
SQL commands for stored procedures . . . . . . . . .
Stored procedures input and return types . . . . . . . .
How to create and use a stored procedure . . . . . . . . .
How to execute a stored procedure . . . . . . . . . . .
Best practices for stored procedure developers . . . . . . .
Security considerations . . . . . . . . . . . . . .
Cross-database access to stored procedures . . . . . . .
Block quoting support . . . . . . . . . . . . . .
SQL restrictions within the stored procedure . . . . . . .
Best practices for Netezza administrators . . . . . . . . .
Back up and restore stored procedures . . . . . . . . .
Upgrade and patch Netezza systems that have stored procedures
Downgrade Netezza systems that have stored procedures . .

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1-1
1-2
1-2
1-2
1-3
1-3
1-3
1-3
1-4
1-5
1-6
1-6
1-6
1-7
1-7

Chapter 2. NZPLSQL statements and grammar . . . . . . . . . . . . . . . . . . 2-1


NZPLSQL structure . . . . . . . . . . . . . .
Transaction commits and rollbacks in stored procedures .
AUTOCOMMIT ON blocks . . . . . . . . . . .
Comments . . . . . . . . . . . . . . . . .
Variables and constants . . . . . . . . . . . . .
Parameter passing . . . . . . . . . . . . . .
Argument list and variables . . . . . . . . . .
Scope of variables . . . . . . . . . . . . . .
Data types and aliases . . . . . . . . . . . .
Array variables . . . . . . . . . . . . . . .
Expressions . . . . . . . . . . . . . . . . .
Literals and math operations in expressions . . . . .
Statements . . . . . . . . . . . . . . . . .
Assignment. . . . . . . . . . . . . . . .
Call another procedure . . . . . . . . . . . .
Run dynamic queries . . . . . . . . . . . .
Obtain other results status . . . . . . . . . . .
Return from a procedure . . . . . . . . . . .
Control Structures . . . . . . . . . . . . . .
Conditional control . . . . . . . . . . . . .
Iterative control . . . . . . . . . . . . . .
Records . . . . . . . . . . . . . . . . . .
Declaration . . . . . . . . . . . . . . . .
Assignments . . . . . . . . . . . . . . .
Iterate through the records of a query . . . . . . .
Report messages and raise errors . . . . . . . . .
Exceptions and error messages support . . . . . . .
Return a result set . . . . . . . . . . . . . .
Copyright IBM Corp. 2009, 2014

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

. 2-1
. 2-2
. 2-3
. 2-4
. 2-5
. 2-6
. 2-6
. 2-7
. 2-9
. 2-10
. 2-11
. 2-12
. 2-15
. 2-15
. 2-16
. 2-16
. 2-17
. 2-17
. 2-17
. 2-17
. 2-19
. 2-20
. 2-20
. 2-20
. 2-21
. 2-22
. 2-23
. 2-25

iii

REFTABLE and ROLLBACK commands . .


Manage large data sets . . . . . . . .
Advanced development topics . . . . . .
Extend the NZPLSQL language with UDFs .
Tips and best practices for stored procedures

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

2-27
2-27
2-28
2-28
2-28

Chapter 3. Create and manage stored procedures . . . . . . . . . . . . . . . . . 3-1


Manage user account permissions. . . . . . . . . .
Create a stored procedure . . . . . . . . . . . .
Design a stored procedure . . . . . . . . . . .
Create a stored procedure . . . . . . . . . . .
Size-specific, generic, and variable argument procedures .
Obfuscate the procedure body . . . . . . . . . .
Call or invoke a stored procedure . . . . . . . . .
Alter a stored procedure . . . . . . . . . . . .
Comment on a stored procedure . . . . . . . . . .
Drop a stored procedure . . . . . . . . . . . .
Show information about a stored procedure . . . . . .
NzAdmin administrative interface for stored procedures. .

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

. 3-1
. 3-4
. 3-4
. 3-4
. 3-5
. 3-8
. 3-10
. 3-10
. 3-11
. 3-12
. 3-12
. 3-12

Appendix A. SQL command reference . . . . . . . . . . . . . . . . . . . . . . A-1


The ALTER PROCEDURE command . . . . . .
The CALL and EXEC[UTE [PROCEDURE]] commands
The CREATE [OR REPLACE] PROCEDURE commands
The DROP PROCEDURE command . . . . . . .
The SHOW PROCEDURE command . . . . . .

Appendix B. Stored procedure examples


Variable argument stored procedure . . . .
Example of simulating an anonymous block .

.
.

.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

A-1
A-3
A-5
A-7
A-9

. . . . . . . . . . . . . . . . . . . . B-1
.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

.
.

. B-1
. B-2

Notices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C-1
Trademarks .

. C-3

Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . X-1

iv

IBM Netezza Stored Procedures Developer's Guide

Electronic emission notices


When you attach a monitor to the equipment, you must use the designated
monitor cable and any interference suppression devices that are supplied with the
monitor.

Federal Communications Commission (FCC) Statement


This equipment was tested and found to comply with the limits for a Class A
digital device, according to Part 15 of the FCC Rules. These limits are designed to
provide reasonable protection against harmful interference when the equipment is
operated in a commercial environment. This equipment generates, uses, and can
radiate radio frequency energy and, if not installed and used in accordance with
the instruction manual, might cause harmful interference to radio communications.
Operation of this equipment in a residential area is likely to cause harmful
interference, in which case the user is required to correct the interference at their
own expense.
Properly shielded and grounded cables and connectors must be used to meet FCC
emission limits. IBM is not responsible for any radio or television interference
caused by using other than recommended cables and connectors or by
unauthorized changes or modifications to this equipment. Unauthorized changes
or modifications might void the authority of the user to operate the equipment.
This device complies with Part 15 of the FCC Rules. Operation is subject to the
following two conditions: (1) this device might not cause harmful interference, and
(2) this device must accept any interference received, including interference that
might cause undesired operation.

Industry Canada Class A Emission Compliance Statement


This Class A digital apparatus complies with Canadian ICES-003.

Avis de conformit la rglementation d'Industrie Canada


Cet appareil numrique de la classe A est conforme la norme NMB-003 du
Canada.

Australia and New Zealand Class A Statement


This product is a Class A product. In a domestic environment, this product might
cause radio interference in which case the user might be required to take adequate
measures.

European Union EMC Directive Conformance Statement


This product is in conformity with the protection requirements of EU Council
Directive 2004/108/EC on the approximation of the laws of the Member States
relating to electromagnetic compatibility. IBM cannot accept responsibility for any
failure to satisfy the protection requirements resulting from a nonrecommended
modification of the product, including the fitting of non-IBM option cards.

Copyright IBM Corp. 2009, 2014

This product is an EN 55022 Class A product. In a domestic environment, this


product might cause radio interference in which case the user might be required to
take adequate measures.
Responsible manufacturer:
International Business Machines Corp.
New Orchard Road
Armonk, New York 10504
914-499-1900
European Community contact:
IBM Technical Regulations, Department M456
IBM-Allee 1, 71137 Ehningen, Germany
Telephone: +49 7032 15-2937
Email: tjahn@de.ibm.com

Germany Class A Statement


Deutschsprachiger EU Hinweis: Hinweis fr Gerte der Klasse A EU-Richtlinie
zur Elektromagnetischen Vertrglichkeit
Dieses Produkt entspricht den Schutzanforderungen der EU-Richtlinie
2004/108/EG zur Angleichung der Rechtsvorschriften ber die elektromagnetische
Vertrglichkeit in den EUMitgliedsstaaten und hlt die Grenzwerte der EN 55022
Klasse A ein.
Um dieses sicherzustellen, sind die Gerte wie in den Handbchern beschrieben zu
installieren und zu betreiben. Des Weiteren drfen auch nur von der IBM
empfohlene Kabel angeschlossen werden. IBM bernimmt keine Verantwortung fr
die Einhaltung der Schutzanforderungen, wenn das Produkt ohne Zustimmung der
IBM verndert bzw. wenn Erweiterungskomponenten von Fremdherstellern ohne
Empfehlung der IBM gesteckt/eingebaut werden.
EN 55022 Klasse A Gerte mssen mit folgendem Warnhinweis versehen werden:
Warnung: Dieses ist eine Einrichtung der Klasse A. Diese Einrichtung kann im
Wohnbereich Funk-Strungen verursachen; in diesem Fall kann vom Betreiber
verlangt werden, angemessene Manahmen zu ergreifen und dafr
aufzukommen.

Deutschland: Einhaltung des Gesetzes ber die


elektromagnetische Vertrglichkeit von Gerten
Dieses Produkt entspricht dem Gesetz ber die elektromagnetische Vertrglichkeit
von Gerten (EMVG). Dies ist die Umsetzung der EU-Richtlinie 2004/108/EG in
der Bundesrepublik Deutschland.

Zulassungsbescheinigung laut dem Deutschen Gesetz ber die


elektromagnetische Vertrglichkeit von Gerten (EMVG) (bzw. der
EMC EG Richtlinie 2004/108/EG) fr Gerte der Klasse A
Dieses Gert ist berechtigt, in bereinstimmung mit dem Deutschen EMVG das
EG-Konformittszeichen - CE - zu fhren.
Verantwortlich fr die Einhaltung der EMV Vorschriften ist der Hersteller:

vi

IBM Netezza Stored Procedures Developer's Guide

International Business Machines Corp.


New Orchard Road
Armonk, New York 10504
914-499-1900
Der verantwortliche Ansprechpartner des Herstellers in der EU ist:
IBM Deutschland
Technical Regulations, Department M456
IBM-Allee 1, 71137 Ehningen, Germany
Telephone: +49 7032 15-2937
Email: tjahn@de.ibm.com
Generelle Informationen: Das Gert erfllt die Schutzanforderungen nach EN 55024
und EN 55022 Klasse A.

Japan VCCI Class A Statement

This product is a Class A product based on the standard of the Voluntary Control
Council for Interference (VCCI). If this equipment is used in a domestic
environment, radio interference might occur, in which case the user might be
required to take corrective actions.

Japan Electronics and Information Technology Industries


Association (JEITA) Statement

Japan Electronics and Information Technology Industries Association (JEITA)


Confirmed Harmonics Guidelines (products less than or equal to 20 A per phase)

Japan Electronics and Information Technology Industries


Association (JEITA) Statement

Japan Electronics and Information Technology Industries Association (JEITA)


Confirmed Harmonics Guidelines (products greater than 20 A per phase)

Electronic emission notices

vii

Korea Communications Commission (KCC) Statement

This is electromagnetic wave compatibility equipment for business (Type A). Sellers
and users need to pay attention to it. This is for any areas other than home.

Russia Electromagnetic Interference (EMI) Class A Statement

People's Republic of China Class A Electronic Emission


Statement

Taiwan Class A Compliance Statement

viii

IBM Netezza Stored Procedures Developer's Guide

Regulatory and compliance


Regulatory Notices
Install the NPS system in a restricted-access location. Ensure that only those
people trained to operate or service the equipment have physical access to it.
Install each AC power outlet near the NPS rack that plugs into it, and keep it
freely accessible.
Provide approved circuit breakers on all power sources.
Product might be powered by redundant power sources. Disconnect ALL power
sources before servicing.
High leakage current. Earth connection essential before connecting supply. Courant
de fuite lev. Raccordement la terre indispensable avant le raccordement au
rseau.

Homologation Statement
This product may not be certified in your country for connection by any means
whatsoever to interfaces of public telecommunications networks. Further
certification may be required by law prior to making any such connection. Contact
an IBM representative or reseller for any questions.

Copyright IBM Corp. 2009, 2014

ix

IBM Netezza Stored Procedures Developer's Guide

About this publication


IBM Netezza stored procedures combine the benefits of SQL to query and
manipulate database information with the benefits of a procedural programming
language to handle data processing, transaction logic, and application branching
behaviors.
Review the topics in this publication to create and use stored procedures on a IBM
Netezza data warehouse appliance. These topics describe the NZPLSQL Netezza
procedural language, provide an overview of the language and statements, and
how to create, alter, and drop procedures by using Netezza SQL commands.
To use these topics, you should be familiar with the Netezza systems and
architecture and Netezza SQL commands and how to access a Netezza database.
You should also be familiar with the general concepts of stored procedures, how to
create structured language programs, and how to debug applications.

If you need help


If you are having trouble using the IBM Netezza appliance, follow these steps:
1. Try the action again, carefully following the instructions for that task in the
documentation.
2. Go to the IBM Support Portal at: http://www.ibm.com/support. Log in using
your IBM ID and password. You can search the Support Portal for solutions. To
submit a support request, click the Service Requests & PMRs tab.
3. If you have an active service contract maintenance agreement with IBM, you
can contact customer support teams by telephone. For individual countries,
visit the Technical Support section of the IBM Directory of worldwide contacts
(http://www.ibm.com/support/customercare/sas/f/handbook/contacts.html).

How to send your comments


You are encouraged to send any questions, comments, or suggestions about the
IBM Netezza documentation. Send an email to netezza-doc@wwpdl.vnet.ibm.com
and include the following information:
v The name and version of the manual that you are using
v Any comments that you have about the manual
v Your name, address, and phone number
We appreciate your suggestions.

Copyright IBM Corp. 2009, 2014

xi

xii

IBM Netezza Stored Procedures Developer's Guide

Chapter 1. Introduction to stored procedures


This section provides an overview of the support for stored procedures in the IBM
Netezza family of data warehouse appliances.
Stored procedure support is available in Netezza Release 4.6 and later. These topics
describe changes available in Release 7.1 and later.

Stored procedures
IBM Netezza stored procedures combine the benefits of SQL to query and
manipulate database information with the benefits of a procedural programming
language to handle data processing, transaction logic, and application branching
behaviors.
For example, if you have a database that contains customer information, inventory,
and sales records, you might also have an application that processes the sale of an
item in inventory. When an order request arrives, the application might be
designed to query the database to determine how many items of that type are
available in inventory, and then to take the following actions:
v If the available inventory is less than the order number, the application processes
the request for the available number and notifies an order administrator to order
more inventory to complete the purchase.
v If the available inventory is greater than the order request, the application
processes the order and updates the database to show the reduction in the
current inventory.
v If the inventory is discontinued, the application saves the order request and
returns a message that the item is no longer available. It can also query for
related or replacement inventory to report alternative merchandise.
While such an application can be managed with a third-party business application
that accesses the Netezza database to do these tasks, you can also use Netezza
stored procedures to encapsulate this application as an object in the Netezza
database. SQL provides the power to access and update the database information
about the host, and the procedure language provides the logic for if-then-else
branching and application processing.
Because the application is on the Netezza host, the application performance can
benefit from its location onsite by avoiding the network time between an
application client system and the Netezza host. The application itself also becomes
easier to maintain, as it is in only one location (the Netezza host) and thus
versioning and updates need only be made in one place to keep the application
up-to-date for all users.
With Netezza stored procedures, you can also take advantage of security and
access benefits. Stored procedures can be defined to run with the credentials of the
user who created the procedure or the credentials of the user who is running the
procedure. The procedure manages the access to information contained in various
base tables and views. You can grant a user permission to run a stored procedure
without granting that user explicit access to underlying tables or views.

Copyright IBM Corp. 2009, 2014

1-1

NZPLSQL language
You implement stored procedures on the IBM Netezza host by creating
applications by using the NZPLSQL language. NZPLSQL is an interpreted
language which is based on Postgres PL/pgSQL language and designed for the
Netezza host environment.
NZPLSQL is a scripting language embedded in SQL. As a procedural language, it
has branch, loop, and subprogram structures while SQL provides the main
program. The subprograms, known as procedures, can take arguments and declare
internal variables. After they are stored in a database, these procedures can be
called from within other databases on the same Netezza host.
The NZPLSQL language provides for the following types of procedural logic:
v Conditionals (if/else)
v Looping (while, for)
v Execution of SQL (including dynamic SQL)
v Variables
v Returning a scalar result or a result set
v Input arguments
v Execution in the calling context (session and transaction)
v Extending functionality (adding NZPLSQL library routines)

SQL commands for stored procedures


To support stored procedures in the IBM Netezza database, the Netezza SQL
language includes commands for stored procedures:
v
v
v
v
v

ALTER PROCEDURE
CALL or EXEC[UTE[ PROCEDURE]]
CREATE [OR REPLACE] PROCEDURE
DROP PROCEDURE
SHOW PROCEDURE

You can use any SQL tool that supports ODBC, JDBC, OLE-DB to enter these
commands. This publication contains examples that use the nzsql command-line
tool.
In addition to these procedure-specific commands, you can also use the commands
GRANT and REVOKE to allow or deny access to procedures, and COMMENT ON
to add descriptions and details to the procedure definitions.
Related concepts:
Chapter 3, Create and manage stored procedures, on page 3-1
Related reference:
Appendix A, SQL command reference, on page A-1

Stored procedures input and return types


IBM Netezza stored procedures are a hybrid between functions and procedures (as
defined by the SQL:2003 standard for SQL-invoked routines). In the Netezza
implementation, an NZPLSQL stored procedure takes only input arguments and
supports a return value as functions do. Unlike functions, a stored procedure must

1-2

IBM Netezza Stored Procedures Developer's Guide

be called by using CALL or a similar construct, and it is not allowed in the usual
query locations where a built-in or standard function is allowed.
A stored procedure can also be designed to return a result set. For more
information, see Return a result set on page 2-25.

How to create and use a stored procedure


As a high-level summary, follow these steps to create and use a stored procedure.
These steps are described in more detail in Chapter 3, Create and manage stored
procedures, on page 3-1
1. Design the stored procedure logic and operation.
2. Define the stored procedure object by using the CREATE [OR REPLACE]
PROCEDURE command.
3. Run or execute the procedure from the SQL command prompt.
As with other IBM Netezza objects, the Netezza admin user can create, list, and
execute stored procedures by default. The admin user can also grant other users
permission to create, list, and execute stored procedures on the Netezza system.
Related concepts:
Manage user account permissions on page 3-1

How to execute a stored procedure


You execute a stored procedure in the SQL command by using either the CALL or
EXEC[UTE[ PROCEDURE]] commands. For example, if you have a stored
procedure named updateacct(), you can run it by using any of the following
commands:
MYDB.SCHEMA(USER)=>
MYDB.SCHEMA(USER)=>
MYDB.SCHEMA(USER)=>
MYDB.SCHEMA(USER)=>

CALL updateacct();
EXEC updateacct();
EXECUTE updateacct();
EXECUTE PROCEDURE updateacct();

You can also use the SELECT command to execute a procedure; however, you
cannot specify a FROM clause. For example:
MYDB.SCHEMA(USER)=> SELECT updateacct();

To execute the procedure, the user must be the owner of or have permission to
execute the updateacct() procedure.
Related reference:
Appendix A, SQL command reference, on page A-1

Best practices for stored procedure developers


The following sections describe some best practices for users who develop stored
procedures.

Security considerations
When you define a stored procedure, you can specify whether the IBM Netezza
system executes the procedure by using the ID of the owner who created the

Chapter 1. Introduction to stored procedures

1-3

stored procedure or the ID of the user who runs the procedure. The user account
adds an additional layer of security (or expanded access) for the data that is
processed by the stored procedure.
For example, if the admin user creates a stored procedure and specifies execute as
owner permission, which is the default, then any user who is allowed to execute
the procedure will do so as the admin user. With the admin user privileges, the
procedure could access data in tables or views that the logged-in database user
might not have permission to access. If the user bsmith creates the stored
procedure, then users who can execute the procedure will do so as the user bsmith.
If a procedure should access only the data that the executing user is allowed to
see, define the stored procedure as execute as caller. In this case, the procedure
uses the user ID of the database user who executes the procedure. The procedure
can access only the data that the calling user is permitted to see.

Cross-database access to stored procedures


When you create a stored procedure by using the CREATE [OR REPLACE]
PROCEDURE command, the command adds the procedure to the database and
schema to which you are connected. You can access the procedure while connected
to the database where the stored procedure is defined, and you can also run
procedures in other schemas in the same database, or in other databases using the
following methods:
v Using fully-qualified object names when calling a procedure object that resides
within a different database, for example:
MYDB.SCHEMA(ADMIN)=> EXEC OTHERDB.SCHEMA.UPDATEACCT();

v Using a schema.object name when calling a procedure object that resides within
a different schema of the same database, for example:
MYDB.SCHEMA(ADMIN)=> EXEC SCH_TWO.UPDATEACCT();

v Using the PATH SQL session variable to specify the databases and/or schemas
to search to find a procedure name that is not fully qualified. To use the PATH
session variable, you enter a command similar to the following:
MYDB.SCHEMA(ADMIN)=> SET PATH = <elem> [, <elem>];

The <elem> value can be a database, a schema, or the variables


CURRENT_CATALOG, CURRENT_USER, CURRENT_SCHEMA, or
CURRENT_PATH. Anything you specify as <elem> must resolve to a database
name.
For example:
MYDB.SCHEMA(ADMIN)=> SET PATH = mydb, nzdb, customer;
SET VARIABLE

To display the PATH value, use the following command:


MYDB.SCHEMA(ADMIN)=> SELECT CURRENT_PATH;
CURRENT_PATH
-----------------MYDB,NZDB,CUSTOMER
(1 row)

The Netezza system uses the PATH variable during the lookup of any unqualified
procedures. It searches the current database if PATH is not set; otherwise it
searches the databases and schemas specified in PATH, in the order that they are
specified. The Netezza system uses the first match that it finds, even if a better
match might exist in a subsequent database. A poorer match is one that might
require implicit casting of arguments or that causes an error due to multiple

1-4

IBM Netezza Stored Procedures Developer's Guide

potential matches. Also, the Netezza system uses the PATH session variable to find
only stored procedures, user-defined functions (UDFs), and user-defined
aggregates (UDAs). Other object types such as tables, sequences, and so on, are not
supported.
If a stored procedure is invoked from a different database, unqualified objects bind
to objects in the invoking database, not in the database where the stored procedure
is defined. Unqualified stored procedures, UDFs, and UDAs are exceptions to this
rule because the Netezza system first uses the PATH variable to search for those
three object types before it searches within the invoking database.
If you plan to invoke cross-database calls to stored procedures that access data in
other databases, make sure that the stored procedure uses fully qualified object
names to refer to those data objects.
Write operations do not work across databases. For any procedures which contain
insert, update, delete, create, truncate, alter, or drop commands, make sure that
you are connected to the database where the stored procedure is defined.

Block quoting support


Stored procedures are defined as a block or body of numerous lines of text. IBM
Netezza provides a block-quoting mechanism to help ease the definition of the
procedure body and to make the content more readable for debugging and
learning.
A section of text bounded by BEGIN_PROC and END_PROC is a block quote. The
following is an example:
CREATE OR REPLACE PROCEDURE name() RETURNS INT4 LANGUAGE NZPLSQL AS
BEGIN_PROC
DECLARE
string varchar;
BEGIN
string := This string is quoted;
END;
END_PROC;

As shown in the example, quotation marks are not escaped within the
block-quoted string. The string content is always written literally. Backslashes have
no special escape meaning.
The stored procedure body is in clear text format by default. Privileged users can
use the SHOW PROCEDURE VERBOSE command and interfaces such as
NzAdmin to review the stored procedure. If necessary, you can hide the
procedure code when you create the procedure.
Block quotes are intended for use only in NZPLSQL body quoting or stored
procedure invocation. The execution commands CALL and EXEC[UTE[
PROCEDURE]] support them, although SELECT does not. They can be used inside
a stored procedure body to build DDL statements where they are allowed, but they
have no quoting implications inside the body. If they are used inside the body,
make sure that there are an equal number of both keywords and that they match
(a BEGIN_PROC appears before the corresponding END_PROC) to avoid errors. If
your program logic dictates that they are not matching, they must be broken up
(that is, 'BEGIN_' || 'PROC').

Chapter 1. Introduction to stored procedures

1-5

Both BEGIN_PROC and END_PROC can appear inside a single or double-quoted


string in normal SQL statements if the SQL statements are not inside a block quote.
For example:
select "BEGIN_PROC" from <table>;
insert into <table> values (BEGIN_PROC);

If you want to do this inside a block quote body, then you must have a matching
END_PROC. For example:
CREATE OR REPLACE PROCEDURE name() RETURNS INT4 LANGUAGE NZPLSQL AS
BEGIN_PROC
DECLARE
string varchar;
BEGIN
string := This string is quoted;
-- This comment is the match for below BEGIN_PROC
insert into va values (END_PROC);
END;
END_PROC;

Because nested BEGIN_PROC and END_PROC keywords have no quoting


implications, the following example is not supported:
CREATE OR REPLACE PROCEDURE name() RETURNS INT4 LANGUAGE NZPLSQL AS
BEGIN_PROC
DECLARE
string varchar;
BEGIN
-- The next statement is a syntax error since it is not quoted
string := BEGIN_PROC This string is not quoted END_PROC;
END;
END_PROC;

Related concepts:
Obfuscate the procedure body on page 3-8

SQL restrictions within the stored procedure


Within the body of a stored procedure, you can use most SQL commands to do the
tasks that relate to database objects.
You cannot use SQL commands that are prohibited for use within a
BEGIN/COMMIT transaction block within the body of a stored procedure. Starting
in release 7.1, you can define a BEGIN AUTOCOMMIT ON block within the body,
and within that block you can use all SQL commands, even those prohibited for
use in a BEGIN/COMMIT transaction block such as GENERATE STATISTICS and
GROOM TABLE. For more information, see AUTOCOMMIT ON blocks on page
2-3.
For a description of the transaction control practices and command restrictions, see
the IBM Netezza Database Users Guide.

Best practices for Netezza administrators


The following topics describe some best practices for IBM Netezza administrators
who manage Netezza systems that have stored procedures.

Back up and restore stored procedures


Any stored procedures that you create are backed up and restored by the IBM
Netezza backup and restore operations. If you back up and restore obfuscated
procedures, those restored procedures remain obfuscated. If you restore a database

1-6

IBM Netezza Stored Procedures Developer's Guide

to a system that is running a release which does not support obfuscated


procedures or VARARGS, for example, those procedures will not run and the
queries that use them will return a syntax error.
If you drop a database, all the objects defined in the database including stored
procedures are likewise dropped. If the Netezza system supports multiple schemas
in a database, and you define stored procedures in that schema, dropping the
schema will likewise drop all the objects in that schema. As a best practice, you
should keep backup copies of your source CREATE OR REPLACE PROCEDURE
definitions in a safe location outside of the Netezza system. Make sure that you
have recent backups of your Netezza systems in the event that you need to recover
from an accidental deletion or change, or to restore Netezza services as part of a
disaster recovery situation.

Upgrade and patch Netezza systems that have stored


procedures
There are no special requirements or procedures necessary to preserve any stored
procedures during an NPS upgrade to a new release. The stored procedures
continue to operate in the same manner on the upgraded system as on the
previous release.
If the upgrade release introduces any new features or changes that can affect the
operation of stored procedures, Netezza describes the changes in the release notes.
Before you install any new release or service pack, review the release notes to
familiarize yourself with any new features, changes, fixes, and known issues for
that release. Make sure that you have a recent backup of your Netezza system
before you upgrade the system.

Downgrade Netezza systems that have stored procedures


If you downgrade your Netezza release, the stored procedures should continue to
work after the downgrade. If the downgrade release does not support all the
NZPLSQL features of the later release, any procedures that use those features will
fail when executed after the downgrade. You can drop or alter those procedures to
ensure that they conform to the NZPLSQL language support of the Netezza release
that your system is running.

Chapter 1. Introduction to stored procedures

1-7

1-8

IBM Netezza Stored Procedures Developer's Guide

Chapter 2. NZPLSQL statements and grammar


This section describes the NZPLSQL language, its structure, and how to use the
language to create stored procedures.
NZPLSQL is similar to the Postgres PL/pgSQL language. Some of the language
descriptions in this section use the Postgres PL/pgSQL documentation. However,
NZPLSQL has some differences that are based on the design and environment of
the IBM Netezza system. NZPLSQL also includes some extensions to assist users
who migrate stored procedures that are written in other languages to the Netezza
environment.

NZPLSQL structure
The NZPLSQL language is a block-structured language.
A block is defined as follows:
<< label >>
[DECLARE
declarations]
BEGIN [AUTOCOMMIT ON|OFF]
statements
exception_handlers
END;

You can specify label as an optional way to identify a block in an EXIT statement,
or to qualify the names of the variables declared in the block.
The variables declared in the declarations section that precedes a block are
initialized to their default values every time that the block is entered, not just once
per procedure call.
The BEGIN statement specifies the start of a block, or a group of statements,
within the body of the procedure. By default, a BEGIN statement operates in
AUTOCOMMIT OFF mode, which causes the procedure to execute all the
statements inside the block as one multi-statement transaction. Within the block,
you can use most of the SQL commands that you can use at the SQL command
line, but you cannot use the SQL commands that are prohibited for use within a
SQL BEGIN/COMMIT transaction block.
Starting in release 7.1, if you specify the BEGIN AUTOCOMMIT ON syntax, the
procedure executes each statement in the block as a singleton statement with an
implied COMMIT after each statement. By committing after each statement, the
block adds support for SQL commands that are not allowed with in a BEGIN block
such as GROOM TABLE, GENERATE STATISTICS, and the other commands that
are prohibited for use within a BEGIN/COMMIT SQL transaction block. Within a
BEGIN/END block, you can specify COMMIT or ROLLBACK commands to either
commit or roll back all the changes in the current transaction.
Note: The BEGIN/END syntax for grouping statements in NZPLSQL is not the
same as the BEGIN/COMMIT SQL database commands for transaction control.
The NZPLSQL BEGIN/END keywords are used only for grouping; they do not
start or end a transaction. Procedures are always executed within a transaction
Copyright IBM Corp. 2009, 2014

2-1

established by an outer query; they cannot start or commit transactions, since IBM
Netezza SQL does not have nested transactions.
The statements section of a block can contain zero, one, or more sub-blocks. A
sub-block is used for logical grouping or to localize variables to a small group of
statements.
All of the keywords and identifiers are not case-sensitive and can be used in mixed
uppercase and lowercase mode. Identifiers are automatically converted to
uppercase, as they are in general SQL statements, unless they are enclosed in
quotation marks to keep them case-sensitive.
The exception_handlers section is an optional section that you can use to catch and
process an error that occurs in the statements section. If an error does not occur, the
exception_handlers section is ignored. For more information, see Exceptions and
error messages support on page 2-23.

Transaction commits and rollbacks in stored procedures


The behavior of a stored procedure depends on whether it is called as a singleton
SQL statement or within a SQL transaction block.
When a stored procedure is called as a singleton SQL statement, the changes made
by the stored procedure are committed when the procedure exits or rolled back if
the procedure aborts.
CALL MYPROCEDURE(123);

If the procedure issues a COMMIT or ROLLBACK statement within the procedure


body, all changes made before the transaction statement are committed or rolled
back, and the system implicitly starts a new transaction. All statements after the
transaction command continue to run as a single multi-statement command, not as
individual commands inside of a transaction block. When the stored procedure
exits, any uncommitted changes are committed or rolled back as they would be
with a stored procedure call before this change.
A sample procedure called test3 follows.
CREATE PROCEDURE TEST3()
LANGUAGE NZPLSQL
RETURNS INT AS
BEGIN_PROC
BEGIN
statement1;
COMMIT;
statement2;
statement3;
RETURN 1234;
END;
END_PROC;

Assume that you run the test3 procedure as a singleton SQL statement such as
EXECUTE test3(). The procedure executes statement1 and commits that change.
The procedure then runs statement2 and statement3, returns the 1234 value, and
exits. If the statements complete without error, the statement2 and statement3
changes are committed when the procedure exits.
Assume that you run the procedure inside a BEGIN transaction block such as the
following example.

2-2

IBM Netezza Stored Procedures Developer's Guide

BEGIN;
execute test3();
ROLLBACK;

When you call the test3 procedure within a transaction block, the procedure
executes statement1 and commits it, then executes statement2 and statement3, but
those statements are not yet committed. The procedure returns control to the
transaction block, which then calls a ROLLBACK command. In this case, the
changes made by statement2 and statement3 are rolled back, but statement1 was
already committed by the COMMIT statement inside the stored procedure body. If
the outside transaction block called a COMMIT instead of a ROLLBACK,
statement2 and statement3 would both be committed by transaction block
COMMIT command.
Remember that if a BEGIN statement starts a transaction block before calling a
stored procedure, the stored procedure always returns with an active transaction
block, and you must issue a COMMIT or ROLLBACK statement to complete or
abort that transaction. Even in the case where an exception causes the stored
procedure to abort, you must still use COMMIT or ROLLBACK after the procedure
exits.

AUTOCOMMIT ON blocks
Each statement within a stored procedure BEGIN AUTOCOMMIT ON block is
executed as a singleton statement with an implied commit immediately after the
statement. This behavior is similar to running a series of SQL commands on the
command line, not inside a BEGIN/COMMIT transaction block.
You can specify all SQL commands inside an AUTOCOMMIT ON block, including
EXECUTE IMMEDIATE, IF statements, FOR statements, and so on. There are no
restrictions on the SQL statements. For each statement that is used inside an
AUTOCOMMIT ON block, the database changes are automatically committed after
each statement is executed.
An example of an AUTOCOMMIT block follows.
CREATE PROCEDURE TEST4()
LANGUAGE NZPLSQL
RETURNS BOOLEAN
BEGIN_PROC
BEGIN AUTOCOMMIT ON
GROOM TABLE MYTBL;
RETURN TRUE;
EXCEPTION WHEN OTHERS THEN
RAISE NOTICE 'ERROR: %', SQLERRM;
RETURN FALSE;
END;

Note: Executing transactional statements such as COMMIT or ROLLBACK inside


an AUTOCOMMIT ON block has no effect because those commands commit or
roll back only their own statement. All previous statements are already committed.
There is an implied COMMIT at the beginning of the AUTOCOMMIT ON block
before any statement in the block is executed. Any exception that is raised by a
command inside an AUTOCOMMIT ON block calls the exception block, in the
same manner as a normal NZPLSQL statement block.
The behavior of statements in an exception block attached to an AUTOCOMMIT
ON block is based on the AUTOCOMMIT ON/OFF status of the parent block. If
Chapter 2. NZPLSQL statements and grammar

2-3

an AUTOCOMMIT ON sub-block occurs within an AUTOCOMMIT ON block, the


statements in the exception block are executed as singletons unless you issue a
BEGIN within the exception block to change the behavior.
The NZPLSQL language allows statement blocks to be nested within each other.
This behavior is supported by AUTOCOMMIT ON blocks as well, so it is possible
to nest AUTOCOMMIT ON|OFF blocks within each other. The syntax BEGIN
AUTOCOMMIT OFF is the default and is identical to BEGIN without an
AUTOCOMMIT clause.
BEGIN
Statement1;
BEGIN AUTOCOMMIT ON
/* an implicit commit occurs here */
Statement2;
/* an implicit commit occurs here */
Statement3;
/* an implicit commit occurs here */
END
END;

When an AUTOCOMMIT ON block is nested inside of an AUTOCOMMIT OFF


block, an implicit commit occurs before the first statement is executed inside of the
AUTOCOMMIT ON block and then an implicit commit occurs after each statement
inside of the AUTOCOMMIT ON block.
When an AUTOCOMMIT OFF block is nested inside of an AUTOCOMMIT ON
block, the statements within the AUTOCOMMIT OFF block are executed as a multi
statement transaction that is immediately committed at the end of the block.
BEGIN AUTOCOMMIT ON
BEGIN AUTOCOMMIT OFF
Statement1;
Statement2;
END;
/* an implicit commit occurs here */
END;

Exception blocks for an AUTOCOMMIT ON block are executed if any of the


statements within the AUTOCOMMIT ON block fails. Unlike a normal exception
block, there is no need to issue a ROLLBACK inside an AUTOCOMMIT ON
exception block. The statement that failed is automatically rolled back and a new
transaction is immediately started before processing any statements in the
exception block.

Comments
Comments within the NZPLSQL language can start with either a double dash or a
forward-slash asterisk.
v A double dash (--) starts a comment that extends to the end of the line. For
example:
-- This is a comment line.

v A forward-slash asterisk pair (/*) starts a block comment, which extends to the
next occurrence of the ending sequence which is an asterisk forward-slash (*/)
pair. For example:
/* This is a block comment,
which can span multiple lines.
Any code inside the block such as:
url varchar := http://www.ibm.com
is ignored. */

2-4

IBM Netezza Stored Procedures Developer's Guide

Block comments cannot be nested, but double dash comments can be enclosed in a
block comment. A double dash comment can hide the block comment delimiters
/* and */.

Variables and constants


All of the variables, rows, and records that are used in a block or its sub-blocks
must be declared in the declarations section of a block. There are some exceptions,
namely the loop variable of a FOR loop that iterates over a range of integer values,
and some built-in variables like FOUND, ROW_COUNT, and LAST_OID.
NZPLSQL variables can have any SQL data type, such as INTEGER, VARCHAR,
and CHAR. Some sample variable declarations follow:
user_id INTEGER;
quantity NUMERIC(5,2);
url VARCHAR;

A variable declaration has the following syntax:


name [ CONSTANT ] type [ NOT NULL ] [ { DEFAULT | := } value ];

v The DEFAULT clause, if included, specifies the initial value assigned to the
variable when the block is entered. If a DEFAULT clause is not specified, the
variable uses the SQL NULL value as its default.
v The CONSTANT option means that the variable cannot be changed; its value
remains constant for the duration of the block.
v If NOT NULL is specified, an assignment of a NULL value results in a runtime
error. Since the default value of all variables is the SQL NULL value, all
variables declared as NOT NULL must also specify a non-null default value.
When specifying types in declarations, NUMERIC can be specified with or without
a precision and scale. CHAR, NCHAR, VARCHAR, and NVARCHAR can be
specified with or without a size. When these types are specified with a size or a
precision/scale, assignment to the variable follows normal cast rules. If they are
specified without sizes, assignment preserves the original source size or
precision/scale.
The default value is evaluated each time the procedure is called. So assigning
now() to a variable of type timestamp causes the variable to be set to the time of
the actual procedure call, not the time when the procedure was precompiled into
its bytecode.
Some examples of variable assignments follow:
quantity INTEGER := 32;
url varchar := http://mysite.com;
user_id CONSTANT INTEGER := 10;

By using the %TYPE and %ROWTYPE attributes, you can declare variables with
the same data type or structure of another database item (for example, a table
field).
The %TYPE attribute provides the data type of a variable or database column. You
can use this attribute to declare variables that hold database values. For example, if
you have a column named user_id in your users table, you can declare a variable
with the same data type as user_id as follows:
user_id users.user_id%TYPE;

Chapter 2. NZPLSQL statements and grammar

2-5

By using %TYPE, you do not have to know the data type of the structure that you
are referencing. Also, if the data type of the referenced item changes in the future
(for example, you change your table definition of user_id to become a REAL), you
do not have to change your procedure definition.
You can declare a row with the structure of a table, as follows:
name table%ROWTYPE;

The table value must be an existing table or view name of the database. The fields
of the row are accessed by using the dot notation.
Only the user attributes of a table row are accessible in the row. You cannot access
an OID or other system attribute because the row could be from a view. The fields
of the row type inherit the sizes or precision for CHAR, NCHAR, and NUMERIC
data types from the table.

Parameter passing
In NZPLSQL, parameters are not named. Instead, only the data types are passed,
and parameters are referenced by their position.
To name parameters, use the ALIAS FOR syntax. For example:
CREATE OR REPLACE PROCEDURE p1 (int, varchar(ANY)) RETURNS int
LANGUAGE NZPLSQL AS
BEGIN_PROC
DECLARE
pId ALIAS FOR $1;
pName ALIAS FOR $2;
BEGIN
INSERT INTO t1 SELECT * FROM t2 WHERE id = pId;

The example highlights the recommended convention to name parameters with a


p prefix to differentiate them from variables. This convention is helpful because
parameters are constant and cannot be modified. If a parameter must be updated
(for example, to assign it a default value if it is null), assign the parameter to a
variable and update the variable. For example:
DECLARE
pId ALIAS FOR $1;
vID integer;
BEGIN
vId := ISNULL(pId, 0);
INSERT INTO t1 SELECT * FROM t2 WHERE id = vId;

Argument list and variables


The arguments passed as input to procedures can be identified by using the names
$1 (first argument), $2 (second argument), and so on. You can also use the $var
notation, which takes the integer value of var to identify the input value specified
in that order position.
You can specify 0 - 64 arguments. If you specify VARARGS in the input argument
list, users can input any number of arguments up to a maximum of 64.
IBM Netezza saves the OIDs of the input arguments in the
PROC_ARGUMENT_TYPES array. The array has the same size as the number of
parameters that are passed to the stored procedure. Its elements are of type OID
and contain the OID type of the corresponding input argument. You can use the
array to obtain the number and type of each argument.

2-6

IBM Netezza Stored Procedures Developer's Guide

For example:
CREATE OR REPLACE PROCEDURE test(VARARGS)
RETURNS INT4
LANGUAGE NZPLSQL
AS
BEGIN_PROC
DECLARE
num_args int4;
typ oid;
idx int4;
BEGIN
num_args := PROC_ARGUMENT_TYPES.count;
RAISE NOTICE Number of arguments: %, num_args;
for i IN 0 .. PROC_ARGUMENT_TYPES.count - 1 LOOP
typ := PROC_ARGUMENT_TYPES(i);
idx := i+1;
RAISE NOTICE argument $% is type % and has the value %,
idx, typ, $idx;
END LOOP;
END;
END_PROC;

A sample call follows:


MYDB.SCHEMA(USR2)=> CALL TEST (1, 3, 9::bigint, test value, 324.56);
NOTICE: Number of arguments: 5
NOTICE: argument $1 is type 23 and has the value 1
NOTICE: argument $2 is type 23 and has the value 3
NOTICE: argument $3 is type 20 and has the value 9
NOTICE: argument $4 is type 705 and has the value test value
NOTICE: argument $5 is type 1700 and has the value 324.56
test
-----(1 row)

Related concepts:
Variable arguments on page 3-7

Scope of variables
When you explicitly declare a new variable (or name), the scope of the variable is
the block in which it is defined.
For example, the following sample defines a variable named val in the DECLARE
section of the <<outer>> block, and then defines another val variable in the
DECLARE section of the <<inner>> block. Although the variables have the same
name, these variables are two different variables:
<<outer>>
DECLARE
val int4;
BEGIN
val := 5;
<<inner>>
DECLARE
val int4;
BEGIN
val := 7;
RAISE NOTICE inner val != outer val % %, val, outer.val;
END;
RAISE NOTICE outer val is 5 %, val;
END;

Chapter 2. NZPLSQL statements and grammar

2-7

In this example, the block labels inner and outer can be used to identify a specific
val variable by using its fully qualified variable name. If you create this procedure
as a stored procedure and run it, you would see output similar to the following:
MYDB.SCHEMA(USER)=> call vals();
NOTICE: inner val != outer val 7 5
NOTICE: outer val is 5 5
VALS
-----(1 row)

When you declare variables for loop iterators, the iterator variables have their own
unique scope. For example, you can use a variable named val as a loop iterator. By
using the same sample procedure, this would give you three unique val variables
in your procedure:
<<outer>>
DECLARE
val int4;
BEGIN
val := 5;
<<inner>>
DECLARE
val int4;
BEGIN
val := 7;
RAISE NOTICE inner val != outer val % %, val, outer.val;
FOR val IN 1 .. 10 LOOP
--Note that this is a NEW val variable for the loop.
RAISE NOTICE The value of val is %, val;
END LOOP;
RAISE NOTICE inner val is still 7. Value %, inner.val;
END;
RAISE NOTICE outer val is still 5. Value %, val;
END;

The following is sample output for this stored procedure:


MYDB.SCHEMA(USER)=> call vals();
NOTICE: inner val != outer val 7 5
NOTICE: The value of val is 1
NOTICE: The value of val is 2
NOTICE: The value of val is 3
NOTICE: The value of val is 4
NOTICE: The value of val is 5
NOTICE: The value of val is 6
NOTICE: The value of val is 7
NOTICE: The value of val is 8
NOTICE: The value of val is 9
NOTICE: The value of val is 10
NOTICE: inner val is still 7. Value 7
NOTICE: inner val is still 5. Value 5
VALS
-----(1 row)

As shown in the output, the val variable of the loop iterator has its own scope. It
has its own value and does not affect the other two val definitions. Within the
loop, if you need to call a specific variable that is defined outside the for loop, you
can use the fully qualified form of the variable name (label.variable).
Related concepts:
Iterative control on page 2-19

2-8

IBM Netezza Stored Procedures Developer's Guide

Data types and aliases


The following table lists the supported data types by their preferred name form,
and includes supported aliases and some notes about the values. For more
information about the data types and values, see the IBM Netezza Database Users
Guide.
Table 2-1. Supported data types for variables
Data type

Alias names

Notes

BOOLEAN

BOOL

A boolean field can store true values, false values, and null. You can use
the following words to specify booleans:
v true or false
v on or off
v 0 or 1
v 'true or false
v t or f
v on or off
v yes or no

CHAR

CHARACTER,
CHAR(n),
CHARACTER(n)

Fixed-length character string, blank padded to length n. If you do not


specify n, the default is an unsized CHAR value. The maximum
character string size is 64,000.

VARCHAR

CHARACTER
VARYING,
VARCHAR(n),
CHARACTER
VARYING(n), CHAR
VARYING(n)

Variable length character string to a maximum length of n. If you do not


specify n, the default is an unsized VARCHAR value. There is no blank
padding, and the value is stored as entered. The maximum character
string size is 64,000.

NCHAR

NATIONAL
CHARACTER,
NATIONAL CHAR(n),
NCHAR(size)

Fixed-length character string, blank padded to length n. If you do not


specify n, the default is an unsized NCHAR value. The maximum length
is 16,000 characters.

NVARCHAR

Variable length character string to a maximum length of n. If you do not


NATIONAL
specify n, the default is an unsized NVARCHAR value. The maximum
CHARACTER
VARYING, NATIONAL length is 16,000 characters.
CHAR VARYING,
NATIONAL CHAR
VARYING(n),
NATIONAL
CHARACTER
VARYING(n), and
NVARCHAR(n)

DATE
TIMESTAMP

Specifies a day with resolution that spans January 1, 0001 to December


31, 9999 (centered around 2000-01-01).
DATETIME

Has a date part and a time part, with seconds stored to 6 decimal
positions. The value represents the number of microseconds since
midnight 2000-01-01.
Min: -63,082,281,600,000,000 (00:00:00, 1/1/0001)
Max: 252,455,615,999,999,999 (23:59:59.999999, 12/31/9999)

TIME

TIME WITHOUT TIME Hours, minutes, and seconds to 6 decimal positions, ranging from
ZONE
00:00:00.000000 to 23:59:59.999999. This value is microsecond resolution
that represents the time of day only (midnight to one microsecond before
midnight).

Chapter 2. NZPLSQL statements and grammar

2-9

Table 2-1. Supported data types for variables (continued)


Data type

Alias names

Notes

INTERVAL

TIMESPAN

An interval of time. It has microsecond resolution and ranges from +/178000000 years. The time part represents everything but months and
years (microseconds) and the month part represents months and years.
For more information, see the section on IBM Netezza interval support
in the IBM Netezza Database Users Guide.

TIME WITH
TIME ZONE

TIMETZ

Hours, minutes, seconds to 6 decimal positions, and time zone offset


from GMT. Ranging from 00:00:00.000000+13:00 to 23:59:59.999999-12:59.

NUMERIC(p,s)

NUMERIC, DEC,
DEC(p,s),
DECIMAL(p,s),
DECIMAL

Fixed-point numeric types with precision p and scale s. Precision can


range from 1 to 38, scale from 0 to the precision.
NUMERIC(p) is equivalent to NUMERIC(p,0).
NUMERIC is an unsized numeric value.
Although decimal is sometimes a distinct SQL data type, Netezza SQL
treats it as an alias for NUMERIC.

REAL

FLOAT(p), FLOAT4

Floating point number with precision p. Precision values of 1 to 6 are


equivalent to FLOAT(6), and are stored as a 4-byte value.
Netezza SQL prefers the type name real, as float(p) is considered more of
an alias for the preferred form.

DOUBLE
PRECISION

DOUBLE, FLOAT,
FLOAT(p), FLOAT8

Floating point number with precision p, from 7 to 15. Precision values 7 15 are equivalent to 15 and are stored as an 8-byte value.
Netezza SQL prefers the type name double precision, as float(p) is
considered more of an alias for the preferred form.

INTEGER

INT, INT4

32-bit values in range 2,147,483,648 to 2,147,483,647

BYTEINT

INT1

8-bit values in the range 128 to 127

SMALLINT

INT2

16-bit values in range 32,768 to 32,767

BIGINT

INT8

64-bit values in range -9,223,372,036,854,775,808 to


9,223,372,036,854,775,807

Array variables
In addition to normal scalar variables, NZPLSQL also supports array variables. To
declare an array variable, use the following syntax:
name VARRAY(size) OF type;

All of the elements of the array are initially set to the SQL NULL value for the
declared type. To assign a value to an element, do the following:
name(idx) := value;

This syntax raises an exception if the index (idx) is out of bounds. The following
methods are supported:
name.EXTEND(size)
name.COUNT
name.TRIM(size)

The EXTEND method extends the array by the specified size. If size is omitted, the
default is 1.
COUNT returns the number of elements in the array.

2-10

IBM Netezza Stored Procedures Developer's Guide

TRIM deletes the last size elements in the array (the default is 1). TRIM and
EXTEND raise an exception if size is out of bounds.
Array references are allowed almost anywhere variable references are allowed,
with the following exceptions:
v As an argument to RAISE
v As an INTO variable
v As the variable in a FOR LOOP
v As part of a default value

Expressions
All expressions used in NZPLSQL statements are processed by using the backend
executor.
Expressions that appear to contain constants could require runtime evaluation (for
example, by using 'now()' for the timestamp type) so it is impossible for the
NZPLSQL parser to identify real constant values other than the NULL keyword.
All expressions are evaluated internally by running a query such as the following:
SELECT expression

In the expression, occurrences of variable identifiers are substituted by parameters


and the actual values from the variables are passed to the executor in the
parameter array. All expressions used in an NZPLSQL procedure are compiled and
cached the first time they are encountered. Everything in NZPLSQL is cached,
except for variable values and SQL plans. If there is a compile error (syntax error),
the expression is not cached. The cached copy is preserved until one of the
following happens:
v The procedure body is modified.
v The procedure is dropped.
v The database session ends.
The type checking done by the IBM Netezza SQL main parser has some side
effects for the interpretation of constant values. For example, the following two
examples are different in how constant values are interpreted. The first example
follows:
DECLARE
logtxt ALIAS FOR $1;
BEGIN
INSERT INTO logtable VALUES (logtxt, now());
RETURN now();
END;

The second example follows:


DECLARE
logtxt ALIAS FOR $1;
curtime timestamp;
BEGIN
curtime := now();
INSERT INTO logtable VALUES (logtxt, curtime);
RETURN curtime;
END

In the first example, when the Netezza SQL main parser prepares the plan for the
INSERT, it interprets now() as a timestamp because the target field of logtable is of
that type. It interprets both instances of now() each time it runs.
Chapter 2. NZPLSQL statements and grammar

2-11

In the second example, the Netezza SQL main parser does not know what type
now() should become and therefore it returns a data type of text that contains the
string now(). During the assignment to the local variable curtime, the NZPLSQL
interpreter casts this string to the timestamp type by calling the text_out() and
timestamp_in() functions for the conversion.
If record fields are used in expressions or statements, the data types of fields
should not change between calls to the same expression or statement.

Literals and math operations in expressions


If your stored procedures perform math operations in expressions, carefully
consider the supported ranges for literals and the possible implicit typecasts that
the IBM Netezza system might perform. These ranges and behaviors can cause
unexpected results or overflow errors in complex math expressions.
The Netezza system checks for overflows when performing integer arithmetic. For
example, all integer literals are 32-bit (signed) numbers by default, which supports
a range of values from -2147483648 to 2147483647. If you perform math operations
on a literal, the system checks for and returns an error if it detects an overflow. For
example, the following stored procedure defines a numeric value n, assigns it the
largest supported value (2147483647) and then adds 1 to the value:
CREATE OR REPLACE PROCEDURE num() RETURNS BOOL LANGUAGE NZPLSQL AS
BEGIN_PROC
DECLARE
n NUMERIC;
BEGIN
n := 2147483647;
RAISE NOTICE n is %, n;
n := 2147483647 + 1;
RAISE NOTICE n is %, n;
END;
END_PROC;

If you create and run this stored procedure, the procedure fails and returns an
integer overflow error:
NOTICE: n is 2147483647
NOTICE: Error occurred while executing PL/pgSQL function NUM
NOTICE: line 6 at assignment
ERROR: overflow in 32 bit arithmetic

To avoid an overflow condition, you can use a cast operation to cast n to a higher
precision type, or assign values to intermediate values. For example, the following
stored procedure creates the overflow issue for the numeric value n but uses casts
to numerics or bigints to increase the range of valid values:
CREATE OR REPLACE PROCEDURE num() RETURNS BOOL LANGUAGE NZPLSQL AS
BEGIN_PROC
DECLARE
n NUMERIC;
BEGIN
n := 2147483647;
RAISE NOTICE n is %, n;
n := 2147483647::numeric + 1;
RAISE NOTICE n is %, n;
n := 2147483647::bigint + 1;
RAISE NOTICE n is %, n;
END;
END_PROC;

2-12

IBM Netezza Stored Procedures Developer's Guide

If you create and run this stored procedure, the output would be similar to the
following:
NOTICE:
NOTICE:
NOTICE:

n is 2147483647
n is 2147483648
n is 2147483648

As this example shows, explicit casts during arithmetic evaluations and careful use
of literals, constants, and types can help to increase the accuracy of the expressions
used in your stored procedures.
If you use floating point numbers in expressions, Netezza attempts to cast it into a
numeric if possible, with a specific precision and scale that it calculates with
internally defined casting rules.
Because arithmetic operations in a stored procedure are evaluated by invoking the
backend executor, they are processed as SELECT statements. To more clearly see
the calculated shape of the expression result, it can be helpful to use it to create a
table, which can then be described by using the \d command. Printing the results
might not provide enough insight to the resulting data types.
In the arithmetic expression that follows, Netezza casts the precision and scale
based on internal Netezza SQL behavior rules:
DEV.SCH1(ADMIN)=> create table test as select (1 + 0.08/365) interest;
INSERT 0 1
DEV.SCH1(ADMIN)=> \d test
Table "TEST"
Attribute |
Type
| Modifier | Default Value
----------+--------------+----------+--------------INTEREST | NUMERIC(8,6) |
|
Distributed on hash: "INTEREST"

In the sample table, the Netezza internal casting rules evaluated the expression
1+0.08/365 and determined that the field would be a numeric value with 8
digits of precision and 6 digits of scale. The following command shows the actual
value saved in the row:
DEV.SCH1(ADMIN)=> select * from TEST;
INTEREST
---------1.000219
(1 row)

Another example follows:


DEV.SCH1(ADMIN)=> create table test2 as select (4 + 1/5) loanrt;
INSERT 0 1
DEV.SCH1(ADMIN)=> \d test2
Table "TEST2"
Attribute | Type
| Modifier | Default Value
----------+----------+----------+--------------LOANRT
| INTEGER |
|
Distributed on hash: "LOANRT"

In the previous example, Netezza is evaluating three integer values (4, 1, and 5).
The Netezza system uses integer as the type for the new column. If you display
the column value, as follows, you can see that the decimal portion of the value
was truncated:

Chapter 2. NZPLSQL statements and grammar

2-13

DEV.SCH1(ADMIN)=> select * from TEST2;


LOANRT
-------4
(1 row)

A similar example follows, but instead of the expression 1/2, this expression uses
the numeric value .5 instead, as follows:
DEV.SCH1(ADMIN)=> create table test3 as select (4 + .5) loanrt;
INSERT 0 1
DEV.SCH1(ADMIN)=> \d test3
Table "TEST3"
Attribute |
Type
| Modifier | Default Value
----------+---------------+----------+--------------LOANRT
| NUMERIC(3,1) |
|
Distributed on hash: "LOANRT"
DEV.SCH1(ADMIN)=> select * from TEST3;
LOANRT
-------4.5
(1 row)

In this example, the .5 value is interpreted as 0.5, and thus cast to numeric(3,1).
In addition to the casts that can occur when math expressions are parsed, Netezza
functions can also cause an implicit typecast. For example, the function sqrt()
takes and returns a double precision value. The following example uses the
function to define a table column:
DEV.SCH1(ADMIN)=> create table test4 as select (sqrt(42));
INSERT 0 1
DEV.SCH1(ADMIN)=> \d test4
Table "TEST4"
Attribute |
Type
| Modifier | Default Value
----------+------------------+----------+--------------SQRT
| DOUBLE PRECISION |
|
Distributed on hash: "SQRT"
DEV.SCH1(ADMIN)=> select * from TEST4;
SQRT
----------------6.4807406984079
(1 row)

In the test4 example, the sqrt() function causes Netezza to cast the input integer
value to a double and to return a double.
Remember these behaviors when you work with stored procedures that use
arithmetic expressions to evaluate data. The implicit casts might not provide the
value that you would expect if you evaluated the same arithmetic expression with
a calculator. An example follows:
CREATE OR REPLACE PROCEDURE sp_expressions_numeric02() RETURNS NUMERIC
LANGUAGE NZPLSQL AS
BEGIN_PROC
DECLARE
thisnum9_2 NUMERIC(9,2);
million NUMERIC(9,2) := 1000000.00;
thisnum18 NUMERIC(18);
litespeed NUMERIC := 186282;
thisnum38 NUMERIC(38);
BEGIN
/* The following expression causes implicit casts in the math
evaluation, reducing the precision and scale of the result. */
thisnum9_2 := million * (1 + 0.08/365)^(365 * 20);

2-14

IBM Netezza Stored Procedures Developer's Guide

RAISE NOTICE thisnum9_2 == %, thisnum9_2;


/* The following expression uses an explicit cast to increase
the precision and scale of the intermediate evaluation. */
thisnum9_2 := million * (1 + 0.08::numeric(20,15)/365)^(365 * 20);
RAISE NOTICE thisnum9_2 == %, thisnum9_2;
/* The following expression uses the numeric literal litespeed to
convert the speed of light from miles per sec to miles per
year. */
thisnum18 := litespeed * 60 * 60 * 24 * 365.25;
RAISE NOTICE thisnum18 == %, thisnum18;
/* The following expression uses the integer 186282 to convert
lightspeed from miles per sec to miles per year. In the
right-side evaluation, however, the values overflowed the
upper limit of an int several times during evaluation,
which causes an overflow error. */
thisnum38 := 186282 * 60 * 60 * 24 * 365.25;
RAISE NOTICE thisnum38 == %, thisnum38;
END;
END_PROC;

Sample output follows:


NOTICE: thisnum9_2 == 4945731.93
NOTICE: thisnum9_2 == 4952164.15
NOTICE: thisnum18 == 5878612843200
NOTICE: Error occurred while executing PL/pgSQL function SP_EXPRESSIONS_NUMERIC02
NOTICE: line 16 at assignment
ERROR: overflow in 32 bit arithmetic

Statements
This section describes the types of statements that are explicitly understood by the
NZPLSQL parser. Any statements that are not specified by using these conventions
(and thus are not understood by the NZPLSQL parser) are assumed to be SQL
commands and sent to the database engine to execute. The resulting query should
not return any data.

Assignment
To assign a value to a variable or row/record field, use the assignment statement
as follows:
identifier := expression;

If the expressions result data type does not match the variables data type but the
types are compatible, or the variable has a size/precision that is known (as for
char(20)), the result value is implicitly cast by the NZPLSQL bytecode interpreter
using the result types output-function and the variables type input-function. Note
that this could potentially result in runtime errors generated by the types input
functions.
Several examples follow:
user_id := 20;
tax := subtotal * 0.06;

For more information about IBM Netezza casting rules and behaviors, see the IBM
Netezza Database Users Guide.

Chapter 2. NZPLSQL statements and grammar

2-15

Call another procedure


All procedures defined in an IBM Netezza database return a value; the default
value is NULL. Thus, the normal way to call a procedure is to run a SELECT
query or to do an assignment (resulting in an NZPLSQL internal SELECT).
However, there are cases where you might not be concerned with the result of the
procedure. In these cases, use the CALL statement to call the procedure, as follows:
CALL query

The CALL statement runs a SELECT query and discards the result. Identifiers such
as local variables are still substituted into input parameters.
There is a maximum stored procedure call recursion limit of 1024. If the call
recursion exceeds this value, the following error message is returned:
ERROR:

stored procedure recursion limit exceeded

Run dynamic queries


There might be times when you want to generate dynamic queries inside your
NZPLSQL procedures. Or, you might have procedures that are designed to
generate other procedures. For these situations, NZPLSQL provides the EXECUTE
IMMEDIATE statement:
EXECUTE IMMEDIATE query-string

The query-string value is a string of type text which contains the query to be
executed.
When working with dynamic queries, make sure that you escape any quotation
marks in NZPLSQL.
A query run by an EXECUTE IMMEDIATE statement is prepared each time the
statement is run. The query string can be dynamically created within the procedure
to do actions on different tables and fields.
The results from SELECT queries are discarded by EXECUTE IMMEDIATE, and
SELECT INTO is not currently supported within EXECUTE IMMEDIATE. So, the
only way to extract a result from a dynamically created SELECT is to use the FOR
... EXECUTE form, described in Iterate through the records of a query on page
2-21.
An example statement follows:
EXECUTE IMMEDIATE UPDATE tbl SET
|| quote_ident(fieldname)
|| =
|| quote_literal(newvalue)
|| WHERE ...;

This example demonstrates the use of the quote_ident and quote_literal


functions. To ensure that strings are correctly processed for quotation marks or
special characters, expressions that contain column and table identifiers should be
passed to quote_ident. Expressions containing values that are literal strings in the
constructed command should be passed to quote_literal. Both take the
appropriate steps to return the input text enclosed in double quotation marks for
quote_ident or quotation marks for quote_literal with any embedded special
characters properly escaped.

2-16

IBM Netezza Stored Procedures Developer's Guide

Obtain other results status


There are two variables that provide system status indicators: ROW_COUNT and
LAST_OID.
v ROW_COUNT is the number of rows processed by the last SQL query sent
down to the SQL engine.
v LAST_OID is the object ID (oid) of the last row inserted by the most recent SQL
query.
LAST_OID is useful only after an INSERT query, and then only when the insert
happens on a catalog table. In practice, LAST_OID is not likely to be useful.
In addition to these variables, you can also use the FOUND and IS NULL variables
to do special conditional processing based on record results.
Related concepts:
Assignments on page 2-20

Return from a procedure


Use the RETURN command to return data from a procedure.
RETURN [expression]

The procedure terminates and the value of expression is returned to the upper
executor. If expression is not provided, NULL is assumed.
The return value of a procedure can be undefined. If control reaches the end of the
top-level block of the procedure without encountering a RETURN statement,
NULL is assumed. The result of the expression is automatically cast into the return
type of the procedure as described for assignments.

Control Structures
Control structures are a useful and important part of the NZPLSQL language. You
can use NZPLSQL control structures to manipulate SQL data in a flexible and
powerful way.

Conditional control
You use IF statements to take action based on certain conditions. NZPLSQL has
three forms of IF statements:
v IF-THEN
v IF-THEN-ELSE
v IF-THEN-ELSE IF
All NZPLSQL IF statements require a corresponding END IF statement. In ELSE-IF
statements, you need two END IF statements: one for the first IF and one for the
second (ELSE IF).

IF-THEN statements
IF-THEN statements are the simplest form of an IF statement. The statements
between THEN and END IF are executed if the condition is true. Otherwise, the
statements that follow the END IF are executed. An example follows:
IF v_user_id <> 0 THEN
UPDATE users SET email = v_email WHERE user_id = v_user_id;
END IF;
Chapter 2. NZPLSQL statements and grammar

2-17

IF-THEN-ELSE statements
IF-THEN-ELSE statements add an ELSE branch for cases when the IF-THEN
condition evaluates to FALSE. You can specify the statements to run in the ELSE
section. For example:
IF parentid IS NULL or parentid =
THEN
return fullname;
ELSE
return hp_true_filename(parentid) || / || fullname;
END IF;
IF v_count
INSERT
return
ELSE
return
END IF;

> 0 THEN
INTO users_count(count) VALUES(v_count);
t;
f;

You can nest IF statements as in the following example:


IF movies.genre = d THEN
film_genre := drama;
ELSE
IF movies.genre = c THEN
film_genre := comedy;
END IF;
END IF;

IF-THEN-ELSE IF statements
When you use the "ELSE IF" statement, you are nesting an IF statement inside the
ELSE statement. Thus, you need one END IF statement for each nested IF and one
for the parent IF-ELSE. For example:
IF movies.genre = d THEN
film_genre := drama;
ELSE IF movies.genre = c THEN
film_genre := comedy;
END IF;
END IF;

While this form works, it can become a little tedious and error-prone if there are
many alternatives to check. Thus, the language offers the alternative syntax by
using ELSIF or ELSEIF, as follows:
IF movies.genre = d THEN
film_genre := drama;
ELSIF movies.genre = c THEN
film_genre := comedy;
ELSIF movies.genre = a THEN
film_genre := action;
ELSIF movies.genre = n THEN
film_genre := narrative;
ELSE
-- An uncategorized genre form has been requested.
film_genre := Uncategorized;
END IF;

The IF-THEN-ELSIF-ELSE form offers some flexibility and eases the coding process
when you need to check many alternatives in one statement. While it is equivalent
to nested IF-THEN-ELSE-IF-THEN commands, it needs only one END IF
statement.

2-18

IBM Netezza Stored Procedures Developer's Guide

Iterative control
With the LOOP, WHILE, FOR, and EXIT statements, you can control the flow of
execution of your NZPLSQL program iteratively.

LOOP statement
The LOOP statement defines an unconditional loop that repeats until terminated
by an EXIT statement or a RETURN statement (which terminates the procedure
and the loop). It has the following syntax:
[<<label>>]
LOOP
statements
END LOOP;

The optional label can be used by EXIT statements of nested loops to specify which
level of nesting is terminated.

EXIT statement
The EXIT statement terminates a loop. It has the following syntax:
EXIT [ label ] [ WHEN expression ];

If you do not specify a label, the innermost loop is terminated and the statement
that follows END LOOP runs next. If you specify a label, it must be the label of
the current or an upper level of nested loop or blocks. Then the named loop or
block is terminated and control continues with the statement after the
corresponding END of the loop or blocks.
Examples:
LOOP
-- some computations
IF count > 0 THEN
EXIT; -- exit loop
END IF;
END LOOP;
LOOP
-- some computations
EXIT WHEN count > 0;
END LOOP;
BEGIN
-- some computations
IF stocks > 100000 THEN
EXIT;
END IF;
END;

WHILE statement
With the WHILE statement, you can loop through a sequence of statements if the
evaluation of the condition expression is true.
[<<label>>]
WHILE expression LOOP
statements
END LOOP;

For example:
Chapter 2. NZPLSQL statements and grammar

2-19

WHILE amount_owed > 0 AND gift_certificate_balance > 0 LOOP


-- some computations here
END LOOP;
WHILE NOT boolean_expression LOOP
-- some computations here
END LOOP;

FOR statement
By using the FOR statement, you can create a loop that iterates over a range of
integer values.
[<<label>>]
FOR name IN [ REVERSE ] expression .. expression LOOP
statements
END LOOP;

The variable name is automatically created as type integer and exists only inside
the loop. The two expressions for the lower and upper bound of the range are
evaluated only when entering the loop. The iteration step is always 1.
Some examples of FOR loops:
FOR i IN 1 .. 10 LOOP
-- some expressions here
RAISE NOTICE i is %,i;
END LOOP;
FOR i IN REVERSE 10 .. 1 LOOP
-- some expressions here
END LOOP;

Related concepts:
Scope of variables on page 2-7

Records
Records are similar to row types, but they have no predefined structure. They are
used in selections and FOR loops to hold one database row from a SELECT
operation.

Declaration
Variables of type RECORD can be used for different selections. Accessing a record
or an attempt to assign a value to a record field when there is no row in it results
in a runtime error. To declare a RECORD variable:
name RECORD;

Assignments
You can use the following query to assign a complete selection into a record or
row:
SELECT expressions INTO target FROM ...;

The target value can be a record, a row variable, or a comma-separated list of


variables and record-fields or row-fields. This interpretation is different from the
SQL interpretation of SELECT INTO, which is that the INTO target is a newly
created table. (If you want to create a table from a SELECT result inside an
NZPLSQL procedure, use the equivalent syntax CREATE TABLE AS SELECT.)

2-20

IBM Netezza Stored Procedures Developer's Guide

If a row or a variable list is used as the target, the selected values must exactly
match the structure of the target or targets, or a runtime error occurs. The FROM
keyword can be followed by any valid qualification, grouping, or sorting that can
be given for a SELECT statement.
After a record or row is assigned to a RECORD variable, you can use the "." (dot)
notation to access fields in that record as follows:
DECLARE
users_rec RECORD;
full_name varchar;
BEGIN
SELECT * INTO users_rec FROM users WHERE user_id=3;
full_name := users_rec.first_name || || users_rec.last_name;

There is a special variable named FOUND of type boolean that can be used
immediately after a SELECT INTO to check whether an assignment was successful.
The following example uses the NOT FOUND form to raise an exception if a
SELECT INTO statement does not match on the requested input name:
SELECT * INTO myrec FROM EMP WHERE empname = myname;
IF NOT FOUND THEN
RAISE EXCEPTION employee % not found, myname;
END IF;

FOUND is very similar to ROW_COUNT. For example, the following statement:


IF FOUND

is equivalent to this statement:


IF ROW_COUNT >= 1

You can also use the IS NULL (or ISNULL) conditionals to test whether a RECORD
or ROW is NULL. If the selection returns multiple rows, only the first is moved
into the target fields. All others are silently discarded. For example:
DECLARE
users_rec RECORD;
full_name varchar;
BEGIN
SELECT * INTO users_rec FROM users WHERE user_id=3;
IF users_rec.homepage IS NULL THEN
-- user entered no homepage, return "http://"
return http://;
END IF;
END;

Related concepts:
Obtain other results status on page 2-17

Iterate through the records of a query


By using a special type of FOR loop, you can iterate through the results of a query
and manipulate that data. The FOR IN loop syntax is as follows:
[<<label>>]
FOR record | row IN select_clause LOOP
statements
END LOOP;

The record or row is assigned all the rows that result from the select clause and the
loop body runs for each. An example follows:

Chapter 2. NZPLSQL statements and grammar

2-21

DECLARE
mviews RECORD;
-- Instead, if you did:
-- mviews cs_materialized_views%ROWTYPE;
-- this record is ONLY usable for the cs_materialized_views table
BEGIN
CALL cs_log(Refreshing materialized views...);
FOR mviews IN SELECT * FROM cs_materialized_views ORDER BY sort_key LOOP
-- Now "mviews" has one record from cs_materialized_views
RAISE EXCEPTION, Cant execute SQL while processing SQL for %,
mview.my_name;
END LOOP;
CALL cs_log(Done refreshing materialized views.);
return 1;
end;

If the loop is terminated with an EXIT statement, the last assigned row is still
accessible after the loop.
The FOR-IN EXECUTE statement is another way to iterate over records:
[<<label>>]
FOR record | row IN EXECUTE text_expression LOOP
statements
END LOOP;

This form is similar to the previous form, except that the source SELECT statement
is specified as a string expression. The main difference between the two is the
syntax and use of variables to build the SQL to run. The first form is faster to
evaluate.

Report messages and raise errors


Use the RAISE statement to report messages and raise errors.
The statement syntax follows:
RAISE level format [, identifier [...]];

Inside format, the percent character (%) is used as a placeholder for a subsequent,
comma-separated identifier. You can specify more than one % and identifier pair,
as follows:
RAISE NOTICE Welcome % %, firstname, lastname;

In this example, the notice message substitutes the value of firstname for the first
% character, and substitutes the value of lastname for the second % character.
The message levels are as follows:
v DEBUG messages are written only to pg.log.
v NOTICE messages are written to the database log and forwarded to the client
application.
v EXCEPTION messages are written to the database log, forwarded to the client
application as non-fatal messages, and usually abort the transaction if they are
not caught.
The following is an example of a RAISE statement:
RAISE NOTICE Calling cs_create_job(%), job_id;

2-22

IBM Netezza Stored Procedures Developer's Guide

In the example, job_id replaces the % in the string and display the message to the
client and in pg.log.
RAISE EXCEPTION Inexistent ID --> %, user_id;

This EXCEPTION statement aborts the transaction (if the exception is not caught)
and writes the message to the database log.

Exceptions and error messages support


Any error that occurs in an NZPLSQL procedure aborts the execution of the
procedure, and it aborts the surrounding transaction as well. The system returns to
the main loop to obtain the next query from the client application. It is not possible
to catch all exceptions, especially if that action leaves the database in a bad state.
To catch and process an error that occurs in a procedure block, you can add an
exception-handling section at the end of a block by using the EXCEPTION
keyword. If no error occurs, the exception-handling section is ignored. Within the
exception-handling section, you can specify one or more exception handlers by
using WHEN clauses that specify the exception to match and the statements to run
when a match occurs. An EXCEPTION statement has the following form:
EXCEPTION
WHEN clause THEN
statements
[ WHEN ... ]

The NZPLSQL supports two clauses for exception processing:


TRANSACTION_ABORTED
Use the TRANSACTION_ABORTED clause to specify the statements that
you want to run when an error occurs that causes the transaction to abort.
In this case, a ROLLBACK is required to continue. Make sure that the
ROLLBACK command is the first command in the exception handling
statements.
OTHERS
Use the OTHERS clause to specify the statements to run when any error
occurs within the procedure block. Errors such as a SQL parsing error do
not abort the transaction, and thus would not match a
TRANSACTION_ABORTED clause.
You can specify both clauses in an exception block, as in the following example.
When an error occurs in the procedure, the procedure code uses the first matching
exception clause and executes the statements in that clause. Any clauses after the
match are ignored. As a best practice, specify the OTHERS clause last because it
matches any type of error.
EXCEPTION
WHEN TRANSACTION_ABORTED THEN
ROLLBACK;
statements_case1
RAISE ERROR Procedure failed: %, sqlerrm;
WHEN OTHERS THEN
statements_case2
RAISE NOTICE Caught error, continuing %, sqlerrm;

In this example, an error that aborts a transaction triggers the


TRANSACTION_ABORTED clause and the stored procedure executes the
ROLLBACK, the statements in statements_case1, and raises the error message. If
the error did not cause the transaction to abort, the exception processing skips to
Chapter 2. NZPLSQL statements and grammar

2-23

the OTHERS clause and the stored procedure runs the statements_case2 set and
raises the notice message. If there were no errors in the block, the exception
statements are skipped.
The variable SQLERRM contains the text of an error message that is caught. In the
absence of an exception block, the exception propagates up to the next stored
procedure in the call stack. If sproc1 calls sproc2, which generates an exception,
but sproc2 does not have an exception handler, then the system looks for a handler
in sproc1. The system also looks at the enclosing block declarations.
For example:
create or replace procedure sp_except01() returns BOOL LANGUAGE
NZPLSQL AS
BEGIN_PROC
DECLARE
r record;
BEGIN
<<inner>>
BEGIN
SELECT * INTO r FROM NONEXISTENT;
END;
END;
END_PROC;
create or replace procedure sp_except02() returns BOOL LANGUAGE
NZPLSQL AS
BEGIN_PROC
BEGIN
CALL sp_except01();
END;
END_PROC;
create or replace procedure sp_except03() returns BOOL LANGUAGE
NZPLSQL AS
BEGIN_PROC
BEGIN
CALL sp_except02();
EXCEPTION WHEN OTHERS THEN
RAISE NOTICE Caught exception;
END;
END_PROC;

In these examples, the exception is generated in sp_except01, in the block inner.


The system first checks for an exception handler for block inner, which is not
found. Control passes to the parent context, which is the procedure sp_except01,
and an exception handler is also not found there. Control then passes to
sp_except02, and finally sp_except03, where an exception handler is found and
used.
If an exception is not caught at any level, additional NOTICE-level log messages
are sent to provide context about the error and where it occurred (line number and
type of statement, unless the error is from a RAISE EXCEPTION statement).
If you include exception handlers in stored procedures, the handlers catch any
errors and the errors are not displayed. For example:
CREATE PROCEDURE sp() RETURNS INTEGER LANGUAGE NZPLSQL AS
BEGIN_PROC
BEGIN

2-24

IBM Netezza Stored Procedures Developer's Guide

EXECUTE IMMEDIATE insert into NOTEXIST || values(1,1);


EXCEPTION WHEN OTHERS THEN
END;
END_PROC;

Assuming that NOTEXIST does not exist in the database, the query does not
display any error output because the error was handled by the exception handler.
To display the error, write the procedure as follows:
CREATE PROCEDURE sp() RETURNS INTEGER LANGUAGE NZPLSQL AS
BEGIN_PROC
BEGIN
EXECUTE IMMEDIATE insert into NOTEXIST || values(1,1);
EXCEPTION WHEN OTHERS THEN
RAISE NOTICE Got exception: %, SQLERRM;
END;
END_PROC;

When you run this query, it displays the following output:


NOTICE:

Got exception: ERROR:

Relation NOTEXIST does not exist

Return a result set


Typically, an NZPLSQL procedure returns a unique return value, but it can also
return a result set in the form of a specified table.
To create a stored procedure that returns a result set:
v Define the stored procedure with a return value of RETURNS REFTABLE
(<table-name>) to indicate that it returns a result set that looks like the
specified table.
v Inside the body of the procedure, use the variable REFTABLENAME to refer to
the results table.
The table specified in the RETURNS value must exist at the time that the stored
procedure is created, although the table can be empty. The table continues to exist
after the stored procedure completes. You cannot drop the reference table while the
stored procedure is defined. (That is, you must drop the stored procedure or
modify it to return a different reference table before you can drop the table.)
For example, the following stored procedure, returntwo, returns a result set by
using the reference table feature. The reference table that it uses, tbl, was
previously defined by using the following command:
CREATE TABLE tbl (i INT4, i2 bigint);

A description of tbl follows:


DEV.SCH1(ADMIN)=> \d tbl
Table "TBL"
Attribute | Type | Modifier | Default Value
-----------+---------+----------+--------------I
| INTEGER |
|
I2
| BIGINT |
|
Distributed on hash: "I"

After you confirm that the reference table exists, you can use the following
command to define the stored procedure returntwo:
DEV.SCH1(ADMIN)=> CREATE OR REPLACE PROCEDURE returntwo(timestamp) RETURNS
REFTABLE(tbl) LANGUAGE NZPLSQL AS
BEGIN_PROC
Chapter 2. NZPLSQL statements and grammar

2-25

BEGIN
EXECUTE IMMEDIATE INSERT INTO || REFTABLENAME || values (1,1);
EXECUTE IMMEDIATE INSERT INTO || REFTABLENAME || values (2,2);
RETURN REFTABLE;
END;
END_PROC;

A sample call to the returntwo stored procedure follows:


DEV.SCH1(ADMIN)=> EXECUTE PROCEDURE returntwo(now());
I | I2
---+---1 | 1
2 | 2
(2 rows)

Restriction: You cannot specify a WHERE clause in a query that calls a stored
procedure that returns a result set.
When you call or invoke the stored procedure by using a SQL command such as
SELECT procedure(), CALL procedure(), EXECUTE procedure(), and so on, the
database does the following:
v Generates a table name TEMPFUNC<oid> where oid is the object ID of the
procedure that was invoked
v Checks if the table name exists; if it does, it issues a DROP TABLE
<temp-table-name> command
v Issues a CREATE TEMPORARY TABLE <temp-table-name> as select * from
<table-name> LIMIT 0 to create the table for the results set with no initial
contents
v Returns the results of SELECT * from <temp-table-name> where proc(args) is
NULL (This situation is the only situation in which a stored procedure is
allowed to be invoked with a FROM clause and where the return value is used
as part of a query.)
To use this in a procedure, you must insert your results in <temp-table-name> by
using the REFTABLENAME variable to obtain the name. This SQL command must
be invoked dynamically to use the variable.
Additionally, you must return NULL in your procedure by one of the following
means:
v RETURN REFTABLE;
v RETURN NULL;
v RETURN;
v Not specifying a RETURN clause.
If you do not return NULL, the procedure returns an error. The recommended
method to return NULL is RETURN REFTABLE.
One REFTABLE procedure can call another, but you encounter unusual results if a
REFTABLE procedure calls itself (either directly or recursively) because of the
temporary table logic; therefore, avoid designing a REFTABLE procedure which
calls itself.
Cross-database access for a REFTABLE procedure should work without problem as
the temporary table will be created in the local database; it will retrieve the shape
of the REFTABLE definition in the other database.

2-26

IBM Netezza Stored Procedures Developer's Guide

The SQL that is executed (for example, CREATE TEMPORARY TABLE, DROP
TABLE) uses the owner ID of the procedure as the effective user ID if EXECUTE
AS OWNER is set; otherwise, if EXECUTE AS CALLER is set, the SQL uses the
user ID of the account which calls or invokes the procedure.

REFTABLE and ROLLBACK commands


If a stored procedure returns a result set (REFTABLE), do not issue a ROLLBACK
command inside the procedure body unless you first issue a COMMIT to create
the temporary table for REFTABLE. Issuing a ROLLBACK without the prior
COMMIT command causes your REFTABLE procedure to fail when executed.
As a best practice, if your procedure body includes a ROLLBACK command, or if
you call another procedure that could issue a ROLLBACK, specify the COMMIT
command as the first statement in the REFTABLE procedure body. An example
follows:
DEV.SCH1(ADMIN)=> CREATE OR REPLACE PROCEDURE returntwo(timestamp) RETURNS
REFTABLE(tbl) LANGUAGE NZPLSQL AS
BEGIN_PROC
BEGIN
COMMIT;
EXECUTE IMMEDIATE INSERT INTO || REFTABLENAME || values (1,1);
EXECUTE IMMEDIATE INSERT INTO || REFTABLENAME || values (2,2);
EXECUTE IMMEDIATE INSERT INTO || REFTABLENAME || values (3,3);
COMMIT;
EXECUTE IMMEDIATE INSERT INTO || REFTABLENAME || values (4,4);
ROLLBACK
RETURN REFTABLE;
END;
END_PROC;
DEV.SCH1(ADMIN)=> EXECUTE returntwo(now());
I | I2
---+---2 | 2
1 | 1
3 | 3
(3 rows)

As shown in the example, your procedure can call the COMMIT command as
needed, but the first COMMIT ensures that the temporary table exists for
processing within the body.
The following message is an example of the error that occurs when the
ROLLBACK ran without a prior COMMIT:
DEV.SCH1(ADMIN)=> EXECUTE returntwo(now());
NOTICE: Error occurred while executing PL/pgSQL function RETURNTWO
NOTICE: line 1 at SQL statement
ERROR: Cannot use ROLLBACK from within a stored procedure which uses
a REFTABLE without a COMMIT first.

Manage large data sets


If users run stored procedures on large data sets, there might be situations where
there is not enough memory to hold the results of a select on that table. For
example, some stored procedures can read each record from a table and take action
on each record:

Chapter 2. NZPLSQL statements and grammar

2-27

FOR rec in SELECT * from tablenm LOOP


--perform processing steps
END LOOP:

The SELECT operation runs first and caches its results in memory or as a
temporary file on disk, depending upon the size of the result set. The procedure
then applies the steps in the inner processing loop.
If the table (tablenm) is very large, such as a table with millions of rows or one
with many thousands of large rows, the temporary file can be a huge file that uses
the free disk space on the IBM Netezza host. Use caution when your stored
procedures process very large tables.
Note: In the Netezza environment, these types of select loops that operate on
single rows are not optimized for performance in the Netezza environment. Where
possible, recast the loop to operate on record sets.
Related concepts:
Tips and best practices for stored procedures

Advanced development topics


This section describes some topics that show how you can take advantage of
user-defined functions and stored procedures to perform advanced programming
and scripting on the Netezza system.

Extend the NZPLSQL language with UDFs


If you or other users at your site create user-defined functions (UDFs) for your
IBM Netezza systems, you can use UDFs to extend the NZPLSQL language. These
UDFs must be invoked by using SQL that is designed to run only on the Netezza
host inside Postgres. For details about the use of UDFs to extend NZPLSQL, see
the IBM Netezza User-Defined Functions Developers Guide.

Tips and best practices for stored procedures


This section describes some common tips and best practices for stored procedures.

Control-C interrupt processing in loops


If the procedure encounters an infinite loop, you can press Control-C to interrupt
the loop. This key sequence should cause an exception (which is not catchable) and
thus cause the loop and the procedure call to be interrupted and return.

Query processing in loops


Within stored procedures, there can be loop designs that appear to use concurrent
queries to process the results. For example, the following procedure uses a SELECT
to gather information, which is then processed for a possible DELETE action:
FOR rec in SELECT * from mytable LOOP
IF rec.type = 'd' THEN
EXECUTE IMMEDIATE 'DELETE FROM mytable2 WHERE recid = ' || rec.id;
END IF;
END LOOP;

While it appears that the outer FOR loop SELECT and the inner EXECUTE
IMMEDIATE queries are running at the same time, the SELECT query finishes and

2-28

IBM Netezza Stored Procedures Developer's Guide

caches its results before the inner query begins. Thus, deleting records from the
table in the inner loop does not affect the SELECT query in the outer loop or
change its results.
Note: Although it can be common to run row-at-a-time operations, as used in the
preceding example, you can significantly improve the performance of these
procedures by designing them to operate on sets of records rather than single row
operations. For example, if you recast the previous example to the following:
DELETE from mytable2 where recid in (select recid from my table
where type = d) ;

This procedure design can take advantage of the IBM Netezza massively parallel
processing (MPP) environment to run much quicker.
Related concepts:
Manage large data sets on page 2-27

Chapter 2. NZPLSQL statements and grammar

2-29

2-30

IBM Netezza Stored Procedures Developer's Guide

Chapter 3. Create and manage stored procedures


This section describes the basic management and user tasks associated with stored
procedures, such as managing permissions, creating procedures, invoking
procedures, and altering and dropping stored procedures.
Related concepts:
SQL commands for stored procedures on page 1-2

Manage user account permissions


Before you create any stored procedures, familiarize yourself with the required
account permissions necessary to create and manage these objects. The IBM
Netezza admin user has full permission to manage and execute stored procedures.
The database owner also has full permission to objects within the database that the
owner owns. For release 7.0.3 and later systems that support multiple schemas in a
database, the schema owner also has full permission to objects within that schema.
In addition, the owner of the stored procedure has permission to manage and
execute the stored procedure.
As the admin user or any user who has account management permissions, you can
grant other users permission to create, manage, or execute the stored procedures
on a Netezza system. You can assign permissions by using the IBM Netezza
Performance Portal User's Guide, NzAdmin user interface, or by using the GRANT
and REVOKE SQL commands. For details about managing users and groups, and
assigning permissions by using the NzAdmin interface, see the IBM Netezza System
Administrators Guide.
If you use SQL commands to manage account permissions, the database to which
you are connected has meaning when you run the GRANT command. If you are
connected to the SYSTEM database, the privilege applies to all databases. If you
are connected to a specific database, the privilege applies only within that
database.
Starting in release 7.0.3, you can use a fully qualified object notation to set the
scope of object privileges from any database. The fully qualified object notation has
the format database.schema.object, where:
v database is a specific database name or the keyword ALL to grant the privilege
across all databases.
v schema is a specific schema name or the keyword ALL for all schemas in the
specified database value.
v object is the class PROCEDURE for all stored procedures, or a full signature
such as customer(VARCHAR(20)).
Make sure that you specify the correct signature for the object, including the sizes
for numeric and string data types, otherwise you receive an error similar to the
following example:
ERROR: GrantRevokeCommand: existing UDX NAME(ARGS) differs in size of
string/numeric arguments

You can use a similar format to set the scope of administrative privileges from any
database. The scope notation has the format IN database.schema, where:
Copyright IBM Corp. 2009, 2014

3-1

v database is a specific database name or the keyword ALL to grant the privilege
across all databases. You can omit a database name.
v schema is a specific schema name or the keyword ALL for all schemas in the
specified database. If you omit the database name, the scope is for ALL schemas
or all the schemas of the specified name.

Grant Create Procedure administration permission


To grant Create Procedure administration permission, use the following command:
GRANT CREATE PROCEDURE TO entity;

For example, the following command grants Create Procedure permissions to the
user bsmith:
GRANT CREATE PROCEDURE TO bsmith;

If you run this command while connected to the SYSTEM database, the privilege is
granted to the user in all databases. If you are connected to a specific database, the
privilege is granted to the user in only that database.
Using the release 7.0.3 fully qualified name form, you could also issue the
command from any database and specify an IN clause to set the privilege scope.
For example, the following command grants the user Create Procedure privilege in
all databases and schemas:
GRANT CREATE PROCEDURE IN ALL.ALL TO bsmith;

The following command grants the user Create Procedure privilege in the database
named NORTH and the schema named SALES:
GRANT CREATE PROCEDURE IN NORTH.SALES TO bsmith;

Grant all object permissions


To grant users or a group with all object permissions, use the following command:
GRANT ALL ON PROCEDURE TO entity;

This command gives the user or group the Alter, Drop, List, and Execute privileges
for procedures and other permissions such as Insert, Delete, and others that are not
used for procedures.
For example, the following command grants object permissions to the user bsmith:
GRANT ALL ON PROCEDURE TO bsmith;

For example, the following command grants object permissions to the user bsmith,
and is scoped to the database (and schema, if applicable) in which you run the
command:
GRANT ALL ON PROCEDURE TO bsmith;

Revoke Create Procedure administration permission


To revoke Create Procedure administration permission, use the following
command:
REVOKE CREATE PROCEDURE FROM entity;

For example, the following command revokes Create Procedure permissions from
the group analysts:

3-2

IBM Netezza Stored Procedures Developer's Guide

REVOKE CREATE PROCEDURE FROM GROUP analysts;

Manage the Alter permission


To grant Alter permission on an object, use the following command:
GRANT ALTER ON object TO entity;

To revoke Alter permission on an object, use the following command:


REVOKE ALTER ON object FROM entity;

For example, to grant Alter permissions for the sample stored procedure
returntwo() to the user asmith:
GRANT ALTER ON returntwo(timestamp) TO asmith;

For example, to revoke Alter permissions on the returntwo() procedure from the
group sales:
REVOKE ALTER ON returntwo(timestamp) FROM GROUP sales;

Manage the Execute permission


To grant Execute permission on an object, use the following command:
GRANT EXECUTE ON object TO entity;

To revoke Execute permission on an object, use the following command:


REVOKE EXECUTE ON object TO entity;

For example, to grant Execute permissions for the sample procedure returntwo()
to the user bsmith:
GRANT EXECUTE ON returntwo(timestamp) TO bsmith;

For example, to revoke Execute permissions for the sample procedure returntwo()
from the group sales:
REVOKE EXECUTE ON returntwo(timestamp) FROM GROUP sales;

Manage the Drop permission


To grant Drop permission on an object, use the following command:
GRANT DROP ON object TO entity;

To revoke Drop permission on an object, use the following command:


REVOKE DROP ON object FROM entity;

For example, to grant Drop permissions for the sample procedure returntwo() to
the user pcollins:
GRANT DROP ON returntwo(timestamp) TO pcollins;

For example, to revoke Drop permissions for the sample procedure returntwo()
from the user bsmith:
REVOKE DROP ON returntwo(timestamp) FROM bsmith;

Related tasks:
How to create and use a stored procedure on page 1-3

Chapter 3. Create and manage stored procedures

3-3

Create a stored procedure


The process to create a stored procedure is straightforward; typically, the
time-consuming work is in the design of the stored procedure, and the debugging
and testing of the procedure.
This section describes the following key steps for creating a stored procedure:
v Design a stored procedure
v Create a stored procedure

Design a stored procedure


The first step is to design the procedure itself. Make sure that you outline the basic
purpose and actions of the procedure, consider helpful error logging, and plan for
exception handling. Review the NZPLSQL language and statements to create the
body of the procedure.

Create a stored procedure


After you create the body of the stored procedure, you add it by using the
CREATE [OR REPLACE] PROCEDURE command. You enter this command at a
SQL command prompt.
The CREATE PROCEDURE command creates a procedure. To use this command,
you must be the admin user, own the database, own the schema (multi-schema
systems), or have the Create Procedure privilege. The CREATE OR REPLACE
PROCEDURE command creates a procedure if one does not already exist with the
specified signature, or updates an existing procedure with the matching signature
for the new (or different) field values. To replace a procedure, you must have the
Alter privilege.
For example, the following procedure customer() writes a customer name string to
the database log by using the RAISE NOTICE statement:
TEST.TESTSCH(USR)=> CREATE PROCEDURE customer()
RETURNS INT4 LANGUAGE NZPLSQL AS
BEGIN_PROC
BEGIN
RAISE NOTICE The customer name is alpha;
END;
END_PROC;
CREATE PROCEDURE

Since the execution user permissions were not specified on the command line, the
command uses the default of EXECUTE AS OWNER.
If you want to change the customer procedure to specify a new return value, you
can use a CREATE OR REPLACE PROCEDURE command similar to the following,
but you must specify all the required fields (such as language and the complete
procedure body) even if their values did not change, as follows:
TEST.TESTSCH(USR)=> CREATE OR REPLACE PROCEDURE customer()
RETURNS INT8 LANGUAGE NZPLSQL AS
BEGIN_PROC
BEGIN
RAISE NOTICE The customer name is alpha;
END;
END_PROC;
CREATE PROCEDURE

3-4

IBM Netezza Stored Procedures Developer's Guide

You can also use the ALTER PROCEDURE command to modify certain
characteristics of a defined procedure.
Related concepts:
Alter a stored procedure on page 3-10

Procedure signatures
Each stored procedure has a signature; that is, a unique identification in the form
<procedure_name>(<argument_type_list>). Signatures must be unique within the
same database; that is, they cannot duplicate the signature of another stored
procedure. The <argument_type_list> component does not consider data type sizes
to be differentiators. For example, you cannot create two procedures called
myproc(numeric(3,2)) and myproc(numeric(4,1)) in the same database. The larger
numeric size is not sufficient to create a unique signature.
If there are common use-cases where a procedure must accept different-sized
strings or numerics, you can design the procedure to accept the largest of the
possible values, or you can create a stored procedure with a different name to
process the different data size, for example:
TEST.TESTSCH(USR)=> CREATE PROCEDURE myproc_lgnum(numeric(4,1))
...

Procedures for overloading


You can create stored procedures that have the same procedure name, but which
have different argument signatures and return types. This process is called
overloading the procedure definition.
For example, assume that you have a procedure called customer_name() that can
take two or three input strings, which represent the first, middle (if specified), and
surname of a customer.
The following example is some sample procedure definitions:
TEST.TESTSCH(USR)=> CREATE PROCEDURE customer_name(VARCHAR(30), VARCHAR(30))
...
TEST.TESTSCH(USR)=> CREATE PROCEDURE customer_name(VARCHAR(30), VARCHAR(30),
VARCHAR(30))
...

If a user calls customer_name with two input strings, the system uses the first (two
argument) procedure. If the user specifies three input strings, the procedure uses
the second procedure that accepts three input strings.
You can use overloading to support different combinations of input values and
return types. However, overloading and uniquely named but similar procedures
have a maintenance overhead; if you need to update or redesign the body of the
procedure, update each procedure definition with the changes that you want to
make.

Size-specific, generic, and variable argument procedures


In the signature of a stored procedure, the <argument_type_list> can use three
general forms: size-specific arguments, generic arguments, and variable arguments.
This section describes these three formats and the benefits and considerations for
using that type.

Size-specific arguments
With size-specific arguments, you declare the type and size of all input arguments,
and the type and size of the return value. Specific data type size declarations are
Chapter 3. Create and manage stored procedures

3-5

useful for error-checking of the input arguments and return values, but they can be
somewhat limiting if your procedure processes strings or numerics that can vary in
size when you run a query.
For example, the following example creates a stored procedure that takes a string
of up to 20 VARCHAR characters:
TEST.TESTSCH(USR)=> CREATE PROCEDURE customer(VARCHAR(20))
RETURNS INT4 LANGUAGE NZPLSQL AS
BEGIN_PROC
BEGIN
remaining text omitted for example...

Constant data type sizes can result in implicit casts, such as casting a smaller input
value to fit a larger declared size. For example, it can increase the precision of a
numeric or add padding to strings. If you choose too small a size, you risk loss of
precision if IBM Netezza casts a larger input numeric to a smaller numeric or
truncates input strings that exceed the input argument size.

Generic-size arguments
Generic-size (or any-size) arguments offer more flexibility for strings and numerics.
You can declare character strings or numerics by using the ANY keyword in the
signature (or in the return value). For example:
TEST.TESTSCH(USR)=> CREATE PROCEDURE customer(VARCHAR(ANY))
RETURNS VARCHAR(ANY) LANGUAGE NZPLSQL AS
BEGIN_PROC
BEGIN
remaining text omitted for example...

The stored procedure accepts an input string of up to 64,000 characters (the


maximum for a VARCHAR). Within the body of the stored procedure, the code
must process the strings and numerics with the plan that you can receive a string
of any valid length. That is, you can check and obtain their size, process them as
needed, and return the value for the procedure.
Generic-size arguments help you to avoid specific limits for the input strings and
numerics, or to use overly large or maximum size values that result in unnecessary
resource allocation for the procedure. This format can also reduce the need to
register and maintain similar procedures that take different input arguments or
have different return values, and possible casting of input values.
Supported generic argument types: You use the ANY keyword to indicate that an
argument is generic. The following data types support the ANY keyword as a size
specifier:
v CHAR or NCHAR
v VARCHAR or NVARCHAR
v NUMERIC
For example, to specify a numeric data type of precision 10 and scale 2, you
specify it as NUMERIC(10,2). To specify a numeric data type that can take any
size, you specify is as NUMERIC(ANY). Likewise, to specify a variable character
string that can take any size, you declare it as VARCHAR(ANY).
Generic arguments in the procedure signature: You can define generic arguments
and the standard data-type-and-size-specific arguments in the signature of a stored
procedure. The IBM Netezza software verifies that all the input arguments match
the required number and data types of the signature.

3-6

IBM Netezza Stored Procedures Developer's Guide

For arguments that have a specific size, the Netezza software also confirms that the
size of the input value matches the defined signature size. If necessary, the Netezza
software casts the input values to match the size specified in the signature. For
example, if you declare a string of 20 characters [CHAR(20)] in a signature, the
Netezza software implicitly truncates an input string that is longer than 20
characters or adds padding if the input string is less than 20 characters.
For generic arguments, the argument values are passed to the procedure without
any casting or changes. For example, if you declare a CHAR(ANY) input value, the
procedure accepts character strings of any length up to the supported maximum; it
checks to make sure that the input value is a valid character string and that it
occurs in the expected place of the signature.
The Netezza software performs some implicit castings for the input values. For
example, if you define an input argument as VARCHAR(ANY) in the signature,
but you pass an input of CHAR(200) to the procedure, the procedure casts the
CHAR(200) to VARCHAR(200). The procedure uses the data type of the signature
and the size of the input value to determine the casting change.
Generic procedure return value:
If you use ANY for a return value size, your procedure calculates the size of the
numeric or string return value from the RETURN expression and returns it.
Register generic procedures: When you register a stored procedure that uses
generic arguments, you use the keyword ANY to declare character or numeric data
types as generic.
An example follows:
MYDB.TESTSCH(USR)=> CREATE PROCEDURE itemfind(NUMERIC(ANY))
RETURNS CHAR(ANY) LANGUAGE NZPLSQL AS
BEGIN_PROC
BEGIN
/* Body of procedure... intentionally omitted from example*/
END;
END_PROC;

In this example, the itemfind() procedure takes an input numeric data type of any
valid size and returns char value of any size.
Related reference:
The CREATE [OR REPLACE] PROCEDURE commands on page A-5

Variable arguments
Variable-argument procedures offer even more flexibility than generic-size
arguments. With variable argument procedures, you specify only the VARARGS
keyword in the argument_type_list. Users can specify from 0 to 64 input values of
any supported data type as input arguments. For example:
TEST.TESTSCH(USR)=> CREATE PROCEDURE customer(VARARGS)
RETURNS VARCHAR(ANY) LANGUAGE NZPLSQL AS
BEGIN_PROC
BEGIN
remaining text omitted for example...

Within the body of the stored procedure, the code must process the input values
and manage them as needed.

Chapter 3. Create and manage stored procedures

3-7

Use variable argument procedures to create one procedure that can be used for
different combinations of input types. This process simplifies the development of
stored procedures and reduces the need to create overloaded procedure definitions
that do the same task for different types and numbers of arguments.
Related concepts:
Argument list and variables on page 2-6

Obfuscate the procedure body


As shown in CREATE PROCEDURE examples, the procedure body is entered in
readable text format. Users who have permission to show the procedure can use
the VERBOSE option to review the procedure body. If your procedure body
contains intellectual property, copyrighted material, or other algorithms that you
do not want in clear text, you can obfuscate the body text.
Related concepts:
Block quoting support on page 1-5
Show information about a stored procedure on page 3-12

Create obfuscated procedures by using a wrapping procedure


A common way to create an obfuscated stored procedure is by creating a stored
procedure wrapper that takes the procedure definition and the procedure body,
and creates the obfuscated procedure, as in the following example:
TEST.TESTSCH(USR)=> CREATE OR REPLACE PROCEDURE wrap_proc(text, text)
RETURNS BOOL LANGUAGE NZPLSQL AS
BEGIN_PROC
DECLARE
proc alias for $1;
body alias for $2;
enc text;
sql text;
BEGIN
enc := wrap_nzplsql(body);
sql := proc || || || quote_literal(enc) || ;
RAISE NOTICE %;, sql;
EXECUTE IMMEDIATE sql;
return true;
END;
END_PROC;
CREATE PROCEDURE

Call the wrap_proc() procedure and specify the CREATE OR REPLACE main
definition in the first input value; then specify the BEGIN PROC/END PROC
contents in the second input value. You must surround the main definition (the
first input value) with single quotation marks. Do not enclose the second input
value (the procedure body) in single quotation marks because the wrap_nzplsql()
built-in procedure takes the text as it would be specified for a CREATE OR
REPLACE PROCEDURE command. An example follows:
TEST.TESTSCH(USR)=> CALL wrap_proc(CREATE OR REPLACE PROCEDURE customer()
RETURNS INT4 LANGUAGE NZPLSQL AS,
BEGIN_PROC
BEGIN
RAISE NOTICE The customer name is alpha;
END;
END_PROC);
NOTICE: CREATE OR REPLACE PROCEDURE customer() RETURNS INT4 LANGUAGE
NZPLSQL
ASTlpQU1FMV1JBUDEwWWk5NUhrQzVhR0xyRFRxTWR3VE5sQT09JEdFQ1B5LzVkSU1KMTI
1a0dUK3NTWjlkb3ZGL3ZHalhpVExPVG5UajRkK3gxSkxvZVhKejdZQmJOVHN0aU1waFRlb
mhoaWtYdHJUTVkKUUNrWDY5Nko5Rms2NlBIYUxra21xeWNZYXdWclBCQT0=;

3-8

IBM Netezza Stored Procedures Developer's Guide

wrap_proc
----------t
(1 row)

When you call an obfuscated procedure, the system uses internal routines to
read the obfuscated body text and run the procedure. The behavior and output
of the obfuscated procedure is identical to a cleartext version of the procedure, for
example:
TEST.TESTSCH(USR)=> CALL customer();
NOTICE: The customer name is alpha
customer
---------(1 row)

Create obfuscated procedure body text


As an alternative to using the wrap_proc() procedure method, you can also create
the obfuscated body of the procedure in a separate step as follows:
TEST.TESTSCH(USR)=> CALL wrap_nzplsql(BEGIN_PROC BEGIN RAISE NOTICE The
customer name is alpha; END; END_PROC);
wrap_nzplsql
---------------------------------------------------------------------TlpQU1FMV1JBUDEwVE5jZlh5TnpYbndCNkV5VFFMRTBiQT09JGE5N2p6ZEdJSVZwTTRrWm
RRM0I3WmUxZERZeWd6YkdjTWkxTzQrL1dCMmpqRGQvak9lUzFQQjArNGdlM08yZVdxUjRI
MTFaTnROUmwKdk5xSm0wb1RPZz09
(1 row)

The wrap_nzplsql() built-in procedure generates the obfuscated body text, which
you can input directly to a CREATE OR REPLACE PROCEDURE command, as
follows:
TEST.TESTSCH(USR)=> CREATE OR REPLACE PROCEDURE customer() RETURNS INT4
LANGUAGE NZPLSQL AS
TlpQU1FMV1JBUDEwVE5jZlh5TnpYbndCNkV5VFFMRTBiQT09JGE5N2p6ZEdJSVZwTTRrW
mRRM0I3WmUxZERZeWd6YkdjTWkxTzQrL1dCMmpqRGQvak9lUzFQQjArNGdlM08yZVdxUjR
IMTFaTnROUmwKdk5xSm0wb1RPZz09;
CREATE PROCEDURE

As shown in the example, you must enclose the obfuscated body text in single
quotation marks for the CREATE OR REPLACE PROCEDURE command.

Create obfuscated procedure definitions for a registration script


If you plan to create a script that users run to register your stored procedures in
their databases, you can use a wrapping procedure that takes as input the
procedure definition and body, and which returns a CREATE OR REPLACE
PROCEDURE command that has obfuscated body text. For example:
TEST.TESTSCH(USR)=> CREATE OR REPLACE PROCEDURE return_wrap(TEXT, TEXT)
RETURNS TEXT LANGUAGE NZPLSQL AS
BEGIN_PROC
DECLARE
proc alias for $1;
body alias for $2;
enc text;
sql text;
BEGIN
enc := wrap_nzplsql(body);
sql := proc || || || quote_literal(enc) || ;
return sql;
END;
END_PROC;
CREATE PROCEDURE

Chapter 3. Create and manage stored procedures

3-9

Similar to the wrap_proc() procedure, specify the CREATE OR REPLACE main


definition as a quoted text string in the first input value, and specify the unquoted
BEGIN PROC/END PROC contents in the second input value. For example:
TEST.TESTSCH(USR)=> CALL return_wrap(CREATE OR REPLACE PROCEDURE customer()
RETURNS INT4 LANGUAGE NZPLSQL AS, BEGIN_PROC BEGIN RAISE NOTICE The
customer name is alpha; END; END_PROC);
return_wrap
---------------------------------------------------------------------CREATE OR REPLACE PROCEDURE customer() RETURNS INT4 LANGUAGE NZPLSQL
AS
TlpQU1FMV1JBUDEwaTVJeHJnV1BLd1o0ZDVtNEtNMGxKQT09JCtiSlVDS1NHbkVrdVZja
01JR3Nrc2dTZlExWDdkaUpDeHdZWUp2dmlrUkZIeEpEQnR6dE1JSHMxOHRTR08xMG1IczJ
FSk92R2F0Ti8KMGhKTGlUUEdIZz09
(1 row)

The return value is a CREATE OR REPLACE PROCEDURE command that you can
use in your registration script to define your stored procedure without displaying
the procedure body text to the script user.

Call or invoke a stored procedure


To invoke or execute the sample stored procedure customer(), you can use any of
the following SQL query forms:
TEST.TESTSCH(USR)=>
TEST.TESTSCH(USR)=>
TEST.TESTSCH(USR)=>
TEST.TESTSCH(USR)=>
TEST.TESTSCH(USR)=>

CALL customer();
EXEC customer();
EXECUTE customer();
EXECUTE PROCEDURE customer();
SELECT customer();

Any of these commands cause the procedure to output the following:


NOTICE: The customer name is alpha
CUSTOMER
---------(1 row)

Related reference:
Appendix A, SQL command reference, on page A-1

Alter a stored procedure


After you define a stored procedure on the IBM Netezza system, you can use the
ALTER PROCEDURE command to change some aspects of the procedure.
You can modify a stored procedure to change the following aspects of the
procedure:
v RETURNS value
v Execution user property (EXECUTE AS OWNER versus EXECUTE AS CALLER)
v The body of the procedure
v The owner of the procedure
You cannot change the procedure name or argument type list. You must drop the
existing procedure and create a procedure with the new name and argument type
list.
For example, the following sample commands can be used to change the
customer procedure. To change the return value type, use a command similar to
the following example:

3-10

IBM Netezza Stored Procedures Developer's Guide

TEST.TESTSCH(USR)=> ALTER PROCEDURE customer() RETURNS INT8;


ALTER PROCEDURE

To change the owner of the procedure to user, use a command similar to the
following example:
TEST.TESTSCH(USR)=> ALTER PROCEDURE customer() OWNER TO user ;
ALTER PROCEDURE

To change the user execution property to EXECUTE AS CALLER, use a command


similar to the following example:
TEST.TESTSCH(USR)=> ALTER PROCEDURE customer() EXECUTE AS CALLER;
ALTER PROCEDURE

To change the procedure definition, use a command similar to the following


example:
TEST.TESTSCH(USR)=> ALTER PROCEDURE customer() AS
BEGIN_PROC
BEGIN
RAISE NOTICE The customer name is beta;
END;
END_PROC;
ALTER PROCEDURE

Related concepts:
Create a stored procedure on page 3-4
Related reference:
The ALTER PROCEDURE command on page A-1

Comment on a stored procedure


As a best practice, add some descriptive comments on stored procedures by using
the COMMENT ON command capability.
For example:
COMMENT ON PROCEDURE customer() IS A procedure that displays a
customer name.;
COMMENT

An IBM Netezza SQL query user can display these comments by using the nzsql
\dd <name> command switch, or the \dd switch shows all comments for all
procedures. Consider using a comment template that includes information about
the author, version, and description in the following format:
COMMENT ON PROCEDURE <procedure name> (<argument type list>) IS
Author: <name>
Version: <version>
Description: <description>;

For example:
COMMENT ON PROCEDURE customer() IS Author: bsmith
Version: 1.0 Description: A procedure that writes a customer name to
the database log file.;

To comment on a stored procedure, you must either be the Netezza admin user,
the owner of the procedure, or you must have Alter permissions for procedure
objects. For more information about COMMENT ON, see the IBM Netezza Database
Users Guide.

Chapter 3. Create and manage stored procedures

3-11

Make sure that you specify a full procedure name and argument list, including
correct sizes for numeric and string data types. Otherwise, you receive an error
similar to the following example:
Error: CommentProcedure: existing procedure name(argument type list)
differs in size of string/numeric arguments

Drop a stored procedure


You can remove a stored procedure from the IBM Netezza system by using the
DROP PROCEDURE command.
For example, to drop the customer procedure, use a command similar to the
following example:
DROP PROCEDURE customer();
DROP PROCEDURE

Related reference:
The DROP PROCEDURE command on page A-7

Show information about a stored procedure


You can use the SHOW PROCEDURE command to display information about a
stored procedure.
A sample command follows for the example customer procedure:
MYDB.TESTSCH(USR)=> SHOW PROCEDURE customer;
RESULT | PROCEDURE | BUILTIN | ARGUMENTS
---------+-----------+---------+----------INTEGER | CUSTOMER | f
| ()
(1 row)

The sample output shows the return value (RESULT), the procedure name, f (false)
to indicate that this is a user-defined procedure (not a built-in or system-supplied
procedure), and the argument list for the procedure (an empty list in this example).
The command displays information for any procedures with names that begin with
the specified characters. For example, if you have two procedures named customer
and customerid, this example command displays information for both procedures.
The command also offers a VERBOSE mode that displays more information about
the procedure, including the procedure body, comments (if supplied), owner,
execution user, and other information. If the procedure is obfuscated, the
procedure body is not in clear text; it is in an unreadable format.
Related concepts:
Obfuscate the procedure body on page 3-8
Related reference:
The SHOW PROCEDURE command on page A-9

NzAdmin administrative interface for stored procedures


If you use the NzAdmin administrative interface, you can view information about
the stored procedures defined on a IBM Netezza system and manage them. You
cannot add or alter a stored procedure from the NzAdmin interface, but you can
display its properties, change its owner, drop the procedure, and manage user and
group permissions for procedures.

3-12

IBM Netezza Stored Procedures Developer's Guide

To view the stored procedures, go to the Database tab of NzAdmin. Select a


database and double-click Procedures to list the stored procedures that are defined
in that database.

Figure 3-1. The NzAdmin stored procedures window

The Procedures list shows the signature, return type, owner, and creation date of
each procedure. Double-click a procedure to obtain information about the
procedure definition, or to view or manage the privileges for the procedure. For
more information about using the NzAdmin interface, see the IBM Netezza System
Administrators Guide.

Chapter 3. Create and manage stored procedures

3-13

3-14

IBM Netezza Stored Procedures Developer's Guide

Appendix A. SQL command reference


This section describes the IBM Netezza SQL commands that relate to the creation
and management of stored procedures.
The following table lists the SQL commands.
Table A-1. Stored procedure SQL commands
Command

Description

More information

ALTER PROCEDURE

Changes a stored
procedure.

The ALTER PROCEDURE command.

CALL or EXEC[UTE [
PROCEDURE]]

Runs a stored
procedure.

The CALL and EXEC[UTE


[PROCEDURE]] commands on page
A-3

CREATE [OR REPLACE]


PROCEDURE

Adds or updates a
stored procedure.

The CREATE [OR REPLACE]


PROCEDURE commands on page
A-5.

DROP PROCEDURE

Drops or deletes a
stored procedure.

The DROP PROCEDURE command


on page A-7.

SHOW PROCEDURE

Displays
information about
stored procedures.

The SHOW PROCEDURE command


on page A-9.

Related concepts:
Call or invoke a stored procedure on page 3-10
How to execute a stored procedure on page 1-3
SQL commands for stored procedures on page 1-2

The ALTER PROCEDURE command


Use the ALTER PROCEDURE command to change a stored procedure.
You can change the return value, execution setting, owner, and body of a
procedure, but you cannot change the name or argument list with this command.
You can add or remove the VARARGS value in an otherwise empty argument list.
To change the name or argument list of a stored procedure, you must drop the
procedure and create a procedure with the new name or argument type list.

Synopsis
ALTER PROCEDURE <name> (<args>) [ RETURNS <type>]
[ EXECUTE AS OWNER | EXECUTE AS CALLER ] [AS <procedure_body>];
ALTER PROCEDURE <name> (<args>) OWNER TO <user>;

Copyright IBM Corp. 2009, 2014

A-1

Inputs
The ALTER PROCEDURE command takes the following inputs:
Table A-2. ALTER PROCEDURE input
Input

Description

name

The name of the stored procedure that you want to change. You cannot
change the name of the procedure. The procedure must be defined in
the database to which you are connected.
For systems that support multiple schemas, you can specify a name in
the format schema.procedure to change a procedure in a different
schema of the current database.

args

A list of input argument data types for the stored procedure. You can
also specify the VARARGS value to create a variable argument
procedure where users can input up to 64 values of any supported data
type. VARARGS is a mutually exclusive value; you cannot specify any
other arguments in the list.
You cannot change the argument list or sizes. You can remove
VARARGS from the argument list, or add it to an otherwise empty
argument list.

RETURNS <type> Specifies the type of data returned by the procedure. The <type> value
can be a IBM Netezza data type or the value REFTABLE (<table-name>)
to indicate that it returns a result set that looks like the specified table.
The table must exist, and it continues to exist after the procedure. The
table can be empty, but it must exist in the database.
EXECUTE AS
OWNER

If specified, the stored procedure uses the procedure owner ID for all
access control and permission checks. This is the default.

EXECUTE AS
CALLER

If specified, the stored procedure uses the ID of the user who called the
procedure for all access control and permission checks.

procedure_body

Specifies the text or body of the procedure. The body must be enclosed
with single quotation marks or enclosed by a BEGIN_PROC/
END_PROC pair.
When you alter the procedure, you can obfuscate the body to mask the
content from users who have permission to show the procedure.

Outputs
The ALTER PROCEDURE command has the following output
Table A-3. ALTER PROCEDURE Output
Output

Description

ALTER PROCEDURE

The message that the system returns if the command


is successful.

ERROR: replacing procedure:


permission denied.

The message indicates that the user does not have


Alter permission on the procedure.

Error: FunctionAlter: existing UDX


NAME(ARGS) differs in size of
string/numeric arguments

This error indicates that a stored procedure exists


with the name but has different sizes specified for
string or numeric arguments.
To alter the stored procedure, make sure that you
specify the exact argument type list with correct sizes.

A-2

IBM Netezza Stored Procedures Developer's Guide

Table A-3. ALTER PROCEDURE Output (continued)


Output

Description

ERROR: FunctionAlter: function


NAME does not exist with that
signature

This error indicates that the specified procedure name


does not exist in the database.

ERROR: Can't specify arguments to You cannot specify both the VARARGS value and any
a varargs procedure
other argument value in the arguments list. The
VARARGS value is mutually exclusive.

Description
You cannot alter a stored procedure that is currently in use in an active query.
After the transaction completes for an active query, the Netezza system processes
the ALTER PROCEDURE command.
Privileges required
To alter a procedure, you must meet one of the following criteria:
v You must have the Alter privilege on the PROCEDURE object.
v You must have the Alter privilege on the specific procedure.
v You must own the procedure.
v You must be the database admin user or own the current database or the
current schema on systems that supports multiple schemas.
Common tasks
You can use the ALTER PROCEDURE command to change the execution
user ID of the procedure, its return value, or the procedure body itself.
You can also use the ALTER PROCEDURE command to change the owner
of a procedure as follows:
ALTER PROCEDURE <name> (<arguments>) OWNER TO <name>;

Usage
To change the execution ID from over to caller, enter:
system(admin)=> ALTER PROCEDURE myproc(int4) EXECUTE AS CALLER;

To change the owner for a procedure in a different schema, enter:


MYDB.MYSCH(USER)=> ALTER PROCEDURE schtwo.myproc(int4) OWNER TO
user2;

Related concepts:
Alter a stored procedure on page 3-10

The CALL and EXEC[UTE [PROCEDURE]] commands


Use the CALL command, EXEC command, EXECUTE command, or EXECUTE
PROCEDURE command to invoke a stored procedure on a IBM Netezza host.
The CALL, EXEC, EXECUTE, EXECUTE PROCEDURE commands are identical in
their behavior, inputs, and outputs. The different commands provide compatibility
with other procedural language invocation methods. You can also use the SELECT
command to invoke a stored procedure.

Appendix A. SQL command reference

A-3

Synopsis
CALL procedure_name(arguments)
EXEC procedure_name(arguments)
EXECUTE procedure_name(arguments)
EXECUTE PROCEDURE procedure_name(arguments)
SELECT procedure_name(arguments)

Inputs
The CALL and EXEC[UTE [PROCEDURE] commands take the following inputs:
Table A-4. CALL and EXEC[UTE [PROCEDURE]] inputs
Input

Description

procedure_name

The name of the stored procedure that you want to invoke. If you
specify only a procedure name, the system searches the current
database and schema, and then search PATH to find the procedure.
You can specify a fully qualified object name to execute a procedure
defined in a different database or schema.

arguments

Specifies a list of constant or literal arguments to the procedure. The


arguments might be results of functions when the functions take only
constant or literal arguments as well.

Outputs
The CALL and EXEC[UTE [PROCEDURE] commands have the following outputs:
Table A-5. CALL and EXEC[UTE [PROCEDURE]] outputs
Output

Description

ERROR:
This error indicates that the current user account does not have Execute
EXECUTE PROC: permission for the stored procedure.
Permission
denied.
ERROR: Function This message indicates that the user entered incorrect arguments for the
stored procedure. A procedure of that name exists, but it is expecting
'NAME(ARGS)'
different input arguments.
does not exist
Unable to
identify a
function that
satisfies the
argument types
You might need
to add explicit
typecasts

Description
Privileges required
To invoke a stored procedure, you must meet one of the following criteria:
v You must have the Execute privilege on the PROCEDURE object.
v You must have the Execute privilege on the specific procedure.
v You must own the procedure.

A-4

IBM Netezza Stored Procedures Developer's Guide

v You must be the database admin user or own the current database or the
current schema on systems that support multiple schemas.

Usage
The following examples provide some sample usage:
MYDB.MYSCH(USER)=>
MYDB.MYSCH(USER)=>
MYDB.MYSCH(USER)=>
MYDB.MYSCH(USER)=>

CALL updateacct();
EXEC schema_two.myproc();
EXECUTE sales.dev.inventorysearch(umbrellas);
EXECUTE PROCEDURE updateacct();

You can also use the SELECT command to run a procedure; however, you cannot
specify a FROM clause. For example:
MYDB.MYSCH(USER)=> SELECT updateacct();
MYDB.MYSCH(USER)=> SELECT inventorysearch(umbrellas);

The CREATE [OR REPLACE] PROCEDURE commands


Use the CREATE OR REPLACE PROCEDURE command to create a stored
procedure or to update an existing procedure with a new return type, execution
permissions, or procedure body.

Synopsis
CREATE [OR REPLACE] PROCEDURE <name> (<arguments>)
RETURNS <type> [ [ EXECUTE AS OWNER | EXECUTE AS CALLER ] ] LANGUAGE
NZPLSQL AS <procedure_body>;

Inputs
The CREATE OR REPLACE PROCEDURE command takes the following inputs:
Table A-6. CREATE OR REPLACE PROCEDURE inputs
Input

Description

name

The name of the stored procedure that you want to create or replace.
This name is the SQL identifier that is used to invoke the procedure in
a SQL expression.
If the stored procedure exists, you cannot change the name with the
CREATE OR REPLACE command.
For systems that support multiple schemas, you can specify a name in
the format schema.procedure to create a procedure in a different
schema of the current database. You cannot create a procedure in a
different database.

arguments

Specifies a list of fully specified argument data types. You can also
specify the VARARGS value to create a variable argument procedure
where users can input up to 64 values of any supported data type.
VARARGS is a mutually exclusive value; you cannot specify any other
arguments in the list.
If the stored procedure exists, you cannot change the argument type list
with the CREATE OR REPLACE command. You can change some
aspects of the argument types; for example, you can change the size of
a string or the precision and scale of a numeric value. You can also
remove VARARGS from the argument list, or add it to an otherwise
empty argument list.

Appendix A. SQL command reference

A-5

Table A-6. CREATE OR REPLACE PROCEDURE inputs (continued)


Input

Description

RETURNS <type> Specifies the type of data returned by the procedure. The <type> value
can be an IBM Netezza data type or the value REFTABLE
(<table-name>) to indicate that it returns a result set that looks like the
specified table. The table must exist, although it can be empty, and it
continues to exist after the procedure.
EXECUTE AS
OWNER

If specified, the stored procedure runs by using the procedure owner ID


for all access control and permission checks. This is the default.

EXECUTE AS
CALLER

If specified, the stored procedure runs by using the ID of the user who
called the procedure for all access control and permission checks.

LANGUAGE

Specifies the programming language used for the procedure. The


default and only supported value is NZPLSQL.

procedure_body

Specifies the text of the procedure and must be enclosed with single
quotation marks or a BEGIN_PROC/END_PROC pair.
You can obfuscate the body to mask the content from users who have
permission to show the procedure.

Outputs
The CREATE [OR REPLACE] PROCEDURE command has the following outputs:
Table A-7. CREATE [OR REPLACE] PROCEDURE outputs
Output

Description

CREATE PROCEDURE

The message that the system returns if the command


is successful.

ERROR: creating procedure:


permission denied.

The message indicates that the user does not have


Create Procedure permission.

ERROR: User 'username' is not


allowed to create/drop procedures.

The system returns this message if your user account


does not have permission to create a stored
procedure.

ERROR: Synonym 'name' already


exists

The system returns this message if a synonym exists


with the name that you specified for the stored
procedure.

ERROR: ProcedureCreate:
procedure NAME already exists
with the same signature

This error is returned when you issue a CREATE


PROCEDURE command and a stored procedure with
the same name and argument type list exists in the
database. Use CREATE OR REPLACE PROCEDURE
instead.

NOTICE: FunctionCreate: existing


UDX NAME(ARGS) differs in size
of string/numeric arguments

This message indicates that a stored procedure exists


with the name but has different sizes specified for
string or numeric arguments. If you did not intend to
change the stored procedure signature, check the
signature and ensure that it is correct.

ERROR: Can't specify arguments to You cannot specify both the VARARGS value and any
a varargs procedure
other argument value in the arguments list. The
VARARGS value is mutually exclusive.

A-6

IBM Netezza Stored Procedures Developer's Guide

Description
When you create a stored procedure, the signature of the stored procedure (that is,
its name and argument type list) must be unique within its database. No other
stored procedure can have the same name and argument type list in the same
database.
You cannot change the stored procedure name or the argument type list with the
CREATE OR REPLACE command. You can change some aspects of the argument
types; for example, you can change the size of a string or the precision and scale of
a numeric value, and you can add or remove the VARARGS value in an otherwise
empty argument list. To change the name or argument type list of a stored
procedure, you must drop the stored procedure and then create a stored procedure
with the new name or argument type list.
You cannot replace a stored procedure that is currently in use in an active query.
After the transaction completes for an active query, the Netezza system processes
the CREATE OR REPLACE PROCEDURE command.
Privileges required
You must have Create Procedure permission to use the CREATE
PROCEDURE command. Also, if you use CREATE OR REPLACE
PROCEDURE to change a stored procedure, you must have Create
Procedure and Alter permission to change it.
Common tasks
Use the CREATE PROCEDURE command to create and become the owner
of a new stored procedure. You can use the ALTER PROCEDURE
command to change the owner of a procedure.

Usage
To create a procedure called customername:
MYDB.SCHEMA(USER)=> CREATE OR REPLACE PROCEDURE customer() RETURNS INT8
LANGUAGE NZPLSQL AS BEGIN_PROC BEGIN RAISE NOTICE The customer
name is alpha; END; END_PROC;

To create a new procedure called customername in a different schema of the same


database:
MYDB.SCHEMA(USER)=> CREATE OR REPLACE PROCEDURE sch_two.customer()
RETURNS INT8 LANGUAGE NZPLSQL AS BEGIN_PROC BEGIN RAISE NOTICE The
customer name is alpha; END; END_PROC;

Related concepts:
Register generic procedures on page 3-7

The DROP PROCEDURE command


Use the DROP PROCEDURE command to remove an existing stored procedure
from a database.

Synopsis
DROP PROCEDURE <name> (<arguments>)

Appendix A. SQL command reference

A-7

Inputs
The DROP PROCEDURE command takes the following inputs:
Table A-8. DROP PROCEDURE inputs
Input

Description

name

The name of the stored procedure that you want to drop. The
procedure must be defined in the database to which you are connected.
For systems that support multiple schemas, you can specify a name in
the format schema.procedure to drop a procedure in a different schema
of the current database. You cannot drop a procedure in a different
database.

arguments

A list of input arguments to uniquely identify the stored procedure.

Outputs
The DROP PROCEDURE command has the following outputs:
Table A-9. DROP PROCEDURE Outputs
Output

Description

DROP PROCEDURE

The message that the system returns if the command


is successful.

ERROR: DROP PROCEDURE:


permission denied

The user does not have Drop permission.

ERROR: RemoveFunction: function


'NAME(ARGS)' does not exist

The message that indicates that the specified


procedure signature does not exist in the database.

ERROR: Name: No such stored


procedure

The message that the system returns if the specified


stored procedure does not exist in the current
database.

ERROR: RemoveFunction: existing


UDX NAME(ARGS) differs in size
of string/numeric arguments

This error indicates that a stored procedure exists


with the name but has different sizes specified for
string or numeric arguments.
To drop the stored procedure, make sure that you
specify the exact argument type list with correct sizes.

Description
You cannot drop a stored procedure that is currently in use in an active query.
After the transaction completes for an active query, the IBM Netezza system
processes the DROP PROCEDURE command. The stored procedure must be
defined in the current database.
The DROP PROCEDURE command has the following characteristics:
Privileges required
To drop a stored procedure, you must meet one of the following criteria:
v You must have the Drop privilege on the PROCEDURE object.
v You must have the Drop privilege on the specific stored procedure.
v You must own the stored procedure.
v You must be the database admin user or own the current database or the
current schema on systems that supports multiple schemas.

A-8

IBM Netezza Stored Procedures Developer's Guide

Common tasks
Use the DROP PROCEDURE command to drop an existing stored
procedure from a database.

Usage
To drop a sample stored procedure named mycalc(), enter:
system(admin)=> DROP PROCEDURE mycalc();

Related concepts:
Drop a stored procedure on page 3-12

The SHOW PROCEDURE command


Use the SHOW PROCEDURE command to display information about one or more
stored procedures. The command checks your user account privileges to ensure
that you are permitted to see information about the procedures.

Synopsis
SHOW PROCEDURE [ALL | <name>] [VERBOSE]

Inputs
The SHOW PROCEDURE command takes the following inputs:
Table A-10. SHOW PROCEDURE inputs
Input

Description

ALL

Show information about all the stored procedures defined in the


database. This is the default.

name

Show information about one or more stored procedures defined in the


database. You can specify a partial name. The command displays
information for all the procedures with names that begin with the
specified characters. You cannot specify a full signature.

VERBOSE

Display detailed information about the stored procedure.

Outputs
The SHOW PROCEDURE command has the following output:
Table A-11. SHOW PROCEDURE output
Output

Description

error found "(" (at char num) syntax The message that the system returns if you specify a
error, unexpected '(', expecting $end full signature, for example:
show procedure returntwo();

Description
The SHOW PROCEDURE command has the following characteristics:
Privileges required
Any user can run the SHOW PROCEDURE command. To see information
about procedures in the output, you must be the admin user, own one or
more procedures, own the current database or the schema on a system that

Appendix A. SQL command reference

A-9

supports multiple schemas, or have object privileges (such as Execute, List,


Alter, or Drop) on one or more procedures or the Procedure object class.
Common tasks
Use the SHOW PROCEDURE command to display one or all stored
procedures in a database.

Usage
To show the sample stored procedure named returntwo, use the following
command:
MYDB.SCHEMA(ADMIN)=> SHOW PROCEDURE returntwo;
RESULT
| PROCEDURE | BUILTIN | ARGUMENTS
--------------------------+-----------+---------+------------REFTABLE(MYDB.USER.TBL) | RETURNTWO | f
| (TIMESTAMP)
(1 row)

To show verbose information for the sample stored procedure named returntwo,
use the following command. The sample output is formatted to fit the page area.
MYDB.SCHEMA(ADMIN)=> SHOW PROCEDURE returntwo VERBOSE;
RESULT
| PROCEDURE | BUILTIN | ARGUMENTS | OWNER | EXECUTEDASOWNER |
VARARGS | DESCRIPTION | PROCEDURESOURCE
-------------------------+-----------+---------+-------------+-------+-----------------+
--------+--------------+----------------REFTABLE(MYDB.USER.TBL) | RETURNTWO | f
| (TIMESTAMP) | USER |
t
|
f
|This is a sample stored procedure |
DECLARE
BEGIN
EXECUTE IMMEDIATE INSERT INTO || REFTABLENAME || values (1,1);
EXECUTE IMMEDIATE INSERT INTO || REFTABLENAME || values (2,2);
RETURN REFTABLE;
END;
(1 row)

If the stored procedure is obfuscated, the VERBOSE mode shows the obfuscated
body text, as follows:
MYDB.SCHEMA(ADMIN)=> SHOW PROCEDURE customer VERBOSE;
RESULT | PROCEDURE
| BUILTIN | ARGUMENTS | OWNER | EXECUTEDASOWNER | VARARGS |
DESCRIPTION | PROCEDURESOURCE
-------------------------+-----------+---------+-------------+-------+-----------------+
--------+--------------+----------------BIGINT | CUSTOMER
| f
|
()
| USR |
t
| f
|
| TlpQU1FMV1JBUDEwVE5jZlh5TnpYbndCNkV5VFFMRTBiQT09JGE5N2p6ZEdJSVZwTTRrWmRRM0I3
WmUxZERZeWd6YkdjTWkxTzQrL1dCMmpqRGQvak9lUzFQQjArNGdlM08yZVdxUjRIMTFaTnROUmwKdk5xSm0wb1RPZz
09
(1 row)

To list all the stored procedures in a database, enter:


MYDB.SCHEMA(ADMIN)=> SHOW PROCEDURE ALL;
RESULT
|
PROCEDURE
| BUILTIN | ARGUMENTS
----------------------------+------------------+---------+-----------------------BOOLEAN
| BOOLPROC
| f
| (BOOLEAN)
CHARACTER
| CHARPROC
| f
| (CHARACTER(ANY))
CHARACTER
| CHARPROCANY
| f
| (CHARACTER(ANY))
CHARACTER
| CHARPROCANY2
| f
| (CHARACTER(10))
REAL
| FLOAT4PROC
| f
| (REAL)
DOUBLE PRECISION
| FLOAT8PROC
| f
| (DOUBLE PRECISION)
BYTEINT
| INT1PROC
| f
| (BYTEINT)

Related concepts:
Show information about a stored procedure on page 3-12

A-10

IBM Netezza Stored Procedures Developer's Guide

Appendix B. Stored procedure examples


This section contains examples of stored procedure definitions.

Variable argument stored procedure


The following is an example of a stored procedure that uses variable arguments
and the $var value to obtain the data type of the input parameters:
CREATE OR REPLACE PROCEDURE sp_varargs01(varargs)
RETURNS INT4
LANGUAGE NZPLSQL
AS
BEGIN_PROC
DECLARE
num_args int4;
typ oid;
idx int4;
BEGIN
num_args := PROC_ARGUMENT_TYPES.count;
RAISE NOTICE Number of arguments is %, num_args;
for i IN 0 .. PROC_ARGUMENT_TYPES.count - 1 LOOP
typ := PROC_ARGUMENT_TYPES(i);
idx := i+1;
RAISE NOTICE argument $% is type % value %, idx, typ,
$idx;
END LOOP;
END;
END_PROC;

A sample call to the sp_varargs01 procedure follows:


select sp_varargs01(true, test::char(10), 62443234::int8, 123::int2,
123456::int4, 34343.4343::float4, 1212.2323::float8,
test2::varchar(10), 2009-05-12::date, 13:14:05::time,
2009-05-12 08:10:10::timestamp, 2 days 1 hour::interval,
11:40:36+05::timetz, 3243.4324234::numeric,
3243.4324234::numeric(7,2), 5::int1, foo::nchar(20),
foo::nvarchar(20), null::int4);
NOTICE: Number of arguments is 19
NOTICE: argument $1 is type 16 value t
NOTICE: argument $2 is type 1042 value test

NOTICE: argument $3 is type 20 value 62443234


NOTICE: argument $4 is type 21 value 123
NOTICE: argument $5 is type 23 value 123456
NOTICE: argument $6 is type 700 value 34343.4
NOTICE: argument $7 is type 701 value 1212.2323
NOTICE: argument $8 is type 1043 value test2
NOTICE: argument $9 is type 1082 value 2009-05-12
NOTICE: argument $10 is type 1083 value 13:14:05
NOTICE: argument $11 is type 1184 value 2009-05-12 08:10:10
NOTICE: argument $12 is type 1186 value 2 days 01:00:00
NOTICE: argument $13 is type 1266 value 11:40:36+05
NOTICE: argument $14 is type 1700 value 3243.4324234
NOTICE: argument $15 is type 1700 value 3243.43
NOTICE: argument $16 is type 2500 value 5
NOTICE: argument $17 is type 2522 value foo

NOTICE: argument $18 is type 2530 value foo


NOTICE: argument $19 is type 23 value <NULL>
sp_varargs01
-------------(1 row)
Copyright IBM Corp. 2009, 2014

B-1

Example of simulating an anonymous block


The following is an NZPLSQL procedure that can execute anonymous blocks:
CREATE OR REPLACE PROCEDURE exec_nzplsql_block(text) RETURNS BOOLEAN
LANGUAGE NZPLSQL AS
BEGIN_PROC
DECLARE lRet BOOLEAN;
DECLARE sid INTEGER;
DECLARE nm varchar;
DECLARE cr varchar;
BEGIN
sid := current_sid;
nm := any_block || sid || ();
cr = CREATE OR REPLACE PROCEDURE || nm ||
RETURNS BOOL LANGUAGE NZPLSQL AS BEGIN_PROC
|| $1 || END_PROC;
EXECUTE IMMEDIATE cr;
EXECUTE IMMEDIATE SELECT || nm;
EXECUTE IMMEDIATE DROP PROCEDURE || nm;
RETURN TRUE;
END;
END_PROC;

An example call and output follows:


MYDB.SCHEMA(USER)=> call exec_nzplsql_block(BEGIN_PROC DECLARE var char;
BEGIN var:= test; raise NOTICE This is a %, var; END; END_PROC);
NOTICE: This is a test
EXEC_NZPLSQL_BLOCK
-------------------t
(1 row)

B-2

IBM Netezza Stored Procedures Developer's Guide

Notices
This information was developed for products and services offered in the U.S.A.
IBM may not offer the products, services, or features discussed in this document in
other countries. Consult your local IBM representative for information on the
products and services currently available in your area. Any reference to an IBM
product, program, or service is not intended to state or imply that only that IBM
product, program, or service may be used. Any functionally equivalent product,
program, or service that does not infringe any IBM intellectual property right may
be used instead. However, it is the user's responsibility to evaluate and verify the
operation of any non-IBM product, program, or service.
IBM may have patents or pending patent applications covering subject matter
described in this document. The furnishing of this document does not grant you
any license to these patents. You can send license inquiries, in writing, to: This
information was developed for products and services offered in the U.S.A.
IBM Director of Licensing
IBM Corporation
North Castle Drive
Armonk, NY 10504-1785 U.S.A.
For license inquiries regarding double-byte (DBCS) information, contact the IBM
Intellectual Property Department in your country or send inquiries, in writing, to:
IBM World Trade Asia Corporation
Licensing 2-31 Roppongi 3-chome, Minato-ku
Tokyo 106-0032, Japan
The following paragraph does not apply to the United Kingdom or any other
country where such provisions are inconsistent with local law:
INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THIS
PUBLICATION "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS
FOR A PARTICULAR PURPOSE. Some states do not allow disclaimer of express or
implied warranties in certain transactions, therefore, this statement may not apply
to you.
This information could include technical inaccuracies or typographical errors.
Changes are periodically made to the information herein; these changes will be
incorporated in new editions of the publication. IBM may make improvements
and/or changes in the product(s) and/or the program(s) described in this
publication at any time without notice.
Any references in this information to non-IBM Web sites are provided for
convenience only and do not in any manner serve as an endorsement of those Web
sites. The materials at those Web sites are not part of the materials for this IBM
product and use of those Web sites is at your own risk.
IBM may use or distribute any of the information you supply in any way it
believes appropriate without incurring any obligation to you.
Copyright IBM Corp. 2009, 2014

C-1

Licensees of this program who wish to have information about it for the purpose
of enabling: (i) the exchange of information between independently created
programs and other programs (including this one) and (ii) the mutual use of the
information which has been exchanged, should contact:
IBM Corporation
Software Interoperability Coordinator, Department 49XA
3605 Highway 52 N
Rochester, MN 55901
U.S.A.
Such information may be available, subject to appropriate terms and conditions,
including in some cases, payment of a fee.
The licensed program described in this document and all licensed material
available for it are provided by IBM under terms of the IBM Customer Agreement,
IBM International Program License Agreement or any equivalent agreement
between us.
Any performance data contained herein was determined in a controlled
environment. Therefore, the results obtained in other operating environments may
vary significantly. Some measurements may have been made on development-level
systems and there is no guarantee that these measurements will be the same on
generally available systems. Furthermore, some measurements may have been
estimated through extrapolation. Actual results may vary. Users of this document
should verify the applicable data for their specific environment.
Information concerning non-IBM products was obtained from the suppliers of
those products, their published announcements or other publicly available sources.
IBM has not tested those products and cannot confirm the accuracy of
performance, compatibility or any other claims related to non-IBM products.
Questions on the capabilities of non-IBM products should be addressed to the
suppliers of those products.
All statements regarding IBM's future direction or intent are subject to change or
withdrawal without notice, and represent goals and objectives only.
All IBM prices shown are IBM's suggested retail prices, are current and are subject
to change without notice. Dealer prices may vary.
This information contains examples of data and reports used in daily business
operations. To illustrate them as completely as possible, the examples include the
names of individuals, companies, brands, and products. All of these names are
fictitious and any similarity to the names and addresses used by an actual business
enterprise is entirely coincidental.
COPYRIGHT LICENSE:
This information contains sample application programs in source language, which
illustrate programming techniques on various operating platforms. You may copy,
modify, and distribute these sample programs in any form without payment to
IBM, for the purposes of developing, using, marketing or distributing application
programs conforming to the application programming interface for the operating
platform for which the sample programs are written. These examples have not
been thoroughly tested under all conditions. IBM, therefore, cannot guarantee or
imply reliability, serviceability, or function of these programs.

C-2

IBM Netezza Stored Procedures Developer's Guide

Each copy or any portion of these sample programs or any derivative work, must
include a copyright notice as follows:
your company name) (year). Portions of this code are derived from IBM Corp.
Sample Programs.
Copyright IBM Corp. _enter the year or years_.
If you are viewing this information softcopy, the photographs and color
illustrations may not appear.

Trademarks
IBM, the IBM logo, ibm.com and Netezza are trademarks or registered trademarks
of International Business Machines Corporation in the United States, other
countries, or both. If these and other IBM trademarked terms are marked on their
first occurrence in this information with a trademark symbol ( or ), these
symbols indicate U.S. registered or common law trademarks owned by IBM at the
time this information was published. Such trademarks may also be registered or
common law trademarks in other countries. A current list of IBM trademarks is
available on the web at "Copyright and trademark information" at
http://www.ibm.com/legal/copytrade.shtml.
Adobe is a registered trademark of Adobe Systems Incorporated in the United
States, and/ or other countries.
Linux is a registered trademark of Linus Torvalds in the United States, other
countries, or both.
Microsoft, Windows, Windows NT, and the Windows logo are trademarks of
Microsoft Corporation in the United States, other countries, or both.
NEC is a registered trademark of NEC Corporation.
UNIX is a registered trademark of The Open Group in the United States and other
countries.
Oracle and Java are registered trademarks of Oracle and/or its affiliates. Other
names may be trademarks of their respective owners.
Red Hat is a trademark or registered trademark of Red Hat, Inc. in the United
States and/or other countries.
D-CC, D-C++, Diab+, FastJ, pSOS+, SingleStep, Tornado, VxWorks, Wind River,
and the Wind River logo are trademarks, registered trademarks, or service marks
of Wind River Systems, Inc. Tornado patent pending.
APC and the APC logo are trademarks or registered trademarks of American
Power Conversion Corporation.
Other company, product or service names may be trademarks or service marks of
others.

Notices

C-3

C-4

IBM Netezza Stored Procedures Developer's Guide

Index
Special characters
$var variable 2-6
%, used in message formats 2-22
%ROWTYPE attribute[ROWTYPE
attribute] 2-5
%TYPE attribute[TYPE attribute] 2-5

A
account permissions, managing 3-1
admin user, permissions 3-1
aliases, for data types 2-9
ALTER PROCEDURE command A-1
using 3-10
ANY keyword 3-6
ANY keyword, for procedure input
arguments 3-6
arithmetic evaluations, and stored
procedures 2-12
array variables
assigning a value 2-10
in NZPLSQL 2-10
reference support 2-10
assignment statement 2-15
AUTOCOMMIT ON blocks 2-3

B
backups, and stored procedures 1-6
BEGIN_PROC keyword 1-5
best practices, stored procedures 1-3
block comments 2-4
block quoting support 1-5
block structured language 2-1
block, in NZPLSQL 2-1

C
CALL command
discarding results 2-16
example 3-10
usage A-3
call recursion limit 2-16
casting
impact on stored procedures 2-12
input values to match signature
sizes 3-6
COMMENT ON PROCEDURE command,
using 3-11
comments
best practices 3-11
in NZPLSQL 2-4
conditional control 2-17
CONSTANT option, variables 2-5
constants, in NZPLSQL 2-5
control statements
conditional 2-17
IF-THEN statements 2-17
iterative 2-19
Copyright IBM Corp. 2009, 2014

control structures 2-17


COUNT method, array variables 2-10
CREATE OR REPLACE PROCEDURE
command A-5
generic arguments example 3-7
using 3-4
cross-database access, to stored
procedures 1-4

D
data types 2-9
DEBUG messages 2-22
declarations section, in NZPLSQL 2-1
DEFAULT clause, variables 2-5
disk space problems, avoiding for large
datasets 2-27
double dash comments 2-4
downgrade cautions 1-7
DROP PROCEDURE command A-7
using 3-12
dropping when database is dropped 1-6
dynamic queries 2-16

E
ELSE IF statements 2-17
ELSIF statements 2-17
END_PROC keyword 1-5
error handling, in NZPLSQL 2-23
errors, raising 2-22
EXCEPTION messages 2-22
EXCEPTION statement 2-23
EXEC command, using 3-10
execute as caller permissions 1-3
execute as owner permissions 1-3
EXECUTE command A-3
using 3-10
EXECUTE IMMEDIATE statement 2-16
EXECUTE PROCEDURE command,
using 3-10
EXIT statement 2-19
expressions
in NZPLSQL 2-11
string processing best practices 2-16
EXTEND method, array variables 2-10

F
FOR IN loop statement 2-21
FOR loop, iteration step count 2-19
FOR statement 2-19
FOR-IN EXECUTE statement 2-21
fully-qualified object names, for stored
procedures 1-4

G
generic arguments, benefits of

3-6

generic procedures
ANY keyword 3-6
input arguments 3-6
registering 3-7
generic return value 3-7
GRANT ALL command, create
permission 3-1
GRANT command
alter permission 3-1
create permission 3-1
drop permission 3-1
execute permission 3-1

H
hiding the procedure body

3-8

I
IF statements 2-17
IF-THEN-ELSE IF statements 2-17
IF-THEN-ELSE statements 2-17
implicit casting
for procedure input values 3-6
in assignments 2-15
in stored procedures, best
practices 2-12
infinite loop, handling 2-28
iterative control 2-19

L
labels, used to identify variables 2-7
large datasets, managing 2-27
LAST_OID variable 2-17
loop processing 2-28
LOOP statement 2-19
loops
infinite, handling 2-28
iterate over integer count 2-19
repeating while true 2-19
terminating 2-19
unconditional 2-19

M
massively parallel processing (MPP),
designing procedures for 2-28
message levels, types of 2-22
messages, reporting 2-22

N
Netezza SQL commands
for stored procedures 1-2
reference A-1
NOT NULL option, variables 2-5
NOTICE messages 2-22

X-1

NzAdmin administrative interface, for


stored procedures 3-12
NZPLSQL language
about 1-2
array variables 2-10
comments 2-4
constants 2-5
control structures 2-17
description of 2-1
dynamic queries 2-16
exception support 2-23
expressions 2-11
message and error reporting 2-22
procedural logic 1-2
record assignments 2-20
record variable 2-20
records 2-20
statements 2-15
variable datatypes 2-5
variables 2-5

O
obfuscating procedures
using in registration scripts 3-9
using wrap_nzplsql 3-8
outputs
ALTER PROCEDURE command A-1
CREATE OR REPLACE PROCEDURE
command A-5
DROP PROCEDURE command A-7
SHOW PROCEDURE command A-9
overflows, avoiding in stored
procedures 2-12
overloading procedures 3-5
owner, stored procedure 3-1

P
parameters 2-6
patches, and stored procedures 1-7
PATH SQL session variable 1-4
permissions 3-1
granting
all 3-1
alter permission 3-1
create 3-1
drop permission 3-1
execute permission 3-1
managing 3-1
revoking
create permission 3-1
drop permission 3-1
execute permission 3-1
PL/pgSQL language 1-2
privileges, commands
ALTER PROCEDURE command A-1
CALL or EXECUTE PROCEDURE
command A-3
CREATE PROCEDURE
command A-5
privileges, managing for accounts 3-1
PROC_ARGUMENT_TYPES array 2-6
procedural programming language 1-1
procedures
calling 2-16

X-2

procedures (continued)
obfuscating 3-8
returning from 2-17

Q
quote_ident function 2-16
quote_literal function 2-16

R
RAISE statement 2-22
RECORD variable 2-20
records
about 2-20
assignments 2-20
recursion limit, calls 2-16
registration script, with obfuscated
procedures 3-9
restores, and stored procedures 1-6
RETURN command 2-17
return value, generic 3-7
REVOKE command
alter permission 3-1
drop permission 3-1
revoking
alter permission 3-1
ROLLBACK, using with
REFTABLE 2-27
ROW_COUNT variable 2-17

S
scoping, variables 2-7
SHOW PROCEDURE command A-9
using 3-12
signature
about 3-5
used in permissions 3-1
SQL commands, for stored
procedures A-1
SQLERRM variable 2-23
statements
assignment 2-15
in NZPLSQL 2-15
section, in NZPLSQL 2-1
stored procedures 1-4, 1-6
about 1-1
account permission overview 3-1
altering 3-10, A-1
benefits of 1-1
best practices 1-3
block quoting support 1-5
call recursion limit 2-16
calling, starting 3-10
commenting on 3-11
creating 1-3, 3-4
creating or replacing A-5
designing 3-4
displaying information for 3-12
dropping 3-12, A-7
example use of 1-1
fully qualified name of 1-4
generic, registering 3-7
impact of implicit casting 2-12
input 1-2

IBM Netezza Stored Procedures Developer's Guide

stored procedures (continued)


limitations of size-specific input
arguments 3-5
loop processing 2-28
managing 3-1
math best practices 2-12
obfuscating the body 3-8
owner of 3-1
PATH session variable 1-4
process to create 3-4
return types 1-2
run 1-3
security and access controls 1-1
security considerations 1-3
See also procedures. 1-1
showing A-9
signature 3-5
starting
CALL A-3
using EXECUTE A-3
stored procedures
result sets 1-2
user of 3-1
strings, processing in expressions 2-16

T
transaction commits in stored
procedures 2-2
TRIM method, array variables

2-10

U
unconditional loop 2-19
upgrades, and stored procedures

1-7

V
VARARGS keyword 2-6, 3-7
variable arguments, benefits of
variable scoping 2-7
variables
datatypes 2-5
in NZPLSQL 2-5

3-7

W
WHILE statement 2-19
wrap_nzplsql built-in procedure

3-8



Part Number: 20470-05 Rev. 1

Printed in USA

S-ar putea să vă placă și