Working With Composite Data Types

Download as ppt, pdf, or txt
Download as ppt, pdf, or txt
You are on page 1of 24

6

Working with
Composite Data Types

Copyright © 2007, Oracle. All rights reserved.


Objectives

After completing this lesson, you should be able to do the


following:
• Create user-defined PL/SQL records
• Create a record with the %ROWTYPE attribute
• Create an INDEX BY table
• Create an INDEX BY table of records
• Describe the differences among records, tables, and tables
of records

6-2 Copyright © 2007, Oracle. All rights reserved.


Composite Data Types

• Can hold multiple values (unlike scalar types)


• Are of two types:
– PL/SQL records
– PL/SQL collections

INDEX BY tables or associative arrays

Nested table

VARRAY

6-3 Copyright © 2007, Oracle. All rights reserved.


Composite Data Types

• Use PL/SQL records when you want to store values of


different data types but only one occurrence at a time.
• Use PL/SQL collections when you want to store values of the
same data type.

6-4 Copyright © 2007, Oracle. All rights reserved.


PL/SQL Records

• Must contain one or more components (called fields) of any


scalar, RECORD, or INDEX BY table data type
• Are similar to structures in most third-generation languages
(including C and C++)
• Are user defined and can be a subset of a row in a table
• Treat a collection of fields as a logical unit
• Are convenient for fetching a row of data from a table for
processing

6-5 Copyright © 2007, Oracle. All rights reserved.


Creating a PL/SQL Record

Syntax:

1 TYPE type_name IS RECORD


(field_declaration[, field_declaration]…);

2 identifier type_name;

field_declaration:
field_name {field_type | variable%TYPE
| table.column%TYPE | table%ROWTYPE}
[[NOT NULL] {:= | DEFAULT} expr]

6-6 Copyright © 2007, Oracle. All rights reserved.


Creating a PL/SQL Record

Declare variables to store the name, job, and salary of a new


employee.
Example:
DECLARE
type t_rec is record
(v_sal number(8),
v_minsal number(8) default 1000,
v_hire_date employees.hire_date%type,
v_rec1 employees%rowtype);
v_myrec t_rec;
BEGIN
v_myrec.v_sal := v_myrec.v_minsal + 500;
v_myrec.v_hire_date := sysdate;
SELECT * INTO v_myrec.v_rec1
FROM employees WHERE employee_id = 100;
DBMS_OUTPUT.PUT_LINE(v_myrec.v_rec1.last_name ||' '||
to_char(v_myrec.v_hire_date) ||' '|| to_char(v_myrec.v_sal));
END;

6-7 Copyright © 2007, Oracle. All rights reserved.


PL/SQL Record Structure

Field1 (data type) Field2 (data type) Field3 (data type)

Example:

Field1 (data type) Field2 (data type) Field3 (data type)


employee_id number(6) last_name varchar2(25) job_id varchar2(10)

100 King AD_PRES

6-8 Copyright © 2007, Oracle. All rights reserved.


%ROWTYPE Attribute

• Declare a variable according to a collection of columns in a


database table or view.
• Prefix %ROWTYPE with the database table or view.
• Fields in the record take their names and data types from the
columns of the table or view.
Syntax:
DECLARE
identifier reference%ROWTYPE;

6-9 Copyright © 2007, Oracle. All rights reserved.


Advantages of Using %ROWTYPE

• The number and data types of the underlying database


columns need not be known—and, in fact, might change at
run time.
• The %ROWTYPE attribute is useful when retrieving a row with
the SELECT * statement.

6 - 11 Copyright © 2007, Oracle. All rights reserved.


%ROWTYPE Attribute: Example

DECLARE
v_employee_number number:= 124;
v_emp_rec employees%ROWTYPE;
BEGIN
SELECT * INTO v_emp_rec FROM employees
WHERE employee_id = v_employee_number;
INSERT INTO retired_emps(empno, ename, job, mgr,
hiredate, leavedate, sal, comm, deptno)
VALUES (v_emp_rec.employee_id, v_emp_rec.last_name,
v_emp_rec.job_id, v_emp_rec.manager_id,
v_emp_rec.hire_date, SYSDATE,
v_emp_rec.salary, v_emp_rec.commission_pct,
v_emp_rec.department_id);
END;
/

6 - 12 Copyright © 2007, Oracle. All rights reserved.


Inserting a Record
by Using %ROWTYPE

...
DECLARE
v_employee_number number:= 124;
v_emp_rec retired_emps%ROWTYPE;
BEGIN
SELECT employee_id, last_name, job_id, manager_id,
hire_date, hire_date, salary, commission_pct,
department_id INTO v_emp_rec FROM employees
WHERE employee_id = v_employee_number;
INSERT INTO retired_emps VALUES v_emp_rec;
END;
/
SELECT * FROM retired_emps;

