java | (十九)oracle数据库(3)视图、PL/SQL、逻辑语句、%TYPE和%ROWTYPE、函数/存储过程、触发器

视图

关系视图
creatr or replace view view_name as select 表 or 其他视图

create or replace view view_emp_table_emp as
select * from emp;

只读视图

create view view_sales as
select sales.id,sales.goods,sales.selldate from sales with read only;

不能更改只读视图的数据

删除视图
drop view 视图名称

PL/SQL

PL/SQL是过程化SQL语言,是对SQL语句的拓展,增加了编程语言的特点,所以PL/SQL就是把数据库操作和查询语句组织在PL/SQL代码的过程性单元中,通过逻辑判断、循环等操作实现复杂的功能,在定义复杂业务的函数、过程及建立触发器时使用。
PL/SQL中通常只能使用数据DML(数据操纵)语言和DCL(数据控制)语言,诸如:insert、update、select into、delete、commit、rollback、savepoint。不允许使用DDL(数据定义)语言create、drop、alter…

PL/SQL基本结构

declare
       name string(43);
       age int:=12;--初始值
begin
     name:='风小田';
     age:=age + 1;
     dbms_output.put_line('名字:'||name);
end;

结果(在输出 显示):
在这里插入图片描述
异常处理

declare 
        n int:=21;
        m int;
        s int;
        err_zir exception;
        pragma exception_init(err_zir,-1476); 
begin
     m:=0;
     s:= n / m;
     dbms_output.put_line('结果是'||to_char(s));
     exception when err_zir then 
     dbms_output.put_line('0不能做除数!');
end; 

输出:
在这里插入图片描述

Oracle%TYPE和%ROWTYPE类型

emp表
在这里插入图片描述

declare 
        v_empName emp.name %type;
        v_emp emp%rowtype;
begin
     select e.name into v_empName from emp e where e.sid = 1;
     dbms_output.put_line(v_empName);
     select * into v_emp from emp e where e.sid = 1;
     dbms_output.put_line('工号'||v_emp.sid||',名字'||v_emp.name);
end;

