Oracle 复杂数据类型

目录

 Oracle 复杂数据类型

1. 对象类型

1.1 对象类型头

1.2 对象类型体

2. 嵌套表类型

2.1 例子

3. 可变数组类型

3.1 例子

4. 索引类型(关联数组)

4.1 例子

5. 记录类型

5.1  例子

6. 集合属性和方法

6.1 集合的方法

6.2 集合特征

6.3 集合类型的嵌套(联合)


 Oracle 复杂数据类型

用户自定义数据类型(User-defined Data Type)
oracle支持对象类型(Object Type)、嵌套类型(Nested Table Type)和可变数组类型(Varray Data Type)三种用户自定义数据类型。

集合数据类型:

类似于编程语言中数组也就是。pl/sql集合类型包括关联数组Associative array(索引表 pl/sql table)、嵌套表(Nested Table)、变长数组(VARRAY)。

1. 对象类型

create or replace type type_name as object (
v_name1 datatype[,v_name2 datatype,...],
[member|static method1 spec,
 member|static method2 spec,...]);

create or replace type body type_name as
member|static method1 body;
member|static method1 body;...

1.1 对象类型头

用于定义对象的公用属性和方法;
属性:最少要包含一个属性,最多包含1000个属性。定义时必须提供属性名和数据类型,但不能指定默认值和not null。并且不能包括long、long raw、rowid、urowid和PL/SQL特有类型(boolean\%type\%rowtype\ref curdor等);
可以包含也可以不包含方法,可以定义构造方法、member方法、static方法、map方法和order方法。

1.2 对象类型体

用于实现对象类型头所定义的公用方法。(如果对象类型头中没有方法,那么就不需要对象类型体);定义对象类型可以包含也可以不包含方法,可以定义构造方法、member方法、static方法、map方法和order方法。
1)、构造方法
用于初始化对象并返回对象实例。构造方法是与对象类型同名的函数,默认的构造方法参数是对象类型的所有属性。9i前只能使用系统默认的构造方法、9i后可自定义构造函数,自定义必须使用constructor function关键字
2)、member方法
用于访问对象实例的数据。当使用member方法时,可以使用内置参数self访问当前对象实例。
当定义member方法时,无论是否定义self参数,它都会被作为第一个参数传递给member方法。
但如果要定义参数self,那么其类型必须要使用当前对象类型。member方法只能由对象实例调用,而不能由对象类型调用。
3)、static方法
用于访问对象类型,可以在对象类型上执行全局操作,而不需要访问特定对象实例的数据,因此static方法引用self参数。static方法只能由对象类型调用,不能由对象实例调用(和member相反)。
4)、map方法
对象类型不同于标量类型可以直接比较,为了按照特定规则排序对象实例的数据,可以定义map方法,但只能有一个,与order互斥。map方法将对象实例映射成标量数值来比较。
5)、order方法
map可以在对多个对象实例之间排序,而order只能比较2个实例的大小。定义对象类型时最多只能定义一个order方法,而且map和order方法不能同时定义。使用原则是可不用则均不用,比较2个对象则用ordder,对个对象则用map。

2. 嵌套表类型

TYPE type_name IS TABLE OF element_type;  

a. 下标从1开始,元素个数没有限制(*使用时必须先初始化,用extend属性可以扩展元素个数)  
b.  可作为表定义数据类型,但是前提是要先create 创造嵌套表类型,这就可以实现1对多了定义 c.  和索引表的区别也就是看看有无index by语句,嵌套表的索引固定是int型的 . 

type / create type 区别:

用 create 后面用 as , 若直接用 type 后面用is

create 是创 object , 而 type 是创record .

另 type用在语句块中,而create 是的独立的.

2.1 例子

SET SERVEROUTPUT ON SIZE 99999;
DECLARE 
   TYPE names_table IS TABLE OF VARCHAR2(10); 
   TYPE grades IS TABLE OF INTEGER;  
   names names_table; 
   marks grades; 
   total integer; 
BEGIN 
   names := names_table('Kavita', 'Pritam', 'Ayan', 'Rishav', 'Aziz'); 
   marks:= grades(98, 97, 78, 87, 92); 
   total := names.count; 
   dbms_output.put_line('Total '|| total || ' Students'); 
   FOR i IN 1 .. total LOOP 
      dbms_output.put_line('Student:'||names(i)||', Marks:' || marks(i)); 
   end loop; 
END; 
/

3. 可变数组类型

TYPE type_name IS VARRAY(size_limit) OF element_type[NOT NULL];  

 a. 这个就和java中的数组差不多了,下标from 1 ,定义时先指定最大元素个数,也和varchar2(size)这种一样。  
 b. 使用时也必须先用构造方法初始化 ,可以作为表列类型  

3.1 例子

declare  
  type varr is VARRAY(10) of int;  
  v_varr varr :=varr();  
begin  
  for i in 1..5 loop  
      v_varr.extend;  
      v_varr(i) :=i*i;  
  end loop;  
  
  for i in 1..5 loop  
      dbms_output.put_line(v_varr(i));  
  end loop;  
end;  
/  

4. 索引类型(关联数组)

TYPE type_name IS TABLE OF element_type [NOT NULL] INDEX BY key_type;  
              
type_name:用户自定义数据类型的名字  
element_type:索引表中元素类型  
key_type:索引表元素下标的数据类型(BINARY_INTEGERPLS_INTEGER,VARCHAR2)  

a. 下标无限制,可以为负数  
b. 元素个数无限制  

4.1 例子

declare  
  type index_tab_type is table of varchar2(30) index by BINARY_INTEGER;  
  v_table index_tab_type;  
