about me:oracle ace pro,optimistic,passionate and harmonious. focus on oracle,mysql and other database programming,peformance tuning,db design, j2ee,linux/aix,architecture tech,etc
全部博文(166)
分类: oracle
2020-07-08 16:13:03
集合分配
相同的集合类型相互赋值,则原来的那个元素的所有值全被替换成新的。
declare type t_name istableofvarchar2(10)indexbypls_integer; old_names t_name; new_names t_name;
begin old_names(1):= 'wang';--初始化 -- old_names(2) := 'ding';
new_names(111):= 'jack';--初始化 new_names(222):= 'json';
old_names := new_names;--将new_names赋值给old_names,则原来的值不存在了,只有111,222这个值
dbms_output.put_line(old_names.last); end;
|
从数据库的表中分配集合的值
1. 获得单行数据
通过select into获得单行数据进入到集合中。最好把集合的元素类型定义成表类型。
declare type student_copy istableof student%rowtype; cst student_copy:=student_copy();--初始化为空 begin cst.extend;--必须有此关键字,不然不可以增加,报下标超出数量错误 select* into cst(1)from student whererownum=1;--抓取第一行到集合中 dbms_output.put_line(cst(1).name);--相当于获得一个行,通过.column获得其属性值 end;
|
2. 获得多行数据
通过for循环一个游标获得多行插入,对于nested table和varray通过extend,对于index by表通过预定义首行index。
/** 获得多行数据 **/
declare type student_copy istableof student%rowtype; cst student_copy:=student_copy(); begin for via in(select* from student)loop--循环加入 cst.extend; cst(cst.last):=via;--cst.last返回最后一个索引 dbms_output.put_line(cst(cst.last).subject); endloop; end; |
/** 对index by表copy多行数据,不能通过extend和loop循环实现,因为extend对于index by非法,index by是稀疏性的,例子里面按顺序来 1.通过bulk collect into 2.如下 **/ declare res operate_collect.i_st; l_row binary_integer:=1; begin for via in(select* from student)loop res(l_row):=via; l_row:=l_row1; endloop; dbms_output.put_line('总共拷贝'||res.count||'行数据 '); for i in res.first..res.lastloop dbms_output.put_line('name is '||res(i).name||', subject is '||res(i).subject||', grade is '||res(i).grade); endloop; end; |
3. 批处理
oracle 9i realse2在plsql中对集合初始化支持bulk collect into批量处理,对nested table或varray不需要用构造器初始化,当然也支持index by表的操作。如:
/** 通过批处理bulk collect into,不需要初始化nested table或arrays,oracle 9i realse2支持 **/ declare type student_copy istableof student%rowtype; cst student_copy;--没有用构造器初始化 begin select* bulkcollectinto cst from student;--批量插入 for i in cst.first..cst.lastloop dbms_output.put_line(cst(i).subject); endloop; end; |
高级无序集合操作
为什么要对集合进行无序操作?在很多应用程序中,我们常常进行一次又一次的相同操作,如果在操作期间,这些查询的数据是很少发生改变的话,我们没有必要每次都进入数据库查询,发送sql—>解析sqlà执行sqlà返回结果。就算在oracle中,相同的sql会缓存到sga中,我们也需要访问sga,然后解析sql获得查询结果。如果查询的表很小或是一个静态表,则可以把该表缓存到一个包级的集合中,用函数获得查询结果。这样就可以在pga(进程全局区)而不是sga(系统全局区)来取数据,这样效率很高。如:
/**
无顺序的集合操作,提高查询效率
**/
--建立表
createtable hairstyles(
code number(10),
descriptionvarchar2(100)
);
--插入测试数据
begin
for i in 1 ..100000 loop
insertinto hairstyles values(i,'this is hair'||i);
endloop;
end;
commit;
--建立package
createorreplacepackage justonce is
functiondescription(code_in in hairstyles.code%type)--description函数返回查询结果
return hairstyles.description%type;
end justonce;
--建立package body
createorreplacepackagebody justonce
is
/*
声明一个集合类型,作为返回结果
*/
type desc_t istableof hairstyles.description%type
indexbybinary_integer;
descriptions desc_t;
/*
声明函数description传入code_in返回查询结果赋给声明的集合descriptions
*/
functiondescription(code_in in hairstyles.code%type)
return hairstyles.description%type
is
--作为返回结果
return_value hairstyles.description%type;
--声明子函数
function desc_from_database return hairstyles.description%type
is
--cursor根据外层函数的code查询结果
cursor desc_cur is
selectdescriptionfrom hairstyles where code = code_in;
--返回desc_rec,存放的是description
desc_rec desc_cur%rowtype;
begin
open desc_cur;
fetch desc_cur into desc_rec;
close desc_cur;
return desc_rec.description;
end;
begin
return descriptions (code_in);
exception
when no_data_found then
descriptions (code_in):= desc_from_database;
return descriptions (code_in);
end;
end justonce;
--测试结果
declare
res varchar2(100);
begin
res:=justonce.description(9999);
dbms_output.put_line(res);
end;在集合里访问数据要解决的问题
1. 如果集合还未被初始化,就查询行数据,则oracle抛出no_data_found异常。所以使用之前必须要填充数据到集合中。
2. 如果extend到varray中,已经超出最大范围limit,则会报越界。