您的位置:首页 > 数据库 > Oracle

Oracle系列之一——复合数据类型

2014-04-01 13:36 393 查看
[b]Oracle复合数据类型 [/b]

当使用标量变量处理oracle数据时,每个标量只能存放单个值,如果要处理多个类型的数据,则要声明多个标量变量;为了解决这种问题,可以使用复合数据类型。复合数据类型包括记录——用于处理单行多列数据,集合——用于处理多行单列数据,记录表——用于处理多行多列数据。

[b]一.记录: [/b]

pl/sql记录用于处于单行多列数据.类似于高级语言中的结构,可以自定义记录,也可以通过%rowtype属性定义记录变量. 明显的,自定义更加灵活,因为它可以跨越多个表,可以任意取字段,而rowtype属性则不能,它只能是固定表/视图的字段。虽然自定义表的代码多点,但是在只需要某几列时,还是得自定义记录,因为它能节省内存空间,多写点代码是非常值得的。

set serveroutput on;

declare

--自定义方式

type dept_record_type is record(

name emp.ename%type,

dname dept.dname%type,

sal emp.sal%type);

dept_record dept_record_type;

begin

select ename, dname, sal

--into dept_record.name, dept_record.dname, dept_record.sal

--只要是类型合适,便会按顺序插入,而不用保证select的字段和记录的字段同样的名称。

into dept_record

from emp

join dept

on emp.deptno = dept.deptno

where emp.empno = &no;

dbms_output.put_line(dept_record.name);

dbms_output.put_line(dept_record.sal);

exception

when no_data_found then

dbms_output.put_line('没有此员工');

end;

在select ,insert,update,delete语句中均可使用记录

如:

如果插件的数据与表字段的顺序、个数、类型完全相同,则可以直接使用。

如果只是使用记录中的某几个字段,则需要使用记录成员,如dept_record.dname;

Declare

--%rowtype属性方式

dept_record dept%rowtype;

begin

dept_record.deptno := 60;

dept_record.dname := 'anaylize';

dept_record.loc := 'beijing';

insert into dept values dept_record;

end;

在update中使用记录:

declare

dept_record dept%rowtype;

begin

dept_record.deptno := 60;

dept_record.dname := 'anaylize';

dept_record.loc := 'shanghai';

update dept set row=dept_record where deptno=60;

end;

当然,直接使用记录成员也可以。

上面稍微一改:

declare

dept_record dept%rowtype;

begin

dept_record.deptno := 60;

dept_record.dname := 'anaylize';

dept_record.loc := 'jinan';

update dept set loc=dept_record.loc where deptno=60;

end;

当在delete语句中使用记录时,只能是在where子句中使用记录成员。

如:

declare

dept_record dept%rowtype;

begin

dept_record.deptno := 60;

delete from dept where deptno=dept_record.deptno;

end;

[b]二.Pl/sql集合 [/b]

Pl/sql集合可以用来处理多行单列数据,如多个雇员的姓名。它类似于高级语言(如java)的数组,可以存储多个类型一样的数据。

Pl/sql集合包括索引表(pl/sql表),嵌套表(Nested table),变长数组(VARRAY)三种类型,应该根据不同的需求正确的选择它们。

[b]索引表 [/b]
索引表的元素个数没有限制,且下标可以为负值。

定义索引表的结构如下:

TYPE type_name is table of element_type

Index by key_value;

Identifier type_name;

Is table …index是定义索引表的固定格式。Type_name是用户自定义数据类型的名称,element_type是存储元素的数据类型,key_Value是下标的类型(可以是Binary_integer,pls_integer,varchar2)。

如下:

set serveroutput on;

declare

type emp_table_type is table of emp.ename%type index by binary_integer;

emp_table emp_table_type;

cursor emp_cursor is

select ename from emp;

i binary_integer:=1;

begin

open emp_cursor;

loop

fetch emp_cursor into emp_table(i);

i:=i+1;

exit when emp_cursor%notfound;

end loop;

close emp_cursor;

for i in 1 .. emp_table.count loop

dbms_output.put_line(emp_table(i));

end loop;

end;

嵌套表
嵌套表的下标是从1开始的,元素个数可以无限,但最重要的特点还是嵌套表的元素值是可以稀疏的。



定义嵌套表的格式如下:

Type type_name is table of element_name;

Identifier type_name;

在pl/sql块中使用嵌套表变量时,必须首先使用构造函数方法初始化嵌套表变量,然后才能在pl/sql块内引用嵌套表元素,如下:

declare

type ename_table_type is table of emp.ename%type;

ename_table ename_table_type;

begin

--初始化几个数据,下标到几

ename_table := ename_table_type('a', 'a', 'a');

select ename into ename_table(2) from emp where emp.empno = 7788;

dbms_output.put_line(ename_table(2));

dbms_output.put_line(ename_table(1));

--下面这句会报错:下标超出数据,因为在前面只初始化了3个元素,所有下标只能到3.

--dbms_output.put_line(ename_table(4));

end;

嵌套表可以在表列中使用。当表中一个字段中的值的个数不确定的时候,非常有用。如person表的phone字段,可以是家庭电话、个人手机、办公电话。

对于这个特性,在这里不做详解,有兴趣的同学可以去查看官方文档或去google百度一下。

3变长数组

该数据类型与高级语言的数组非常相似,下标从1开始,而且无数个数有限制,即可以处理pl/sql数组,也可以当作表列。

定义如下:

Type type_name is varray(size) of element_type;

Identifier type_name;

同Nested Table一样,在使用前一定要先用构造函数初始化。

declare

type ename_varray_type is varray(20) of emp.ename%type;

ename_varray ename_varray_type := ename_varray_type(' ');

begin

select ename into ename_varray(1) from emp where emp.empno = &no;

dbms_output.put_line('姓名:' || ename_varray(1));

--dbms_output.put_line('姓名:' || ename_varray(2));

end;

[b]三.Pl/sql记录表 [/b]

记录表可以用来处理多行多列数据,它结合了pl/sql记录和pl/sql集合的优点,从而可以有效的处理多行多列数据。

declare

type emp_table_type is table of emp%rowtype index by binary_integer;

emp_table emp_table_type;

begin

select * into emp_table(1) from emp where emp.empno = &no;

dbms_output.put_line(emp_table(1).ename);

end;

declare

type emp_table_type is table of emp%rowtype index by binary_integer;

emp_table emp_table_type;

begin

select * bulk collect into emp_table from emp;

for i in 1..emp_table.count loop

dbms_output.put_line(emp_table(i).ename);

end loop;

end;

declare

type emp_record_type is record

(

name emp.ename%type,

sal emp.sal%type

);

type emp_table_type is table of emp_record_type index by binary_integer;

emp_table emp_table_type;

begin

select ename,sal bulk collect into emp_table from emp;

for i in 1..emp_table.count loop

dbms_output.put_line(emp_table(i).name||' '||emp_table(i).sal);

--dbms_output.put_line(emp_table(i).sal);

end loop;

end;

赋予用户调试权限:grant debug connect session to user
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: