Records in NZPLSQL
In NZPLSQL, a record can be used in a SELECT operation or FOR statement to hold one database row.
A variable of type RECORD can be used for different selections. Accessing an empty record, or attempting to assign a value to a field of an empty record, results in a runtime error.
A record can be either structured or unstructured:
- An unstructured record does not specify a row type, and can be used when the structure of
the row being read is unknown. Issue the following statement to declare an unstructured
record:
whererecordname RECORD;
recordname
represents the name of the record. - A structured record explicitly specifies a row type by means of either an AS keyword or
the %ROWTYPE attribute. Issue one of the following statements to declare a structured
record:
whererecordname RECORD AS row_type; recordname tablename%ROWTYPE;
row_type
represents the name of a predefined row type andtablename
represents the name of a table whose rows structure corresponds to the desired row type.
To define a row type, issue a CREATE TYPE statement, for
example:
CREATE TYPE DEPTROW AS ROW (DEPTNO VARCHAR(3),
DEPTNAME VARCHAR(29),
MGRNO CHAR(6),
ADMRDEPT CHAR(3),
LOCATION CHAR(16))
Assigning a complete selection into a record or row
You can use the following query to assign a complete selection into a record or
row:
SELECT expressions INTO target FROM ...;
The target value can be a record,
a row variable, or a comma-separated list of variables and record fields or row fields. If the query
returns several rows, only the first row is moved into the target fields; all others are
discarded.Note: This interpretation of SELECT INTO is different from that of SQL, in which the INTO target is
a newly created table. To create a table from a SELECT result from within an NZPLSQL procedure, use
a CREATE TABLE AS SELECT statement.
If the target is a row, record, or variable list, the selected values must exactly match the structure of the target. The FROM keyword can be followed by any valid qualification, grouping, or sorting clauses that can be specified for a SELECT statement.
After a record or row is assigned to a record, you can use dot notation to access the fields of
that record. For example, to access the first_name and last_name fields in the record
users_rec:
DECLARE
users_rec RECORD AS users_rowtype;
full_name varchar;
BEGIN
SELECT * INTO users_rec FROM users WHERE user_id=3;
full_name := users_rec.first_name || ' ' || users_rec.last_name;
Checking whether a value was assigned to a record
There are several ways to check whether a value was assigned to a record by a SELECT INTO statement:
- Use the special variable named FOUND of type Boolean immediately after the SELECT INTO
statement. For
example:
SELECT * INTO myrec FROM EMP WHERE empname = myname; IF NOT FOUND THEN RAISE EXCEPTION 'employee % not found', myname; END IF;
- Use
ROW_COUNT >= 1
instead ofFOUND
. - Use IS NULL or ISNULL conditionals to test whether a record or row is NULL. For
example:
DECLARE users_rec RECORD AS users_rowtype; 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;
Iterating through the results of a query
There are two methods for iterating through the results of a query and manipulating the result
data. In both methods, the record or row is assigned all the rows that are returned by the select
clause and the loop body runs for each row.
- Use a FOR...IN statement
- The syntax of a FOR...IN statement
is:
A FOR...IN statement can use either a structured or an unstructured record type. If the loop is terminated with an EXIT statement, the last assigned row is still accessible.[<<label>>] FOR record_or_row IN select_clause LOOP statements END LOOP;
For example:DECLARE mviews RECORD AS cs_materialized_views_rowtype; -- this record is usable ONLY 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, 'Can't execute SQL while processing SQL for %', mview.my_name; END LOOP; CALL cs_log('Done refreshing materialized views.'); return 1; end;
- Use a FOR...IN EXECUTE statement
- The syntax of a FOR...IN EXECUTE statement is similar to that of a FOR...IN statement, except
that the source SELECT statement is specified as a string
expression:
A FOR...IN EXECUTE statement must use a structured record type. A FOR...IN EXECUTE statement lets you create a dynamic statement. For example, you can pass in the SELECT statement as a VARCHAR string into the NZPLSQL procedure.[<<label>>] FOR record_or_row IN EXECUTE 'select_clause' LOOP statements END LOOP;