结果:
在这里插入图片描述
(这个知识点是后面不上的,参照这个链接

逻辑判断

if-else语句/if-elsif语句

declare
       age int:=15;
       message string(64):='是成年人';
       message2 string(64):='是未成年人';
begin
     if age > 18 then
        dbms_output.put_line(message);
        else
            dbms_output.put_line(message2);
        end if;
end;

declare 
        score number:=34;
begin
     if(score <= 100 and score >=0) then
              if(score > 90) then
                       dbms_output.put_line('优秀');
              elsif(score >60 and score <= 90) then
                       dbms_output.put_line('良好');
              elsif(score <= 60 and score > 30) then
                       dbms_output.put_line('不及格');
              else
                       dbms_output.put_line('重修');
              end if;
      else
              dbms_output.put_line('成绩不在范围');
      end if;
end;
      

case-when语句

declare 
        score number:=34;
begin
     if(score <= 100 and score >=0) then
              if(score > 90) then
                       dbms_output.put_line('优秀');
              elsif(score >60 and score <= 90) then
                       dbms_output.put_line('良好');
              elsif(score <= 60 and score > 30) then
                       dbms_output.put_line('不及格');
              else
                       dbms_output.put_line('重修');
              end if;
      else
              dbms_output.put_line('成绩不在范围');
      end if;
      
      if(score <= 100 and score >=0) then
               case 
                    when score > 90 then
                         dbms_output.put_line('优秀');
                    when score > 60 then
                         dbms_output.put_line('良好');
                    when score > 30 then
                         dbms_output.put_line('不及格');
                    else
                         dbms_output.put_line('重修');
                    end case;
       else
              dbms_output.put_line('成绩不在范围');
       end if;
      
end;

loop

--loop 求100以内被3整除的数的个数    
declare 
        counts number:=0;
        num number:=1;
begin
     loop
         if(num > 100) then
                exit;--退出循环
         end if;
         if(num mod 3 = 0) then
                counts := counts+1; 
         end if;
         num := num+1;
     end loop;
     dbms_output.put_line(to_char(counts));
end; 

while

--while 求100内的数相加
declare 
        num number:=0;
        sumResult number:= 0;
begin
     while(num <= 100) loop
               sumResult := sumResult + num;
               num := num+1;
     end loop;
     dbms_output.put_line(to_char(sumResult));
end;

for循环

--for 循环计算100内偶数和
declare
       num int:=1;
       sums number:=0;
begin
     for i in 1..100 loop
         if(num mod 2 = 0)then
                sums:=sums+num; --统计偶数的累加和
         end if;
         num:=num+1;
     end loop;
     dbms_output.put_line(to_char(sums));
end;
--遍历表中的数据
declare
       pro_num int := 0;--工程部人数
       yanfa_num int := 0;--研发部人数
begin
     --pro_num := select count(emp_dep_mesView.所属部门) from emp_dep_mesView;
     for i in (select * from emp) loop
         if i.dep_id = 3 then pro_num := pro_num+1; end if;
         if i.dep_id = 4 then yanfa_num := yanfa_num+1; end if;
     end loop;  
     dbms_output.put_line('工程部人数'||pro_num);
     dbms_output.put_line('研发部人数'||yanfa_num);
end;
       

函数

oracle中函数必需有一个返回值,存储过程没有返回值
无参函数的构建

--oracle 自定义无参函数
create or replace function fun_sayhello
return string
is 
--函数中的定义写在此处(is和begin之间)
say string(64) := '你好';
begin 
      return 'hello';
end;

--在pl sql 中调用
begin
     dbms_output.put_line(fun_sayhello);
end;
--在sql语句中调用函数
select name || fun_sayhello from emp;

结果:
在plSql中调用结果:
在这里插入图片描述
在sql语句中调用结果
在这里插入图片描述
有参函数的构建
in 输入类型,直接的后调用时输入,此类型可以省略
out 输出类型不接收调用输入,此类型函数返回后必需使用变量接收
int out 输入输出型,可接收输入也可以输出,函数内对此类型赋值

in类型

create or replace function fun_doubleNum(num in number)
return number as
begin
     return num * 2;
end fun_doubleNum;

declare
       n number := 2.3;
begin 
      dbms_output.put_line(fun_doubleNum(n));--4.6
end;

同时带有in和out

--带out输出类型的函数
create or replace function fun_outArg(num in int,res out int)
return string as
mess string(64):= '已计算完成';
begin
     res := num * 2;
     return mess;
end fun_outArg;

declare
       res int := 0;
       begin
            dbms_output.put_line(fun_outArg(25,res));
            dbms_output.put_line('计算结果是:'||to_char(res));
       end;

结果
在这里插入图片描述
既是输入又是输出的函数

--in out 类型参数
--给定一个整数获取其平方根
create or replace function fun_in_out(num in out number)
return number as
begin
     num:=sqrt(num);
     return num*2;
end fun_in_out;

declare 
        res number := 7;
begin
     dbms_output.put_line(fun_in_out(res));
     dbms_output.put_line('结果为'||to_char(res));
end;

存储过程

oracle中存储过程与函数的最大区别在于函数必需有返回值,而存储过程没有返回值。
存储过程在Oracle数据库中使用procedure关键字定义
存储过程与函数一样也支持in,out,in out三种类型参数

--存储过程
--计算梯形面积
create or replace procedure proc_TS_area(up in number,down in number,height in number,area out number)
as
mess string(64) := '已经计算完成';
begin
     area := (up+down)*height / 2;
     dbms_output.put_line(mess);
end proc_TS_area;

--执行储存过程
declare
       area number := 0;
begin
     proc_TS_area(1,1,22.2,area);
     dbms_output.put_line(area);
end;

在这里插入图片描述

触发器

trigger,满足某种条件是自动触发执行,通常在需要时由专门数据开发人员雨哦DBA开发制定。
功能:约束数据功能(触发器是一种复杂的约束定义)
是根据触发动作完成复杂业务数据处理和记录

分类:
DML触发器,最常用的触发器,通常在执行insert,delete和update时自动触发 ;
instead of 触发器,建立在视图上的触发器对象,不提倡使用 DDL触发器,当发生CREATE、ALTER、DROP、TRUNCATE命令时触发此类型触发器;
DB触发器,当数据库系统方式Startup、shutdown、Logon、Logoff是触发DB触发器;

--建立update触发器
create or replace trigger trig_update_emp_tab
before update
on emp --在哪个表
referencing old as o new as n
for each row --定义为行级触发器(不加上这行,下面的结果就只输出一次,即语句触发器)
begin
     dbms_output.put_line('触发器被触发触发');
end;

select * from emp;
update emp set name = '王改名' where emp.sid in (1,2);--有两个数据被更新

停用,启用,删除

alter trigger trig_update_emp_tab disable;--禁用触发器
alter trigger trig_update_emp_tab enable;--启用触发器
drop trigger trig_update_emp_tab;--删除触发器

事务处理

指作为独立的逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。
事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。

特点:
不可分割、隔离性、一致性、持久性

commit 提交事务处理
rollback 撤销?回滚事务处理
savepoint 事务保存点
rollback to savepoint 回滚到事务保存点


declare 
mc string(64) := '转账成功';
mf string(64) := '转账失败';
err_exception exception;
pragma exception_init(err_exception,-2290);

begin
     insert into bussiness values(seq_test.nextval,10000,1,default,100);
     insert into bussiness values(seq_test.nextval,1000,0,default,100);
     update account set balace = balace + 10000;
     update account set balace = balace - 1000;
     commit;--提交事务
     dbms_output.put_line(mc);
     exception when err_exception then 
     rollback;--回滚所有操作
     dbms_output.put_line(mf);
end;
     

事务执行中部分撤销


create table aaa
(
 address varchar2(33)
)
     
select * from aaa;
     
declare 
mes string(64) := '零不能做除数';
zer_error exception;
pragma exception_init(zer_error,-1476);

begin
     insert into aaa values('广东');
     savepoint insert_point;--设置一个保存点
     dbms_output.put_line(56/0);
     commit;
     exception when zer_error then 
     rollback to insert_point;--撤销到保存点
     dbms_output.put_line(mes);
end;

猜你喜欢

转载自blog.csdn.net/weixin_42953201/article/details/119814943