/**
1.1 pl/sql(数据库编程):是对表中的sql语句的扩展,扩展了过程化的控制
1.2
变量:
数据类型:varchar2(len),nvarchar2(len),char(len),date,boolean,number(p,s)
运算符:|| and or not != <>
逻辑控制:
循环结构:
1.3.pl/sql块:下面相当于一个方法,没有名字,因此叫匿名块。declare(声明)
declare
定义变量,v是变量的意思
begin
写sql或者pl/sql语句
exception
异常处理
end;
**/
------------------------------------------
declare
-- v_name varchar(20):='乌龟';--声明变量,同时赋值(第一种赋值)
v_name varchar(20);
begin
v_name:='乌龟';---赋值(第二种赋值)
select sname into v_name from student where sno='112';--into的意思是把学生表的sname赋值给v_name(第三中赋值)
dbms_output.put_line(v_name);---打印变量的值,相当于system.out.println()
end;
--------------------------------
---逻辑控制。if else,输出大年龄
declare
v_age number(5):=22;
v_age2 number(5):=10000;
begin ----- if then endif相当于if语句。v_age>v_age2是判断条件,dbms_output.put_line('v_age:' ||v_age)是输出的结果
if v_age>v_age2 then
dbms_output.put_line('v_age:' ||v_age);
else
dbms_output.put_line('v_age2:' ||v_age2);
end if;
end;
-------------------------------------
---逻辑控制。多重if
declare
v_age number(5):=22;
v_age2 number(5):=10000;
begin
if v_age>v_age2 then
dbms_output.put_line('v_age=' ||v_age);
elsif v_age=v_age2 then---elsif在java中相当于else if
dbms_output.put_line('v_age2=' ||v_age2 ||'v_age:' ||v_age);
else
dbms_output.put_line('v_age2=' ||v_age2 );---数据管理系统
end if;
end;
-------------------
---逻辑控制。case等值判断。(在java中就是switch,等值判断)
declare
v_grade number(1):=8;
begin
case
when v_grade=1 then dbms_output.put_line('☆');
when v_grade=2 then dbms_output.put_line('☆☆');
when v_grade=3 then dbms_output.put_line('☆☆☆');
when v_grade=4 then dbms_output.put_line('☆☆☆☆');
else dbms_output.put_line('☆☆☆☆11111111');
end case;
end;
-----------
--逻辑控制。case区间判断
declare
v_grade number(3):=89;
begin
case
when v_grade>=90 then dbms_output.put_line('A');
when v_grade>=80 then dbms_output.put_line('B');
when v_grade>=60 then dbms_output.put_line('c');
when v_grade<60then dbms_output.put_line('d');
end case;
end;
--------------------
---逻辑控制。case用在select中。好像跟sign()很相似
select sname,
case
when sage>40 then '中上'
when sage>30 then '中上'
when sage>20 then '中上'
when sage<20 then '中上'
end case
from student
---==================================================================
------第二部分:循环控制
-----循环结构 loop
declare
v_x number(6):=1;
begin
loop ---循环的意思,loop是个死循环
dbms_output.put_line(v_x);
if v_x =100 then
exit;---强制退出循环
end if ;
v_x:=v_x+1;---结果缓冲区溢出,因为超过10000个字节了。因为这是个死循环
end loop;
end;
-------------------
---循环结构 for 。。in后面是个集合
declare
v_x number(6):=1;
begin
for v_x in 1..100 loop ---loop就相当于左大括号,end loop就相当于右边大括号
dbms_output.put_line(v_x);
end loop;
end;
---------------------
-- 循环结构 while
declare
v_x number(6):=1;
begin
while v_x<=120 loop
dbms_output.put_line(v_x);
v_x:=v_x+1;
end loop;
end;
------------------------
------第三部分:oracle 复合数据类型(其实就是java中的引用类型)
---1.record记录类型
--record:就相当于创建类(更确切的说应该是创建表,因为格式更像是创建表,
--因为他里面的内容都放在了一对括号里了,每个字段后面用逗号,而不是分号,最后一个字段不用逗号)
declare
---- 1.定义一个复合类型v_r (type是定义类型,相当于定义类,名字v_r)。完成的就是对类的定义和给类中属性赋值
type v_r is record
(
v_x varchar(20),---这三行相当于是给类加上属性,更确切的说就是成员对象(或者说是在建表)
v_y varchar(20),
v_z varchar(20)
);----这个表是个整体,因此结束的时候要分号
---2.定义复合类型的变量(相当于java创建对象)
v_n v_r;
begin
--这个sql块想要说明的就是v_n.v_x(对象.属性)的使用
-- v_n.v_x:='安娜';---相当于在java中的利用对象调用属性
--v_n.v_z:='令狐冲';
-- v_n.v_y:=23;
select sname,saddress,sage into v_n.v_x,v_n.v_y,v_n.v_z from student where sno='112';---这个sql块想要说明的就是v_n.v_x(对象.属性)的使用
dbms_output.put_line(v_n.v_x);
dbms_output.put_line(v_n.v_y);
dbms_output.put_line(v_n.v_z);
end;
----用处:定义一个record变量存放第二条记录, 并输出结果
--------------------------------------------------------
----2.table类型(相当于数组) :总结一下:自己指定数组名字,数组类型,索引类型,索引名字,不用给数组指定大小,因为他自己会增加 。完成的就是对数组的定义和赋值
declare
---1.声明table类型,of varchar2(23)是数组中元素的类型,index by 是索引的类型。v_t是数组类型.索引不用指定大小,会一直增加。索引的类型自己指定,
---(索引类型改成number不行(改成其他的不受限制)。因为number可以出现小数位)
type v_t is table of varchar2(23) index by varchar2(3);
---2.定义v_t类型的变量,现在v_a就是数组变量
v_a v_t;
begin
select sname,saddress into v_a('1'),v_a('2') from student where sno='112';----这里的1,2代表索引(类型是varchar2(3))。这索引也是自己定义的。但是要注意在select后面的列的类型,要跟数组的类型一致
dbms_output.put_line(v_a('x'));
end;
----用处:定义一个table 类型变量存放3条记录, 并输出结果
---====================================================
---第四部分:扩展变量类型
----题:把表中某列的值赋值到一个变量里,但是我不知道这些列的数据类型
---1.%type 赋值某一列(一个字段)
declare
v_name student.sname%type;----student.sname%type是student表中的sname列的数据类型
v_age student.sage%type;
begin
select sname ,sage into v_name,v_age from student where sno='112';---into是把sname的值给v_name
dbms_output.put_line(v_name);
dbms_output.put_line(v_age);
end;
---2.%rowtype 赋值某一行(也就是所有列)
declare
v_x student%rowtype;----student.sname%type将sname变量的数据类型赋值
begin
select sname,sage into v_x.sname,v_x.sage from student where sno='112';
dbms_output.put_line(v_x.sname);
dbms_output.put_line(v_x.sage);
end;
------这两个的用处:用pl/sql实现输出7369号员工的姓名
--=================================================
-----第五部分:异常
---1.java中用异常类来描述(描述类名和异常的具体产生信息,异常编号)。
---oracle中描述异常:
---异常名字
--异常的具体描述信息
--异常编号
---2.oracle中异常的分类,按照异常名称分类
---预定义异常:名称,描述,编号都由oracle系统提供(相当于java的异常类)
---非预定义异常:指提供描述和编号(没有名字的异常)
---自定义异常:三无。名称,描述和编号都由程序员自己提供
--------------------------------------------------
-----预定义异常。异常1
declare
v_num number(3):=10;
v_num2 number(3):=0;
v_num3 number(3);
begin
v_num3 :=v_num/v_num2;
exception
when ZERO_DIVIDE then---除零异常
--dbms_output.put_line('这里有除数为0异常');--这里汉字就是描述
dbms_output.put_line(sqlcode||'----'||sqlerrm);--系统编号sqlcode和中文描述sqlerrm
when others then---所有异常,others相当于exception
dbms_output.put_line('这里有异常');
end;
---------------------------
--预定义异常 异常2
declare
v_name varchar2(20);
begin
---select sname into v_name from student where sno='112';--应该这样写,但是为了测试异常没有加where条件
select sname into v_name from student;
exception
when too_many_rows then-----实际返回的行数超出请求的行数,因为sname能查出好多,而v_name只能保存一个
dbms_output.put_line(sqlcode||'鄙视你'||sqlerrm);
end;
-----
--------第二种:非预定义异常
declare
---1.声明异常名字
v_bajie exception;----这跟定义变量一样,变量名字 变量类型
----2.给非预定义异常编号为2291的异常绑定一个名字,名字为v_bajie
--(因为名字都是程序员起的,因此在系统中根本不可能给他编号,,因此要程序员自己给绑定编号。程序员要用20000-20999之间的数)
pragma exception_init(v_bajie,-2291) ;
begin
insert into score values('129','200','3',2);---添加成绩的时候要考虑主外键关系,129和200都是外检,但是在主表中没有这个数据
exception
when v_bajie then
dbms_output.put_line(sqlcode||' 八戒异常 '||sqlerrm);
end;
-------
---第三种异常:自定义异常
declare
---假设描述仓库管理员,当数量小于5的时候产生异常
v_count number(3):=2; ---声明变量,表示库存数量
---1.声明名称
v_wkex exception ;
---2.将异常名称和异常编号进行绑定。其中,pragma是编译指令,在编译是时候被处理,不在运行的时候执行
pragma exception_init(v_wkex,-20001);
begin
---3.产生异常(引发异常,就是抛出)
if v_count<5 then
-- raise v_wkex ;--1.抛出。这种方式不能进行描述
raise_application_error(-20001,'异常描述,库存不足');---2.进行关联,把名称和描述关联。自己描述的
end if;
exception
---4.使用名称进行处理
when v_wkex then
dbms_output.put_line(sqlcode||' '||sqlerrm);---此时的编号是自己定义的编号-20001,描述也是自己的描述:异常描述,库存不足
end;