Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
50
Добавлен:
16.04.2013
Размер:
5.97 Mб
Скачать

Assigning Values to Records

DECLARE

TYPE EmpRec IS RECORD (

emp_id

NUMBER(4)

last_name

VARCHAR2(10),

dept_num

NUMBER(2),

job_title

VARCHAR2(9),

salary

NUMBER(7,2));

FUNCTION nth_highest_salary (n INTEGER) RETURN EmpRec IS ...

BEGIN NULL;

END;

/

Like scalar variables, user-defined records can be declared as the formal parameters of procedures and functions:

DECLARE

TYPE EmpRec IS RECORD ( emp_id emp.empno%TYPE, last_name VARCHAR2(10), job_title VARCHAR2(9), salary NUMBER(7,2));

...

PROCEDURE raise_salary (emp_info EmpRec); BEGIN

...

END;

/

Assigning Values to Records

To set all the fields in a record to default values, assign to it an uninitialized record of the same type:

DECLARE

TYPE RecordTyp IS RECORD (field1 NUMBER, field2 VARCHAR2(32) DEFAULT 'something');

rec1 RecordTyp; rec2 RecordTyp;

BEGIN

--At first, rec1 has the values we assign. rec1.field1 := 100; rec1.field2 := 'something else';

--Assigning an empty record to rec1 resets fields to their default values.

--Field1 is NULL and field2 is 'something' (because of the DEFAULT clause above). rec1 := rec2;

