10.9 How do I…Achieve array functionality with PL/SQL Index-By tables?Problem
I need to declare variables in my PL/SQL code to represent columns retrieved from the database. Errors can occur if I don’t create the variable with the correct datatype and column width. If the column changes in the table, my code needs to be modified. I want to create variables to represent columns. I also want to create structures to represent records in my PL/SQL code. How do I create variables to represent records and columns?
Technique
In PL/SQL, it is possible to declare the datatype of a variable as the datatype of a table column using the %TYPE attribute. The %TYPE attribute ensures that the datatype of the variable is suitable for handling the column. The usage of the %TYPE attribute is shown here:
variable_name table_name.column_name%TYPE;
A separate variable is declared for each table column, using the %TYPE attribute. A single variable can be created to represent the entire row, by using the %ROWTYPE attribute. Variables declared with the %ROWTYPE attribute are structures containing all the columns in the table. The usage of the %ROWTYPE attribute is shown here:
variable_name table_name%ROWTYPE;
When a variable is declared using the %ROWTYPE attribute, its components are referenced using the syntax variable_name.column_name. When using cursors, the %ROWTYPE attribute can be used to declare a variable representing the columns returned by a cursor as:
variable_name cursor_name%ROWTYPE;
This is particularly useful when you are not dealing with all the columns of a table but only those returned by the cursor. Obviously, the cursor declaration has to appear before using the %ROWTYPE attribute with the cursor_name. Refer to Chapter 11 for more information on the use of cursors. You can also define a PL/SQL record type as
TYPE record_type IS
RECORD
(field_name1 datatype1 [NOT NULL] [DEFAULT default_value1],
field_name2 datatype2 [NOT NULL] [DEFAULT default_value2],
...
field_namen datatypen [NOT NULL] [DEFAULT default_valuen]);
where record_type is the name of the datatype representing the record. The field_name is the name of the field within the record, and data_type represents the datatype of the field. A NOT NULL constraint and a DEFAULT initial value for each field in the record can be optionally specified. A DEFAULT value must be provided for any NOT NULL fields in the record.
Steps
1. Run SQL*Plus and connect as the WAITE user account. CHP10_28.SQL, as shown in Figure 10.28, creates the sample table used in this How-To. Run the file to create the sample table and data.
The DEPT10 table created by the script contains two columns used to define column and record type variables in the following steps.
2. Run the CHP10_29.SQL file in SQL*Plus. The PL/SQL block contained in the file uses the %TYPE attribute when declaring variables to represent database columns. The code and results are shown in Figure 10.29.
Lines 1 through 3 contain the declarative section of the block. Lines 2 and 3 declare variables using the %TYPE attribute. The D_NO and D_NAME variables are declared with the datatype of the DEPT_NO and DEPT_NAME columns in the sample table, even though the datatypes are not specified. Lines 4 through 9 contain the execution section of the block. The query contained in lines 5 through 7 selects a record from the sample table and puts the results in the variables declared with the %TYPE attribute. Even though the datatype is not known to the programmer when the module is created, the %TYPE attribute ensures its correctness. The DBMS_OUTPUT package is used in lines 8 and 9 to display the values returned by the query. The exception section contained in lines 10 through 12 handles the exception raised if no data is returned by the query.
3. Run the CHP10_30.SQL file in SQL*Plus. The PL/SQL block contained in the file declares a record variable using the %ROWTYPE attribute (see Figure 10.30).
Lines 1 and 2 contain the declarative section of the block. Line 2 uses the %ROWTYPE attribute to declare a record variable representing all the columns in the DEPT10 table. Lines 3 through 8 contain the executable section of the block. The query defined in lines 4 through 6 retrieves a record from the sample table in Step 1 and places the columns in the components of the record variable. Line 5 shows how the columns of a record-type variable are referenced using dot notation. Lines 7 and 8 use the DBMS_OUTPUT package to display the values contained in the components of the record variable. The exception section contained in lines 9 through 11 handles the exception if no data is returned by the query.
4. Run the CHP10_31.SQL file in SQL*Plus. The PL/SQL block contained in the file declares a record variable of a user-defined RECORD type (see Figure 10.31).
Lines 2 through 5 contain the declarative section of the block. A user-defined composite type is defined in lines 2 through 4 using the TYPE IS RECORD syntax. Line 5 declares a record variable of the newly defined record type. Lines 6 through 11 contain the executable section of the block. The query defined in lines 7 through 9 retrieves a record from the sample table created in Step 1 and places the columns in the fields of the record variable. Line 8 shows how the columns of a record-type variable are referenced using dot notation. Lines 10 and 11 use the DBMS_OUTPUT package to display the values contained in the components of the record variable. The exception section contained in lines 12 through 14 handles the exception if the query fails to return a row from the table.
How It Works
The %TYPE attribute can be used to declare variables of the datatype contained in the column of a table. This enables you to declare variables without knowing the datatype of the value it will receive. The %ROWTYPE attribute enables you to declare a composite datatype containing all the columns in a table. Step 1 creates a sample table used in the following steps. Step 2 demonstrates the use of the %TYPE attribute by declaring variables to represent the columns in the sample table. Step 3 uses the %ROWTYPE attribute to declare a composite variable containing all the columns in the sample table. Step 4 uses the TYPE IS RECORD syntax to define a record type and then declare a record variable of that record type. A PL/SQL record type can contain another table or a record with composite fields.
Comments
It is good practice to use the %TYPE and %ROWTYPE attributes whenever you create a variable to represent a table column or create multiple variables to represent an entire record. Using the %TYPE and %ROWTYPE attributes ensures that your PL/SQL code will continue to work if the structure of the table or datatypes of a column change. A record type variable provides a means to group logically related variables to be treated as a single unit. Records can be passed as parameters to subprograms.