begin  
  v_table(-1) :='hello';--设定下标为-1的元素的值  
  v_table(1)  :=',';  
  dbms_output.put_line(v_table(-1)||'-'||v_table(1));  
  dbms_output.put_line('元素个数:'||v_table.count);  
  v_table(5) :='world';  
  dbms_output.put_line('元素个数:'||v_table.count);  
  dbms_output.put_line('第一个元素'||v_table.first);  
  dbms_output.put_line('最后一个元素'||v_table.last);  
end;  
/  
运行结果:
hello-,  
元素个数:2  
元素个数:3  
第一个元素-1  
最后一个元素5  
  
PL/SQL 过程已成功完成。  

5. 记录类型

TYPE RECORD_NAME IS RECORD(
  V1  DATA_TYPE1 [NOT NULL][:=DEFAULT_VALUE],
  V2  DATA_TYPE2 [NOT NULL][:=DEFAULT_VALUE],
  VN  DATA_TYPEN [NOT NULL][:=DEFAULT_VALUE]
);

5.1  例子

SET SERVEROUTPUT ON SIZE 99999;
DECLARE 
   type books is record 
      (title varchar(50), 
      author varchar(50), 
      subject varchar(100), 
      book_id number); 
   book1 books; 
   book2 books; 
BEGIN 
   -- Book 1 specification 
   book1.title  := 'C Programming'; 
   book1.author := 'TanHao';  
   book1.subject := 'C Programming Tutorial'; 
   book1.book_id := 1920122;  
   -- Book 2 specification 
   book2.title := 'Telecom Billing'; 
   book2.author := 'LiDawei'; 
   book2.subject := 'Telecom Billing Tutorial'; 
   book2.book_id := 2032942;  

  -- Print book 1 record 
   dbms_output.put_line('Book 1 title : '|| book1.title); 
   dbms_output.put_line('Book 1 author : '|| book1.author); 
   dbms_output.put_line('Book 1 subject : '|| book1.subject); 
   dbms_output.put_line('Book 1 book_id : ' || book1.book_id); 

   -- Print book 2 record 
   dbms_output.put_line('Book 2 title : '|| book2.title); 
   dbms_output.put_line('Book 2 author : '|| book2.author); 
   dbms_output.put_line('Book 2 subject : '|| book2.subject); 
   dbms_output.put_line('Book 2 book_id : '|| book2.book_id); 
END; 
/

6. 集合属性和方法

    集合属性是数据库提供给用户的操作集合的方法(函数和过程),
过程包括:extend,trim,delete
函数包括:exists,count,limit,first,last,prior,next。
集合方法只能在pl/sql语句中使用,不能在sql语句中使用。

6.1 集合的方法

       exists(index) 索引处的元素是否存在  
       count 当前集合中的元素总个数  
       limit 集合元素索引的最大值  
          索引表和嵌套表是不限个数的,所以返回null,变长数组返回定义时的最大索引  
       first  返回集合第一个元素索引  
       last  返回集合最后一个元素索引  
       prior 当前元素的前一个  
       next 当前元素的后一个  
       extend 扩展集合的容量,增加元素 只是用于嵌套表和varry类型  
           x.extend 增加一个null元素  
           x.extend(n) 增加n个null元素  
           x.extend(n,i) 增加n个元素,元素值与第i个元素相同  
       trim 从集合的尾部删除元素 只用于嵌套表和varry类型
       trim 从集合尾部删除一个元素  
       trim(n) 从集合尾部删除n个元素  
       delete 按索引删除集合元素   只适用于嵌套表,delete(n)\delete(m,n)不适用于varray
           delete 删除所有  
           delete(index) 删除第index个  
           delete(a,b) 删除a--b之间的所有元素 

处理单行单列数据,可以使用标量变量(varchar2、number、date、boolean);
处理单行多列的数据,可以使用pl/sql记录(%rowtype,record);
处理单列多行数据,可以使用pl/sql集合(table、varray);
那么处理多列多行数据,可以集合类型的嵌套;

6.2 集合特征

6.3 集合类型的嵌套(联合)

1.table和%rowtype的联合
declare
type type_tab_ename is table of emp%rowtype;
v_arr type_tab_ename:=type_tab_ename();
v_cnt number:=1;
begin
for rs in (select * from emp) loop
v_arr.extend;
v_arr(v_cnt):=rs;
dbms_output.put_line('雇员名:'||v_arr(v_cnt).ename);
v_cnt:=v_cnt+1;
end loop;
end;

2.二维数组 varray和varray的嵌套
declare
type d1_varray_type is varray(10) of number;--定义一维VARRAY
type nd1_varray_type is varray(5) of d1_varray_type;--定义二维VARRAY集合
--初始化二维集合变量
v_arr nd1_varray_type:=nd1_varray_type(
d1_varray_type(2,4),
d1_varray_type(5,73));
begin
dbms_output.put_line('显示二维数组所有元素');
for i in 1..v_arr.count loop
for j in 1..v_arr(i).count loop
dbms_output.put_line('v_arr('||i||','||j||')='||v_arr(i)(j));
end loop;
end loop;
end;

(2,4)
(5,73)

如果多维集合的元素个数没有限制,那么可以在嵌套表类型中嵌套另一个嵌套表类型
3.二维嵌套表 table和table的嵌套
declare
type d1_table_type is table of number;--定义一维嵌套表
type nd1_table_type is table of d1_table_type;--定义二维嵌套表集合
--初始化二维集合变量
v_tab nd1_table_type:=nd1_table_type(
d1_table_type(58,100,102),
d1_table_type(55,6),
d1_table_type(2));
begin
dbms_output.put_line('显示二维数组所有元素');
for i in 1..v_tab.count loop
for j in 1..v_tab(i).count loop
dbms_output.put_line('v_tab('||i||','||j||')='||v_tab(i)(j));
end loop;
end loop;
end;

  • 13
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值