4. PLSQL的记录类型
4.1 创建记录类型
记录是一种复合的数据类型,一种有逻辑上相关联的独立元素组成的复合的数据类型
记录只能存储一行数据,行变量是记录的一种特殊形式,有继承的原结构(显式游标,表)
(1)直接访问记录的元素,分别给每个字段赋值
declare
type hrc_org_rec is record(hrc_org_id number,hrc_descr varchar2(20),org_short_name varchar2(30));
v_example_rec hrc_org_rec;
begin
v_example_rec.hrc_org_id:=1001;
v_example_rec.hrc_descr:='CEO/COO';
v_example_rec.org_short_name:='Office of CEO/COO ABC Inc.';
dbms_output.put_line(to_char(v_example_rec.hrc_org_id)||' '||v_example_rec.hrc_descr||' '||
v_example_rec.org_short_name);
exception when others then
null;
end;
(2)记录之间的赋值
declare
type hrc_org_rec is record(hrc_org_id number,hrc_descr varchar2(20),org_short_name varchar2(30));
v_example_rec1 hrc_org_rec;
v_example_rec2 hrc_org_rec;
begin
v_example_rec1.hrc_org_id:=1001;
v_example_rec1.hrc_descr:='CEO/COO';
v_example_rec1.org_short_name:='Office of CEO/COO ABC Inc.';
v_example_rec2:=v_example_rec1;
dbms_output.put_line(to_char(v_example_rec2.hrc_org_id)||' '||v_example_rec2.hrc_descr||' '||
v_example_rec2.org_short_name);
exception when others then
null;
end;
将上面的练习使用记录的方式实现:
declare
type rc is ref cursor;
v_rc rc;
v_deptno number;
type emp_dept_rec is record(v_dname varchar2(30),v_empno number,v_ename varchar2(30),v_job varchar2(30),v_hiredate date,v_sal number);
v_example_rec emp_dept_rec;
type emp_dept_rec1 is record(v_empno number,v_sal number,v_grade number);
v_example_rec1 emp_dept_rec1;
begin
open v_rc for select d.dname,e.empno,e.ename,e.job,e.hiredate,e.sal
from emp e,dept d
where e.deptno=d.deptno;
loop
fetch v_rc into v_example_rec; --必须要整一行都赋予记录
exit when(v_rc%notfound);
dbms_output.put_line(v_example_rec.v_dname||' '||v_example_rec.v_empno||' '||v_example_rec.v_ename||' '||v_example_rec.v_job||' '||to_char(v_example_rec.v_hiredate)||' '||v_example_rec.v_sal);
end loop;
close v_rc;
dbms_output.put_line('------------------------------------');
open v_rc for select a.empno,a.sal,s.grade
from emp a,salgrade s
where a.sal between s.losal and s.hisal;
loop
fetch v_rc into v_example_rec1;
exit when(v_rc%notfound);
dbms_output.put_line(to_char(v_example_rec1.v_empno)||' '||rpad(to_char(v_example_rec1.v_sal),10,' ')||' '||to_char(v_example_rec1.v_grade));
end loop;
close v_rc;
exception when others then
null;
end;
###########################################################################################
4.2 oracle的序列对象
(1) 定义一个序列:
create sequence hrc_org_seq minvalue 1 maxvalue 999999 start with 100 increment by 1;
(2) 查询验证:
select * from user_objects where object_name='HRC_ORG_SEQ';
select * from user_sequences;
(3) 使用方法:
SQL> select hrc_org_seq.nextval from dual;
NEXTVAL
----------
100
SQL> select hrc_org_seq.nextval from dual;
NEXTVAL
----------
101
SQL> select hrc_org_seq.nextval from dual;
NEXTVAL
----------
102
经常用作主键的生成器,比如:
SQL> select '44522'||to_char(sysdate,'yyyymmdd')||'BOSS'||hrc_org_seq.nextval from dual;
这个主键永远都不会重复
一般不用有业务含义的字段作主键,设计系统的时候要求一旦主键生成就不能再被修改,只能删除,也不能够update
有业务含义的字段经常会被修改,比如某个人手机号,证书号码,属性信息可能会发生错乱而导致数据的不一致。
(4)删除一个序列对象
SQL> drop sequence hrc_org_seq;
Sequence dropped
###########################################################################################
4.3记录类型的相关操作
(1) 通过select into 语句来给记录赋值
declare
type hrc_org_rec is record(hrc_org_id number,hrc_descr varchar2(20),org_short_name varchar2(30));
v_example_rec hrc_org_rec;
begin
select hrc_org_seq.nextval,h.hrc_descr,o.org_short_name
into v_example_rec
from org_tab o,hrc_tab h
where o.hrc_code=h.hrc_code
and o.org_id=1002; --使用select into方式填充记录,必须要确保查到的数据是一行
dbms_output.put_line(to_char(v_example_rec.hrc_org_id)||' '||v_example_rec.hrc_descr||' '||
v_example_rec.org_short_name);
exception when others then
null;
end;
(2)将6个org_id都通过记录读取并且输出,修改上面的程序
declare
type hrc_org_rec is record(
hrc_org_id number,
hrc_descr varchar2(20),
org_short_name varchar2(30));
v_example_rec hrc_org_rec;
begin
for idx in (select org_id from org_tab) loop
select hrc_org_seq.nextval, h.hrc_descr, o.org_short_name
into v_example_rec
from org_tab o, hrc_tab h
where o.hrc_code = h.hrc_code
and o.org_id = idx.org_id; --使用select into方式填充记录,必须要确保查到的数据是一行
dbms_output.put_line(to_char(v_example_rec.hrc_org_id) || ' ' ||
v_example_rec.hrc_descr || ' ' ||
v_example_rec.org_short_name);
end loop;
exception
when others then
null;
end;
注意:测试两个记录是否相等,不能 if record1 = record2 .... 错误的写法,只能使用每个字段的内容都去比较
declare
type hrc_org_rec is record(hrc_org_id number,hrc_descr varchar2(20),org_short_name varchar2(30));
v_example_rec1 hrc_org_rec;
v_example_rec2 hrc_org_rec;
begin
v_example_rec1.hrc_org_id:=1001;
v_example_rec1.hrc_descr:='CEO/COO';
v_example_rec1.org_short_name:='Office of CEO/COO ABC Inc.';
v_example_rec2:=v_example_rec1;
if(v_example_rec1.hrc_org_id=v_example_rec2.hrc_org_id and v_example_rec1.hrc_descr=v_example_rec2.hrc_descr and v_example_rec1.org_short_name = v_example_rec2.org_short_name) then
dbms_output.put_line('YES');
end if;
exception when others then
null;
end;
练习:修改之前的练习,尝试用记录实现接收取到的值
-------------------------------------------------
定义一个游标变量类型,声明游标,分别打开两个查询并输出
1.员工的姓名、薪资、雇佣日期、部门名
2.员工的编号、薪水、薪水等级,关联salgrade表
(3) 行变量的记录:行变量是一种特殊的记录,结构是基于表或者游标的。
declare
cursor csr_hrc is select * from hrc_tab order by 1;
hrc_rec csr_hrc%rowtype;
hrc_rec1 hrc_tab%rowtype;
type hrc_org_rec is record(hrc_code number,hrc_descr varchar2(20));
hrc_rec2 hrc_org_rec;
begin
open csr_hrc;
loop
fetch csr_hrc into hrc_rec;
exit when(csr_hrc%notfound);
dbms_output.put_line(to_char(hrc_rec.hrc_code)||' '||hrc_rec.hrc_descr);
end loop;
close csr_hrc;
dbms_output.put_line('-----------------------------------');
open csr_hrc;
loop
fetch csr_hrc into hrc_rec1;
exit when(csr_hrc%notfound);
dbms_output.put_line(to_char(hrc_rec1.hrc_code)||' '||hrc_rec1.hrc_descr);
end loop;
close csr_hrc;
dbms_output.put_line('-----------------------------------');
open csr_hrc;
loop
fetch csr_hrc into hrc_rec2;
exit when(csr_hrc%notfound);
dbms_output.put_line(to_char(hrc_rec2.hrc_code)||' '||hrc_rec2.hrc_descr);
end loop;
close csr_hrc;
dbms_output.put_line('-----------------------------------');
open csr_hrc;
loop
fetch csr_hrc into hrc_rec; --fetch值给行变量
exit when(csr_hrc%notfound);
hrc_rec2:=hrc_rec; --将行变量赋值给记录类型的变量,能够赋值成功
dbms_output.put_line(to_char(hrc_rec2.hrc_code)||' '||hrc_rec2.hrc_descr);
end loop;
close csr_hrc;
exception when others then
null;
end;
(4)涉及到DML操作的记录
A insert操作
declare
type hrc_org_rec is record(hrc_code number,hrc_descr varchar2(30));
v_example_rec hrc_org_rec;
begin
v_example_rec.hrc_code:=6;
v_example_rec.hrc_descr:='Wev analyze l';
insert into hrc_tab values v_example_rec; --使用记录的方式插入一行数据
commit;
exception when others then
null;
end;
验证:
select * from hrc_tab;
B update操作
declare
type hrc_org_rec is record(hrc_code number,hrc_descr varchar2(30));
v_example_rec hrc_org_rec;
begin
v_example_rec.hrc_code:=6;
v_example_rec.hrc_descr:='Wev analyze 2';
update hrc_tab set row=v_example_rec where hrc_code=v_example_rec.hrc_code; --使用记录的方式更新一行数据
commit; --注意row关键字
exception when others then
null;
end;
验证:
select * from hrc_tab;
C delete操作
declare
type hrc_org_rec is record(hrc_code number,hrc_descr varchar2(30));
v_example_rec hrc_org_rec;
begin
v_example_rec.hrc_code:=6;
delete from hrc_tab where hrc_code=v_example_rec.hrc_code; --使用记录的方式删除一行记录
commit;
exception when others then
null;
end;
验证:
select * from hrc_tab;
注意:不能用整行作为过滤条件
declare
type hrc_org_rec is record(hrc_code number,hrc_descr varchar2(30));
v_example_rec hrc_org_rec;
begin
v_example_rec.hrc_code:=6;
v_example_rec.hrc_descr:='Web anayled 1';
delete from hrc_tab where row=v_example_rec; --不能使用这种方式删除
commit;
exception when others then
null;
end;