首页 > 数据库 >Oracle数据库PL/SQL学习笔记三——复合数据的定义

Oracle数据库PL/SQL学习笔记三——复合数据的定义

时间:2022-12-07 21:38:43浏览次数:44  
标签:end name -- list 游标 loop SQL Oracle PL


--自定义记录record
declare
type demo_record_type is record(
id number default 1,
value varchar2(10) := 'one'
);
demo demo_record_type;
begin
dbms_output.put_line('['||demo.id||']['||demo.value||']');
end;




--自定义数组(varray)
declare
type number_varray is varray(10) of number; --类型number_varray是包含10个数字的number类型的varray数组
list number_varray := number_varray(1,2,3,4,5,6,7,8,null,null); --变量list的类型是number_varray,并初始化
begin
for i in 1..list.limit loop --limit返回最大尺寸
dbms_output.put('['||list(i)||']');
end loop;
dbms_output.new_line;
end;




--嵌套表数据类型(索引列表或java类),list集合, 特点:有序,密集填充 ,大小不固定
declare
type number_table is table of number; --类型是table,包含的是number,不用声明长度
list number_table := number_table(1,90,3,4,5,6,7,8);
begin
list.delete(2); --删除第二个元素,但不删除已分配的空间
dbms_output.put_line(list.count);
dbms_output.put_line(list.limit); --table没有limit属性,只有varray数组才有limit属性
for i in 1..list.count loop
if list.exists(i) then
dbms_output.put('['||list(i)||']');
end if;
end loop;
dbms_output.new_line;
end;






--联合数组数据类型 (类似set集合) 特点:无序 稀疏,大小不固定
--和嵌套表定义非常相似,主要不同点:指定了如何进行索引 index by Pls_Integer 或者 index by varchar2(10)
declare
type number_table is table of number index by Pls_Integer;
list number_table;
begin
for i in 1..8 Loop
dbms_output.put_line('The index value is ['||i||']');
list(i):= i;
end loop;
dbms_output.put_line(list.count);
list.delete(2); --和varray和嵌套表中不同,删除元素时也会删除已分配的空间
dbms_output.put_line(list.count);
for i in 1..list.count loop --由于count变小,所有最后一个值8查不到
if list.exists(i) then
dbms_output.put('['||list(i)||']');
end if;
end loop;
dbms_output.new_line;
end;






--引用游标
--弱类型的引用游标没有返回类型,强类型的引用游标有返回类型
--主要作用: 实现在程序间传递结果集的功能,在同一过程中使用引用游标没有意义。
declare
type weakly_typed is ref cursor;
quick weakly_typed;
v_a1 varchar2(30);
v_b1 number(10);
begin
open quick for
select t.name,t.age from tb_user t;
/* loop
fetch quick into v_a1,v_b1;
dbms_output.put_line(v_a1||'今年'||v_b1||'岁');
exit when quick%notfound;
end loop;*/
end;






--动态显示游标(sql语句中带有局部变量)
--局部变量的名称必须与列名不同,变量在打开游标的时候才被替换
--显示游标的典型用法***********
declare
p_id number :=34;
type item_record is record
(
id number,
name varchar2(30)
);

item item_record;
cursor c is select t.userid,t.name from tb_user t where t.userid = p_id;
begin
p_id:=45; --在游标打开之前,仍可改变形参
open c; --打开游标
loop --开始循环
fetch c into item; --从游标中抓取值
exit when c%notfound;
dbms_output.put_line('Name is ['||item.name||']');
end loop; --结束循环
close c; --关闭游标
End;



--通过游标索引指派记录结构
declare
type item_record is record(
id number,
name varchar2(30)
);
ex_item item_record;
cursor c is
select t.userid,t.name from tb_user t;
begin
for i in c loop
ex_item := i; --给record赋值
dbms_output.put_line('name['||ex_item.name||']');
end loop;
end;


--单行隐式游标(使用record接受查询值只能接受单行记录,多了就报错)
declare
type item_record is record
(
id tb_user.userid%type,
name tb_user.name%type,
age tb_user.age%type
);
dataset item_record;
begin
select t.userid,t.name,t.age into dataset
from tb_user t
where rownum<2;
dbms_output.put_line(dataset.name);
end;


--多行隐式游标(在pl/sql块中编写DML语句或者直接在游标for循环中编写嵌入式而不是在声明块中定义)
--方式一:sql嵌入式for循环 在这种隐式游标中SQL%ROWCOUNT特性返回null
begin
for i in (select * from tb_user t) loop
if i.name = 'JONES' then
exit;
end if;
dbms_output.put_line('The name is ['||i.name||']');
dbms_output.put_line('update1['||SQL%rowcount||']');
end loop;
dbms_output.put_line('update2['||SQL%rowcount||']');
dbms_output.put_line('循环结束');
end;


--方式二:pl/sql块中编写dml语句
begin
update tb_user t set t.name ='xiaolei'
where t.userid=90;
if SQL%found then --隐式游标的%found游标特性只有在行被更新是返回true
dbms_output.put_line('update['||SQL%rowcount||']'); --%rowcount表示影响的行数
else
dbms_output.put_line('nothing updated!');
end if;
end;



--带参数的游标使用
declare
v_id number;
type item_record is record
(
id number,
name varchar2(30)
);

item item_record;
cursor c(p_id number) is select t.userid,t.name from tb_user t where t.userid = p_id;
begin
v_id:=45;
open c(v_id); --在打开游标的时候传入游标的参数
loop
fetch c into item; --从游标中抓取值
exit when c%notfound;
dbms_output.put_line('Name is ['||item.name||']');
end loop; --结束循环
close c; --关闭游标
End;






--批游标 (bulk collect) 相当于java中的集合colletion
--主要是针对table类型

