JAVAEE框架数据库技术之13_oracle 之PLSQL技术及存储过程和函数(一)

简介: JAVAEE框架数据库技术之13_oracle 之PLSQL技术及存储过程和函数

day03_Oracle

一、课程目标

PLSQL语法(掌握)
存储函数(了解)
存储过程(掌握)
JAVA来调用oracle函数或过程(掌握)

二、PL/SQL基础语法

2.1 什么是PL/SQL

PL/SQL(Procedure Language/SQL)是 Oracle 对 sql 语言的过程化扩展,指在 SQL 命令语言中增加了过程处理语句(如分支、循环等),使 SQL 语言具有过程处理能力。把 SQL 语言的数据操纵能力与过程语言的数据处理能力结合起来,使得 PLSQL 面向过程但比过程语言简单、高效、灵活和实用。

2.2 基本语法

[declare 
  --声明变量
]
begin
  --代码逻辑 
[exception
    --异常处理
 ]
end;

2.3 变量

  • 声明变量和赋值
变量名 类型(长度);  
-- 1.基本类型
变量名:=变量值
--  1+1=2的案例
declare 
   a int:=1;
   b int:=1;
   c number;
begin  
  c:=a+b;
   dbms_output.put_line(c);   
end;
  • Select into 方式 赋值
select 列名 into 变量名 from 表名 where 条件
  • 注意:结果必须是一条记录(不是一个值) ,有多条记录和没有记录都会报错
declare 
   num_sal number;
   var_name varchar2(20);
   begin
            select ename,sal into var_name,num_sal from emp where empno=7369;
            dbms_output.put_line(var_name||'工资是:'||num_sal);
   end;
  • 引用变量
    优点:1.用户不必查看表中各列的数据类型,即可查询到所需数据;
    2.对表中已经有的数据类型进行修改,不必考虑已定义的数据类型,和表中的一致;
    2.%Type类型
    – 变量 表名.列名%type
    使用%Type关键字可以声明一个与指定名称相同的数据类型,它通常跟在指定列名的后面。

         

var_job emp.job%type – 表示var_job和emp表下的job是同一个类型;