6 - 13 Copyright © 2007, Oracle. All rights reserved.


Updating a Row in a Table
by Using a Record

SET VERIFY OFF


DECLARE
v_employee_number number:= 124;
v_emp_rec retired_emps%ROWTYPE;
BEGIN
SELECT * INTO v_emp_rec FROM retired_emps;
v_emp_rec.leavedate:=CURRENT_DATE;
UPDATE retired_emps SET ROW = v_emp_rec WHERE
empno=v_employee_number;
END;
/
SELECT * FROM retired_emps;

6 - 14 Copyright © 2007, Oracle. All rights reserved.


INDEX BY Tables or Associative Arrays

• Are PL/SQL structures with two columns:


– Primary key of integer or string data type
– Column of scalar or record data type
• Are unconstrained in size. However, the size depends on the
values that the key data type can hold.

6 - 15 Copyright © 2007, Oracle. All rights reserved.


Creating an INDEX BY Table

Syntax:
TYPE type_name IS TABLE OF
{column_type | variable%TYPE
| table.column%TYPE} [NOT NULL]
| table%ROWTYPE
[INDEX BY PLS_INTEGER | BINARY_INTEGER
| VARCHAR2(<size>)];
identifier type_name;
Declare an INDEX BY table to store the last names of
employees:
...
TYPE ename_table_type IS TABLE OF
employees.last_name%TYPE
INDEX BY PLS_INTEGER;
...
ename_table ename_table_type;

6 - 16 Copyright © 2007, Oracle. All rights reserved.


INDEX BY Table Structure

Unique key Value


... ...

1 Jones
5 Smith
3 Maduro

... ...

PLS_INTEGER Scalar

6 - 18 Copyright © 2007, Oracle. All rights reserved.


Creating an INDEX BY Table

DECLARE
TYPE ename_table_type IS TABLE OF
employees.last_name%TYPE
INDEX BY PLS_INTEGER;
TYPE hiredate_table_type IS TABLE OF DATE
INDEX BY PLS_INTEGER;
ename_table ename_table_type;
hiredate_table hiredate_table_type;
BEGIN
ename_table(1) := 'CAMERON';
hiredate_table(8) := SYSDATE + 7;
IF ename_table.EXISTS(1) THEN
INSERT INTO ...
...
END;
/

6 - 19 Copyright © 2007, Oracle. All rights reserved.


Using INDEX BY Table Methods

The following methods make INDEX BY tables easier to use:


• EXISTS • PRIOR
• COUNT • NEXT
• FIRST • DELETE
• LAST

6 - 20 Copyright © 2007, Oracle. All rights reserved.


INDEX BY Table of Records

Define an INDEX BY table variable to hold an entire row from a


table.
Example:
DECLARE
TYPE dept_table_type IS TABLE OF
departments%ROWTYPE
INDEX BY VARCHAR2(20);
dept_table dept_table_type;
-- Each element of dept_table is a record

6 - 21 Copyright © 2007, Oracle. All rights reserved.


INDEX BY Table of Records: Example

DECLARE
TYPE emp_table_type IS TABLE OF
employees%ROWTYPE INDEX BY PLS_INTEGER;
my_emp_table emp_table_type;
max_count NUMBER(3):= 104;
BEGIN
FOR i IN 100..max_count
LOOP
SELECT * INTO my_emp_table(i) FROM employees
WHERE employee_id = i;
END LOOP;
FOR i IN my_emp_table.FIRST..my_emp_table.LAST
LOOP
DBMS_OUTPUT.PUT_LINE(my_emp_table(i).last_name);
END LOOP;
END;
/

6 - 23 Copyright © 2007, Oracle. All rights reserved.


Nested Tables

1 Bombay
2 Sydney
3 Oxford
4 London
.. ....
2 GB

6 - 24 Copyright © 2007, Oracle. All rights reserved.


VARRAY

1 Bombay
2 Sydney
3 Oxford
4 London
.. ....
10 Tokyo

6 - 26 Copyright © 2007, Oracle. All rights reserved.


Summary

In this lesson, you should have learned how to:


• Define and reference PL/SQL variables of composite data
types
– PL/SQL record
– INDEX BY table
– INDEX BY table of records
• Define a PL/SQL record by using the %ROWTYPE attribute

6 - 27 Copyright © 2007, Oracle. All rights reserved.


Practice 6: Overview

This practice covers the following topics:


• Declaring INDEX BY tables
• Processing data by using INDEX BY tables
• Declaring a PL/SQL record
• Processing data by using a PL/SQL record

6 - 28 Copyright © 2007, Oracle. All rights reserved.

You might also like