Netezza Stored Procedures Guide Rev 2014
Netezza Stored Procedures Guide Rev 2014
Netezza Stored Procedures Guide Rev 2014
Release 7.1
IBM Netezza
Release 7.1
Note
Before using this information and the product it supports, read the information in Notices on page C-1
Contents
Electronic emission notices . . . . . . . . . . . . . . . . . . . . . . . . . . . v
Regulatory and compliance . . . . . . . . . . . . . . . . . . . . . . . . . . . ix
About this publication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi
If you need help . . . . .
How to send your comments
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. xi
. xi
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. 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
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
2-27
2-27
2-28
2-28
2-28
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. 3-1
. 3-4
. 3-4
. 3-4
. 3-5
. 3-8
. 3-10
. 3-10
. 3-11
. 3-12
. 3-12
. 3-12
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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
vi
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.
vii
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.
viii
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.
ix
xi
xii
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.
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)
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
1-2
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.
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
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
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.
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 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
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.
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').
1-5
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;
Related concepts:
Obfuscate the procedure body on page 3-8
1-6
1-7
1-8
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.
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
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;
2-3
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
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 */.
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;
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;
2-6
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;
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;
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;
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
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)
VARCHAR
CHARACTER
VARYING,
VARCHAR(n),
CHARACTER
VARYING(n), CHAR
VARYING(n)
NCHAR
NATIONAL
CHARACTER,
NATIONAL CHAR(n),
NCHAR(size)
NVARCHAR
DATE
TIMESTAMP
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).
2-9
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
NUMERIC(p,s)
NUMERIC, DEC,
DEC(p,s),
DECIMAL(p,s),
DECIMAL
REAL
FLOAT(p), FLOAT4
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
BYTEINT
INT1
SMALLINT
INT2
BIGINT
INT8
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
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 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.
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
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)
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:
2-13
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
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.
2-15
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:
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 ...;
2-16
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;
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
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
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 ...;
2-20
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;
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
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:
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.
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
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.
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;
2-24
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;
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;
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
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.
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.
2-27
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
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
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
2-29
2-30
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.
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;
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;
For example, the following command revokes Create Procedure permissions from
the group analysts:
3-2
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;
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;
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
3-3
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
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))
...
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 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...
3-6
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.
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
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
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)
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.
3-9
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 customer();
EXEC customer();
EXECUTE customer();
EXECUTE PROCEDURE customer();
SELECT customer();
Related reference:
Appendix A, SQL command reference, on page A-1
3-10
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
Related concepts:
Create a stored procedure on page 3-4
Related reference:
The ALTER PROCEDURE command on page A-1
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.
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
Related reference:
The DROP PROCEDURE command on page A-7
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
3-12
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.
3-13
3-14
Description
More information
ALTER PROCEDURE
Changes a stored
procedure.
CALL or EXEC[UTE [
PROCEDURE]]
Runs a stored
procedure.
Adds or updates a
stored procedure.
DROP PROCEDURE
Drops or deletes a
stored procedure.
SHOW PROCEDURE
Displays
information about
stored procedures.
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
Synopsis
ALTER PROCEDURE <name> (<args>) [ RETURNS <type>]
[ EXECUTE AS OWNER | EXECUTE AS CALLER ] [AS <procedure_body>];
ALTER PROCEDURE <name> (<args>) OWNER TO <user>;
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
A-2
Description
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;
Related concepts:
Alter a stored procedure on page 3-10
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
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
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);
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.
A-5
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
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
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
ERROR: ProcedureCreate:
procedure NAME already exists
with the same signature
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
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;
Related concepts:
Register generic procedures on page 3-7
Synopsis
DROP PROCEDURE <name> (<arguments>)
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
Outputs
The DROP PROCEDURE command has the following outputs:
Table A-9. DROP PROCEDURE Outputs
Output
Description
DROP PROCEDURE
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
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
Synopsis
SHOW PROCEDURE [ALL | <name>] [VERBOSE]
Inputs
The SHOW PROCEDURE command takes the following inputs:
Table A-10. SHOW PROCEDURE inputs
Input
Description
ALL
name
VERBOSE
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
A-9
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)
Related concepts:
Show information about a stored procedure on page 3-12
A-10
B-1
B-2
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
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
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
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
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
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
Printed in USA