--好处:比标准游标更快,用于从表或视图中选择,插入,更新或删除大数据集
-- 收集: select 字段 collect bulk into 批游标
--fetch抓取 : fetch 字段 bulk collect into 批游标
--从list中获取第i个值 list(i) 注意:这里用的是小括号


--并行集合目标
declare
type name_collection is table of varchar2(30);
type age_collection is table of number;

v_name_list name_collection;
v_age_list age_collection;
begin
select t.name,t.age
bulk collect into v_name_list,v_age_list
from tb_user t ;
for i in 1..v_name_list.count loop
dbms_output.put_line('name is ['||v_name_list(i)||']');
end loop;
end;


--记录集合目标
declare
type user_record is record( --定义record
name varchar2(30),
age number
);
type collection is table of user_record; --定义集合
full_name collection;
begin
select name,age bulk collect into full_name from tb_user;
for i in 1..full_name.count loop
dbms_output.put_line('name is ['||full_name(i).name||']');
end loop;
end;




--limit约束的集合目标
--用于设置批收集返回的最大行数

--例:如何每次10行管理批集合
declare
type name_collection is table of varchar2(30);
type age_collecction is table of number;
namelist name_collection;
agelist age_collecction;
cursor c is
select name,age
from tb_user;
begin
open c;
fetch c bulk collect into namelist,agelist limit 10; --limit 10限制一次只从游标中取10个值
for i in 1..namelist.count loop
exit when namelist.count = 0;
dbms_output.put_line('name is ['||namelist(i)||']');
end loop;
close c;
end;


declare
type name_record is record(
name varchar2(30),
age number
);
type collection is table of name_record;
full_name collection;
cursor c is select name,age from tb_user;
begin
open c;
loop
fetch c bulk collect into full_name limit 10; --每次循环从游标中抓取10条记录
exit when full_name.count = 0;
for i in 1..full_name.count loop
dbms_output.put_line('name is ['||full_name(i).name||']');
end loop;
end loop;
end;




--forall语句
--在进行批量insert,update,delete时,forall的效率高于for loop的效率
declare
type id_collection is table of number;
type name_collection is table of varchar2(30);
idlist id_collection;
namelist name_collection;
cursor c is
select userid,name from tb_user;
begin
open c;
loop
fetch c bulk collect into idlist,namelist limit 10;
exit when namelist.count =0;
forall i in idlist.first..idlist.last
update tb_user set name = Substrb(namelist(i), 0, Length(namelist(i))-1)
where userid = idlist(i);
end loop;
end;





--错误管理(编译错误和运行时错误)
when 错误类型 then
异常处理;

return | exit;


--使用when others then可以捕获任何异常
--内置函数: SQLCODE 返回Oracle预定义的异常的负数
-- SQLERRM 返回引发异常的错误代码和消息


declare
a int:=0;
ex_1 exception; --定义异常
begin
if a=0 then
raise ex_1; --抛出异常
end if;
exception
when others then --捕获所有异常
dbms_output.put_line('exception is' + SQLERRM);
end;

 

标签:end,name,--,list,游标,loop,SQL,Oracle,PL
From: https://blog.51cto.com/u_15905482/5920096

相关文章

  • Oracle数据库PL/SQL学习笔记二——基础控制语句
    <spanstyle="font-size:18px;font-family:Arial,Helvetica,sans-serif;">--简单的if判断</span><spanstyle="font-size:18px;">beginif&var>10and&var<=50......
  • Oracle数据库PL/SQL学习笔记——函数定义
    小技巧:如果在sqlwindow窗口下创建函数,但是创建的函数一直是无效函数(有个小红叉),那么可以再新建-》programwindow-》function 窗口中重写创建函数,这里面有相信的错误信......
  • Oracle数据库学习笔记四——存储过程的值传递和引用传递
    编程语言中的4种子例程:由两种行为定义,即形式值是否返回以及参数列表是值传递还是引用传递。如果返回输出,子例程就是函数,如果不返回,就是过程。所以4中子例程为:1.值传递函......
  • SQL注入的本质
    注入测试的本质:把用户输入的数据当做代码执行。两个关键条件:用户能够控制输入原本程序要执行的代码,拼接用户输入数据被执行手工测试但很多时候,Web服务器关闭了错误回显,这......
  • 解析mysql存储结构---innodb_ruby工具
    innodb_ruby用途:主要可查看innodb数据库数据表的各种存储,解析innodb的文件,用于学习数据库底层的一些存储。在debian系统安装innodb_ruby1、sudoaptinstallruby-dev2、su......
  • ezsql2
    最基本的联合查询payload:-1'unionselect1,group_concat(schema_name),3frominformation_schema.schematalimit0,1--+selectgroup_concat(schema_name)from......
  • sql注入葵花宝典
    sql注入葵花宝典重要的是找到注入点四种常见的数据库注入过程大同小异先探测出数据类型很重要注入类型union注入带错误条件注入时间延迟注入报错注入外带交互的......
  • mysql explain
    explain这个命令来查看SQL语句的执行计划,查看该SQL语句有没有使用上了索引,有没有做全表扫描等执行explain后,显示的信息有如下几列id:表示查询中执行select子句或操......
  • 初探spring事件applicationEvent
    前言不知道各位小伙伴对事件(event)这个比较抽象的名词如何理解,从我实际开发和使用经验来说,事件通常指的是某一特定条件下触发的一组操作。做过生态开发(ISV)的小伙伴一定对......
  • [BUUCTF][Web][SUCTF 2019]EasySQL 1
    这一题有点蛋疼,比较难顶看了别人的writeup也很难get到解题思路,感觉必须要拿到源码进行审计才能解大佬们猜后端是这么写的select$_POST['query']||flagfromFlag;......