记录record
基于表的记录
emp%rowtype;
基于游标的记录
cursor c_emp is select empno,ename from emp;
rec_emp c_emp%rowtype;
用户定义的record
TYPE type_name IS RECORD
(field_name1 datatype1 [NOT NULL] [ := DEFAULT EXPRESSION],
field_name2 datatype2 [NOT NULL] [ := DEFAULT EXPRESSION],
...
field_nameN datatypeN [NOT NULL] [ := DEFAULT EXPRESSION]);
record_name TYPE_NAME;
declare
type rec_date_type is record (
rec_date date,
rec_day varchar2(12),
rec_time varchar2(8) := '00:00:00');
rec_d rec_date_type;
begin
select sysdate into rec_d.rec_date from dual;
rec_d.rec_day := to_char(rec_d.rec_date,'Day');
rec_d.rec_time := to_char(rec_d.rec_date,'hh24:mi:ss');
dbms_output.put_line('date is '||rec_d.rec_date);
dbms_output.put_line('day is '||rec_d.rec_day);
dbms_output.put_line('time is '||rec_d.rec_time);
end;
/
注意:
当声明记录类型时,也许会为单个字段指定NOT NULL约束。要记得必须初始化这种字段,这一点很重要。下的范例会导致语法错误,因为某记录字段在定义NOT NULL约束后没有初始化。
type sample_type is record(
field1 number(3),
field2 varchar2(3) not null);
正确的写法
type sample_type is record(
field1 number(3),
field2 varchar2(3) not null := 'ABC');
记录的兼容性
DECLARE
TYPE name_type1 IS RECORD(
first_name VARCHAR2(15),
last_name VARCHAR2(30));
TYPE name_type2 IS RECORD(
first_name VARCHAR2(15),
last_name VARCHAR2(30));
name_rec1 name_type1;
name_rec2 name_type2;
BEGIN
name_rec1.first_name := 'John';
name_rec1.last_name := 'Smith';
name_rec2 := name_rec1; -- illegal assignment
END;
这上例中,两个记录拥有相同的结构,但是每个记录的类型不同。因此在记录层次中,这些记录是不兼容的,也就是说,集合赋值语句会导致错误:
name_rec2 := name_rec1; -- illegal assignment
*
ERROR at line 13:
ORA-06550: line 13, column 27:
PLS-00382: expression is of wrong type
ORA-06550: line 13, column 3:
PL/SQL: Statement ignored
为把name_rec1赋予name_rec2,可以把name_rec1的每个字段赋予name_rec2的对应字段,或者可以声明name_rec2,以便于具有与name_rec1相同的数据类型,如下所示:
DECLARE
TYPE name_type1 IS RECORD(
first_name VARCHAR2(15),
last_name VARCHAR2(30));
name_rec1 name_type1;
name_rec2 name_type1;
BEGIN
name_rec1.first_name := 'John';
name_rec1.last_name := 'Smith';
name_rec2 := name_rec1; -- no longer illegal assignment
END;
上面说的赋值限制应用于用户定义记录。也就是说,可以把基于表或者基于游标的记录赋予用户定义类型,只要两者具有相同的结构
DECLARE
CURSOR course_cur IS
SELECT * FROM course WHERE rownum <= 4;
TYPE course_type IS RECORD(
course_no NUMBER(38),
description VARCHAR2(50),
cost NUMBER(9, 2),
prerequisite NUMBER(8),
created_by VARCHAR2(30),
created_date DATE,
modified_by VARCHAR2(30),
modified_date DATE);
course_rec1 course%ROWTYPE; -- table-based record
course_rec2 course_cur%ROWTYPE; -- cursor-based record
course_rec3 course_type; -- user-defined record
BEGIN
-- Populate table-based record
SELECT * INTO course_rec1 FROM course WHERE course_no = 10;
-- Populate cursor-based record
OPEN course_cur;
LOOP
FETCH course_cur
INTO course_rec2;
EXIT WHEN course_cur%NOTFOUND;
END LOOP;
course_rec1 := course_rec2;
course_rec3 := course_rec2;
END;
嵌套记录
DECLARE
TYPE name_type IS RECORD(
first_name VARCHAR2(15),
last_name VARCHAR2(30));
TYPE person_type IS RECORD(
name name_type,
street VARCHAR2(50),
city VARCHAR2(25),
state VARCHAR2(2),
zip VARCHAR2(5));
person_rec person_type;
BEGIN
SELECT first_name, last_name, street_address, city, state, zip
INTO person_rec.name.first_name,
person_rec.name.last_name,
person_rec.street,
person_rec.city,
person_rec.state,
person_rec.zip
FROM student
JOIN zipcode
USING (zip)
WHERE rownum < 2;
DBMS_OUTPUT.PUT_LINE('Name: ' || person_rec.name.first_name || ' ' ||
person_rec.name.last_name);
DBMS_OUTPUT.PUT_LINE('Street: ' || person_rec.street);
DBMS_OUTPUT.PUT_LINE('City: ' || person_rec.city);
DBMS_OUTPUT.PUT_LINE('State: ' || person_rec.state);
DBMS_OUTPUT.PUT_LINE('Zip: ' || person_rec.zip);
END;
enclosing_record.(nested_record or nested_collection).field_name
记录的集合
DECLARE
CURSOR name_cur IS
SELECT first_name, last_name
FROM student
WHERE ROWNUM <= 4;
TYPE name_type IS TABLE OF name_cur%ROWTYPE
INDEX BY BINARY_INTEGER;
name_tab name_type;
v_counter INTEGER := 0;
BEGIN
FOR name_rec IN name_cur LOOP
v_counter := v_counter + 1;
name_tab(v_counter).first_name := name_rec.first_name;
name_tab(v_counter).last_name := name_rec.last_name;
DBMS_OUTPUT.PUT_LINE('First Name('||v_counter||'): '||
name_tab(v_counter).first_name);
DBMS_OUTPUT.PUT_LINE('Last Name('||v_counter||'): '||
name_tab(v_counter).last_name);
END LOOP;
END;
record
最新推荐文章于 2017-11-22 15:16:18 发布