dbms_output.put_line('Field1 = ' || NVL(TO_CHAR(rec1.field1),'<NULL>') || ',

field2 = ' || rec1.field2); END;

/

You can assign a value to a field in a record using an assignment statement with dot notation:

emp_info.last_name := 'Fields';

Instead of assigning values separately to each field in a record, you can assign values to all fields at once.

You can assign one user-defined record to another if they have the same datatype. Having fields that match exactly is not enough. Consider the following example:

5-34 PL/SQL User's Guide and Reference

Assigning Values to Records

DECLARE

--Two identical type declarations.

TYPE DeptRec1 IS RECORD ( dept_num NUMBER(2), dept_name VARCHAR2(14)); TYPE DeptRec2 IS RECORD ( dept_num NUMBER(2), dept_name VARCHAR2(14)); dept1_info DeptRec1;

dept2_info DeptRec2; dept3_info DeptRec2;

BEGIN

--Not allowed; different datatypes, even though fields are the same.

--dept1_info := dept2_info;

--This assignment is OK because the records have the same type. dept2_info := dept3_info;

END;

/

You can assign a %ROWTYPE record to a user-defined record if their fields match in number and order, and corresponding fields have the same datatypes:

DECLARE

TYPE RecordTyp IS RECORD (last employees.last_name%TYPE, id employees.employee_ id%TYPE);

CURSOR c1 IS SELECT last_name, employee_id FROM employees;

--Rec1 and rec2 have different types. But because rec2 is based on a %ROWTYPE, we can

--assign is to rec1 as long as they have the right number of fields and the fields

--have the right datatypes. rec1 RecordTyp;

rec2 c1%ROWTYPE;

BEGIN

SELECT last_name, employee_id INTO rec2 FROM employees WHERE ROWNUM < 2; rec1 := rec2;

dbms_output.put_line('Employee #' || rec1.id || ' = ' || rec1.last); END;

/

You can also use the SELECT or FETCH statement to fetch column values into a record. The columns in the select-list must appear in the same order as the fields in your record.

DECLARE

TYPE RecordTyp IS RECORD (last employees.last_name%TYPE, id employees.employee_ id%TYPE);

rec1 RecordTyp; BEGIN

SELECT last_name, employee_id INTO rec1 FROM employees WHERE ROWNUM < 2; dbms_output.put_line('Employee #' || rec1.id || ' = ' || rec1.last);

END;

/

You cannot assign a list of values to a record using an assignment statement. There is no constructor-like notation for records.

Comparing Records

Records cannot be tested for nullity, or compared for equality, or inequality.

Using PL/SQL Collections and Records 5-35

Assigning Values to Records

If you want to make such comparisons, write your own function that accepts two records as parameters and does the appropriate checks or comparisons on the corresponding fields.

Inserting PL/SQL Records into the Database

A PL/SQL-only extension of the INSERT statement lets you insert records into database rows, using a single variable of type RECORD or %ROWTYPE in the VALUES clause instead of a list of fields. That makes your code more readable and maintainable.

If you issue the INSERT through the FORALL statement, you can insert values from an entire collection of records.

The number of fields in the record must equal the number of columns listed in the INTO clause, and corresponding fields and columns must have compatible datatypes. To make sure the record is compatible with the table, you might find it most convenient to declare the variable as the type table_name%ROWTYPE.

Example 5–34 Inserting a PL/SQL Record Using %ROWTYPE

This example declares a record variable using a %ROWTYPE qualifier. You can insert this variable without specifying a column list. The %ROWTYPE declaration ensures that the record attributes have exactly the same names and types as the table columns.

DECLARE

dept_info dept%ROWTYPE; BEGIN

--deptno, dname, and loc are the table columns.

--The record picks up these names from the %ROWTYPE. dept_info.deptno := 70;

dept_info.dname := 'PERSONNEL'; dept_info.loc := 'DALLAS';

--Using the %ROWTYPE means we can leave out the column list

--(deptno, dname, loc) from the INSERT statement. INSERT INTO dept VALUES dept_info;

END;

/

Updating the Database with PL/SQL Record Values

A PL/SQL-only extension of the UPDATE statement lets you update database rows using a single variable of type RECORD or %ROWTYPE on the right side of the SET clause, instead of a list of fields.

If you issue the UPDATE through the FORALL statement, you can update a set of rows using values from an entire collection of records.

Also with an UPDATE statement, you can specify a record in the RETURNING clause to retrieve new values into a record. If you issue the UPDATE through the FORALL statement, you can retrieve new values from a set of updated rows into a collection of records.

The number of fields in the record must equal the number of columns listed in the SET clause, and corresponding fields and columns must have compatible datatypes.

Example 5–35 Updating a Row Using a Record

You can use the keyword ROW to represent an entire row:

5-36 PL/SQL User's Guide and Reference

Assigning Values to Records

DECLARE

dept_info dept%ROWTYPE; BEGIN

dept_info.deptno := 30; dept_info.dname := 'MARKETING'; dept_info.loc := 'ATLANTA';

--The row will have values for the filled-in columns, and null

--for any other columns.

UPDATE dept SET ROW = dept_info WHERE deptno = 30;

END;

/

The keyword ROW is allowed only on the left side of a SET clause.

The argument to SET ROW must be a real PL/SQL record, not a subquery that returns a single row.

The record can also contain collections or objects.

Example 5–36 Using the RETURNING Clause with a Record

The INSERT, UPDATE, and DELETE statements can include a RETURNING clause, which returns column values from the affected row into a PL/SQL record variable. This eliminates the need to SELECT the row after an insert or update, or before a delete.

By default, you can use this clause only when operating on exactly one row. When you use bulk SQL, you can use the form RETURNING BULK COLLECT INTO to store the results in one or more collections.

The following example updates the salary of an employee and retrieves the employee's name, job title, and new salary into a record variable:

DECLARE

TYPE EmpRec IS RECORD (last_name employees.last_name%TYPE, salary employees.salary%TYPE);

emp_info EmpRec; emp_id NUMBER := 100;

BEGIN

UPDATE employees SET salary = salary * 1.1 WHERE employee_id = emp_id RETURNING last_name, salary INTO emp_info;

dbms_output.put_line('Just gave a raise to ' || emp_info.last_name || ', who now makes ' || emp_info.salary);

ROLLBACK;

END;

/

Restrictions on Record Inserts/Updates

Currently, the following restrictions apply to record inserts/updates:

Record variables are allowed only in the following places:

On the right side of the SET clause in an UPDATE statement

In the VALUES clause of an INSERT statement

In the INTO subclause of a RETURNING clause

Record variables are not allowed in a SELECT list, WHERE clause, GROUP BY clause, or ORDER BY clause.

Using PL/SQL Collections and Records 5-37

Соседние файлы в папке Oracle 10g