参考案例(同上做比较):
```plsql
select * from emp
declare
   var_job emp.job%type;
   var_name emp.ename%type;
begin
  select ename,job into var_name,var_job from emp where empno=7369;
  dbms_output.put_line(var_name||'职务:'||var_job);
end;

3.%rowtype类型

记录类型,用来存储从数据表查询到的一行的数据

语法:表变量名 表名%rowtype;

declare 
   varEmp  emp%rowtype;
   begin
     select * into varEmp from emp where empno= 7839;
     dbms_output.put_line('员工'||varEmp.empno||'姓名'||varEmp.ename);
 end;

从运行结果可以看到,变量varEmp和emp表的结构完全相同。

2.4 异常

在运行程序时出现的错误叫做异常发生异常后,语句将停止执行,控制权转移到 PL/SQL 块的异常处理部分

异常有两种类型:

  • 预定义异常

当 PL/SQL 程序违反 Oracle 规则或超越系统限制时隐式引发

  • 用户定义异常

用户可以在 PL/SQL 块的声明部分定义异常,自定义的

异常通过 RAISE 语句显式引发

2.4.1 预定义异常

Oracle 预定义异常 21 个

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e1H8eidn-1666020355057)(assets/image-20210326085850685.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h24a1ePX-1666020355059)(assets/image-20210326085917379.png)]

2.4.2 语法结构

exception
  when 异常类型 then
       异常处理逻辑

案例

declare
       primary_iter exception;  -- 定义一个自定义异常
       pragma exception_init(primary_iter,-00001);
       begin
         insert into emp(empno,ename)values(7369,'sss');
       exception
         when primary_iter then
              dbms_output.put_line('主键不能重复');
       end;

2.5 条件判断

2.5.2 单分支

if 条件 then
  业务逻辑
end if;
declare
   vnum number:=#
   begin
     if vnum=1 then 
        dbms_output.put_line('成功登录');
     end if;
   end;

2.5.2 if else

if 条件 then
 业务逻辑
else
 业务逻辑
end if;
declare
   vnum number:=#
   begin
        if vnum=1 then
           dbms_output.put_line('登录成功');
        else
          dbms_output.put_line('登录失败');
        end if;
     end;

2.5.3 多分支

if 条件 then
  业务逻辑
elsif 条件 then  -- 注意:这个长相:是els+if
  业务逻辑
else
  业务逻辑 
end if;
declare
   age number:= #
   begin
     if age<18 then 
       dbms_output.put_line('未成年人');
     elsif age>=18 and age<60 then 
       dbms_output.put_line('年轻人');
     elsif age>=60 and age<80 then
       dbms_output.put_line('中年人');
     elsif age>=80 then
       dbms_output.put_line('老人');
     end if;       
   end;

2.5.4 Case语句

Oracle 9i之后增加的语句,笔记二未体现。

declare
   age integer:=&num;
   vresult varchar2(100); -- 别起result关键字;
   begin
     case 
       when age<18 then
         vresult:='未成年人';
       when age>=18 and age<60 then
         vresult:='年轻人';
       when age>=60 and age<80 then
         vresult:='中年人';
       when age>=80 then
         vresult:='老年人';
     end case;
     dbms_output.put_line(vresult);
   end;

2.6 循环

2.6.1 loop when循环

  • 语法
loop   
 --循环语句   类似于之前的do while循环
   exit when 退出条件;
end loop;
  • 演示

输出从1开始的100个数

declare
  i number:=1;
begin 
 loop
   dbms_output.put_line(i);
     i:=i+1;
     exit when i>100;
 end loop; 
end ;

2.6.2 when loop循环

  • 语法
while 循环条件  
loop
  循环体
end loop;
  • 演示

输出从1开始的100个数

declare
  i number:=1;
begin
 while i<=100 loop
     dbms_output.put_line(i);
     i:=i+1; 
 end loop; 
end ;

2.6.3 for … loop循环

  • 语法
-- for(int i=1;i<结束值;i++){}
for 变量 in 起始值..终止值 loop
    -- 循环语句
end loop;
  • 演示

输出从1开始的100个数

begin
 for i in 1..100
 loop
  dbms_output.put_line(i); 
 end loop;
end;

向表中插入数据;

insert into student(id,name)values(seq_test.nextval,'李四')
-- 向student表中插入1000条数据;使用while loop循环????
declare
   i number :=1;
begin
  while i<=1000 loop -- 当大于2755的时候,控制台会报错;插入没问题;
      -- dbms_output.put_line(i); 在sql控制台输出
      insert into student(id,name)values(seq_test.nextval,'李四'||i);
      commit;
      i:=i+1;
  end loop;    
end;

三、存储函数

3.1 什么是存储函数

存储函数又称为自定义函数,一种存储在数据库中的命令程序块。可以接收零或多个参数,必须有返回值

3.2 存储函数语法

创建或修改存储过程的语法如下:

CREATE [ OR REPLACE ] FUNCTION 函数名称(参数名称 参数类型, 参数名称 参数类型,...n)
  RETURN 结果变量数据类型
IS
   变量声明部分;
BEGIN
 -- 逻辑部分;
    RETURN  结果变量;
[EXCEPTION 异常处理部分]
END;

示例

需求:根两个数相加函数

create or replace function f_sum(a number,b number) return number
is fresult number;  -- 这个是变量,fresult这个是需要return
begin
       fresult:=a+b;
       return fresult;
  end;

调用存储函数

select f_sum(3,2) from dual

实用函数:

Create Or Replace Function Money2Chinese(Money In Number) Return Varchar2 Is
  strYuan       Varchar2(150);
  strYuanFen    Varchar2(152);
  numLenYuan    Number;
  numLenYuanFen Number;
  strRstYuan    Varchar2(600);
  strRstFen     Varchar2(200);
  strRst        Varchar2(800);
  Type typeTabMapping Is Table Of Varchar2(8) Index By Binary_Integer;
  tabNumMapping  typeTabMapping;
  tabUnitMapping typeTabMapping;
  numUnitIndex   Number;
  i              Number;
  j              Number;
  charCurrentNum Char(1);
Begin
  If Money Is Null Then
    Return Null;
  End If;
  strYuan := TO_CHAR(FLOOR(Money));
  If strYuan = '0' Then
    numLenYuan := 0;
    strYuanFen := lpad(TO_CHAR(FLOOR(Money * 100)), 2, '0');
  Else
    numLenYuan := length(strYuan);
    strYuanFen := TO_CHAR(FLOOR(Money * 100));
  End If;
  If strYuanFen = '0' Then
    numLenYuanFen := 0;
  Else
    numLenYuanFen := length(strYuanFen);
  End If;
  If numLenYuan = 0 Or numLenYuanFen = 0 Then
    strRst := '零圆整';
    Return strRst;
  End If;
  tabNumMapping(0) := '零';
  tabNumMapping(1) := '壹';
  tabNumMapping(2) := '贰';
  tabNumMapping(3) := '叁';
  tabNumMapping(4) := '肆';
  tabNumMapping(5) := '伍';
  tabNumMapping(6) := '陆';
  tabNumMapping(7) := '柒';
  tabNumMapping(8) := '捌';
  tabNumMapping(9) := '玖';
  tabUnitMapping(-2) := '分';
  tabUnitMapping(-1) := '角';
  tabUnitMapping(1) := '';
  tabUnitMapping(2) := '拾';
  tabUnitMapping(3) := '佰';
  tabUnitMapping(4) := '仟';
  tabUnitMapping(5) := '万';
  tabUnitMapping(6) := '拾';
  tabUnitMapping(7) := '佰';
  tabUnitMapping(8) := '仟';
  tabUnitMapping(9) := '亿';
  For i In 1 .. numLenYuan Loop
    j            := numLenYuan - i + 1;
    numUnitIndex := Mod(i, 8);
    If numUnitIndex = 0 Then
      numUnitIndex := 8;
    End If;
    If numUnitIndex = 1 And i > 1 Then
      strRstYuan := tabUnitMapping(9) || strRstYuan;
    End If;
    charCurrentNum := substr(strYuan, j, 1);
    If charCurrentNum <> 0 Then
      strRstYuan := tabNumMapping(charCurrentNum) ||
                    tabUnitMapping(numUnitIndex) || strRstYuan;
    Else
      If (i = 1 Or i = 5) Then
        If substr(strYuan, j - 3, 4) <> '0000' Then
          strRstYuan := tabUnitMapping(numUnitIndex) || strRstYuan;
        End If;
      Else
        If substr(strYuan, j + 1, 1) <> '0' Then
          strRstYuan := tabNumMapping(charCurrentNum) || strRstYuan;
        End If;
      End If;
    End If;
  End Loop;
  For i In -2 .. -1 Loop
    j              := numLenYuan - i;
    charCurrentNum := substr(strYuanFen, j, 1);
    If charCurrentNum <> '0' Then
      strRstFen := tabNumMapping(charCurrentNum) || tabUnitMapping(i) ||
                   strRstFen;
    End If;
  End Loop;
  If strRstYuan Is Not Null Then
    strRstYuan := strRstYuan || '圆';
  End If;
  If strRstFen Is Null Then
    strRstYuan := strRstYuan || '整';
  Elsif length(strRstFen) = 2 And substr(strRstFen, 2) = '角' Then
    strRstFen := strRstFen || '整';
  End If;
  strRst := strRstYuan || strRstFen;
  --strRst := Replace(strRst, '亿零', '亿');
  --strRst := Replace(strRst, '万零', '万');
  Return strRst;
End Money2Chinese;
-- 调用--
Select Money2Chinese(786.213) From dual;


JAVAEE框架数据库技术之13_oracle 之PLSQL技术及存储过程和函数(二)https://developer.aliyun.com/article/1432878

目录
相关文章
|
27天前
|
存储 缓存 Java
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
93 3
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
|
10天前
|
人工智能 Cloud Native 多模数据库
实力见证!数据管理服务DMS、云原生多模数据库Lindorm荣获“2024技术卓越奖”
实力见证!数据管理服务DMS、云原生多模数据库Lindorm荣获“2024技术卓越奖”
|
1月前
|
SQL 存储 关系型数据库
【SQL技术】不同数据库引擎 SQL 优化方案剖析
不同数据库系统(MySQL、PostgreSQL、Doris、Hive)的SQL优化策略。存储引擎特点、SQL执行流程及常见操作(如条件查询、排序、聚合函数)的优化方法。针对各数据库,索引使用、分区裁剪、谓词下推等技术,并提供了具体的SQL示例。通用的SQL调优技巧,如避免使用`COUNT(DISTINCT)`、减少小文件问题、慎重使用`SELECT *`等。通过合理选择和应用这些优化策略,可以显著提升数据库查询性能和系统稳定性。
85 9
|
2月前
|
存储 运维 OLAP
【Meetup回顾 第1期】竟是这样的国产数据库,YashanDB技术内幕曝光
YashanDB是一款基于统一内核,支持单机/主备、共享集群、分布式等多种部署方式,覆盖OLTP/HTAP/OLAP交易和分析混合负载场景的新型数据库系统;YashanDB同时提供开发平台、运维平台和迁移平台3大工具平台以满足数据全生命周期管理。
48 2
【Meetup回顾 第1期】竟是这样的国产数据库,YashanDB技术内幕曝光
|
2月前
|
关系型数据库 分布式数据库 数据库
1月17日|阿里云云谷园区,PolarDB V2.0技术沙龙,畅聊国产数据库
为了助力国产化项目顺利推进,阿里云邀请企业开发者和数据库负责人到云谷园区,与PolarDB V2.0技术专家面对面交流。扫描海报二维码报名,我们将根据信息为您申请入园。欢迎参与,共同探讨PolarDB的最新技术和应用!
|
3月前
|
存储 JSON NoSQL
学习 MongoDB:打开强大的数据库技术大门
MongoDB 是一个基于分布式文件存储的文档数据库,由 C++ 编写,旨在为 Web 应用提供可扩展的高性能数据存储解决方案。它与 MySQL 类似,但使用文档结构而非表结构。核心概念包括:数据库(Database)、集合(Collection)、文档(Document)和字段(Field)。MongoDB 使用 BSON 格式存储数据,支持多种数据类型,如字符串、整数、数组等,并通过二进制编码实现高效存储和传输。BSON 文档结构类似 JSON,但更紧凑,适合网络传输。
94 15
|
3月前
|
人工智能 物联网 大数据
解密时序数据库的未来:TDengine Open Day技术沙龙精彩回顾
在数字化时代,开源已成为推动技术创新和知识共享的核心力量,尤其在数据领域,开源技术的涌现不仅促进了行业的快速发展,也让更多的开发者和技术爱好者得以参与其中。随着物联网、工业互联网等技术的广泛应用,时序数据库的需求愈发强烈,开源的兴起更是为这一技术的创新与普及提供了强有力的支持。
56 3
|
2月前
|
关系型数据库 MySQL 数据库连接
数据库连接工具连接mysql提示:“Host ‘172.23.0.1‘ is not allowed to connect to this MySQL server“
docker-compose部署mysql8服务后,连接时提示不允许连接问题解决
|
1月前
|
关系型数据库 MySQL 数据库
Docker Compose V2 安装常用数据库MySQL+Mongo
以上内容涵盖了使用 Docker Compose 安装和管理 MySQL 和 MongoDB 的详细步骤,希望对您有所帮助。
165 42
|
24天前
|
关系型数据库 MySQL 网络安全
如何排查和解决PHP连接数据库MYSQL失败写锁的问题
通过本文的介绍,您可以系统地了解如何排查和解决PHP连接MySQL数据库失败及写锁问题。通过检查配置、确保服务启动、调整防火墙设置和用户权限,以及识别和解决长时间运行的事务和死锁问题,可以有效地保障应用的稳定运行。
122 25

推荐镜像

更多