Oracle数据库PLSQL编程和存储过程
1.1、使用PLSQL实现 Hello world!
1 -- Created on 2022/8/22 by ADMINISTRATOR 2 declare 3 -- 这是申明变量的地方,还包括游标 4 -- 相当于public class A() 5 i integer; 6 begin 7 -- Test statements here 8 -- 执行部分 9 -- public static void main(String args[]){} 10 11 -- 异常处理 12 dbms_output.put_line('hello world!'); 13 end;
1.2、有关变量的定义和使用
PLSQL编程中的变量主要有两大类:
-
普通数据类型:(char、varchar2、data、number、boolean、long)
-
特殊变量类型:(引用型变量、记录型变量)
1.2.1普通变量的申明和打印:
赋值方式:
-
直接赋值:使用 := 符号进行变量的赋值,可以在声明变量时直接赋值,也可以在 begin 中直接赋值;
-
语句赋值:使用 select……into……赋值(语法:select 值 into 变量)
1 -- 声明一个人的信息,姓名、薪水、地址 2 declare 3 -- Local variables here 4 -- 姓名 5 v_name varchar2(50) := '张三丰'; 6 7 -- 薪水 8 v_salary number; 9 10 -- 地址 11 v_addr varchar2(200); 12 begin 13 -- Test statements here 14 -- 直接赋值 15 v_salary := 15900; 16 17 -- 语句赋值 18 select '江苏连云港' into v_addr from dual; 19 20 dbms_output.put_line('姓名:' || v_name || ',薪水:' || v_salary || ',地址:' || v_addr); 21 22 end;
1 姓名:张三丰,薪水:15900,地址:江苏连云港
1.2.2引用型变量的使用
引用型变量的类型和长度取决于表中字段的类型和长度
通过表名.列名%TYPE来指定变量的类型和长度,例如:v_id A_XX.A_ID%TYPE;
【查询A_XX表中ID为2的员工信息,包括ID,地址,并打印出来】
1 declare 2 -- Local variables here 3 -- ID 4 v_id A_XX.A_ID%TYPE; 5 -- 地址 6 v_addr A_XX.ADDRESS%TYPE; 7 begin 8 -- Test statements here 9 -- 语句赋值 10 select a_id , address into v_id , v_addr from A_XX where a_id = 2; 11 12 dbms_output.put_line('ID:' || v_id || ',地址:' || v_addr); 13 14 end;
1 ID:2,地址:xyz
使用引用变量的好处:
相比较普通类型变量需要知道变量的类型和长度而言,引用变量不用考虑表中字段的类型和长度,使得PLSQL编程更加灵活,更加适应数据库的动态更新。
1.2.3记录型变量的使用
记录型变量是用来存储一行数据,相当于JAVA中对象的使用;
基本语法为:变量名 表名%ROWTYPE,例如:v_AA A_XX%ROWTYPE;
1 declare 2 -- Local variables here 3 -- ID 4 v_AA A_XX%ROWTYPE; 5 6 begin 7 -- Test statements here 8 -- 语句赋值 9 select * into v_AA from A_XX where a_id = 2; 10 11 dbms_output.put_line('ID:' || V_AA.A_ID || ',地址:' || V_AA.ADDRESS); 12 13 end;
1 ID:2,地址:xyz
记录型变量适用于一行中变量多的情况下
1.3、流程控制语句
1.3.1条件分支
1 begin 2 IF 条件1 THEN 执行1 3 ELSIF 条件2 THEN 执行2 4 ELSE 执行3 5 END IF; 6 end;
注意关键字ELSIF
1.3.2循环语句
Oracle中有三种循环,这里介绍loop循环
1 begin 2 LOOP 3 EXIT WHEN 退出循环条件 4 END LOOP; 5 end;
【打印数字1-10】
1 declare 2 -- Local variables here 3 -- 设置循环变量并赋初值 4 v_num NUMBER := 1; 5 6 begin 7 -- Test statements here 8 -- LOOP循环 9 LOOP 10 EXIT WHEN V_NUM > 10; 11 dbms_output.put_line(V_NUM); 12 -- 循环自增 13 V_NUM := V_NUM + 1; 14 END LOOP; 15 end;
输出结果:
1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10
二、游标
2.1什么是游标
用于临时储存一个查询返回的多行数据,(结果集,相当于JAVA中的Resultset结果集),可以通过游标遍历,逐行访问处理这个结果集中的数据。
游标的使用步骤:声明——>打开——>读取——>关闭
2.2语法
1 -- 声明游标 2 CURSOR 游标名[(参数列表)] IS 查询语句; 3 4 -- 游标打开 5 OPEN 游标名; 6 7 -- 游标的取值 8 FETCH 游标名 INTO 变量列表; 9 10 -- 游标的关闭 11 CLOSE 游标名;
2.3游标的属性
游标的属性 | 返回值类型 | 说明 |
---|---|---|
%ROWCOUNT | 整型 | 获得FETCH语句返回的数据行数 |
%FOUND | 布尔型 | 最近的FETCH语句返回一行数据为真,否则为假 |
%NOTFOUND | 布尔型 | 最近的FETCH语句返回一行数据为假,否则为真 |
%ISOPEN | 布尔型 | 游标打开为真,否则为假 |
【游标的使用】
1 declare 2 -- 声明一个游标 3 CURSOR C_AA IS 4 SELECT A_ID, ADDRESS FROM A_XX; 5 -- 定义引用变量接收游标中的值 6 V_ID A_XX.A_ID%TYPE; 7 V_ADDR A_XX.ADDRESS%TYPE; 8 begin 9 -- 打开游标 10 OPEN C_AA; 11 -- 读取游标中的值 12 LOOP 13 -- 获取游标中的数据,如果有,赋值给变量 14 FETCH C_AA 15 INTO V_ID, V_ADDR; 16 EXIT WHEN C_AA%NOTFOUND; 17 dbms_output.put_line('ID:' || V_ID || ',地址:' || V_ADDR); 18 END LOOP; 19 -- 关闭游标 20 CLOSE C_AA; 21 end;
三、存储过程
3.1存储过程的概念
之前我们编写的PLSQL程序可以对表进行操作、判断、循环逻辑处理的过程,但无法重复使用;
可以理解为我们将这些程序代码写在了main方法中,作为匿名程序使用,而JAVA是通过将匿名程序封装成方法或对象来实现代码的复用性;
作为PLSQL程序而言,是通过将程序代码存储起来,来实现程序过程的复用性,而这些被存储起来的PLSQL程序,被称之为存储过程
3.2存储过程的作用
-
在开发程序过程中,为了一个特定的业务功能,需要不断地向数据库进行连接关闭,(连接关闭是很耗费资源的),需要对数据库进行多次的I/O读写,性能较低;如果将这些业务放到PLSQL程序中,在应用程序中只需要调用PLSQL就可以完成连接关闭一次数据库,可以大大提高效率。
-
Oracle官方:能够让数据库操作的,不要放在程序代码中。
3.3语法
1 create or replace procedure 过程名称[(参数列表)] is 2 begin 3 4 end 过程名称;
【示例】
1 create or replace procedure p_hello is 2 begin 3 dbms_output.put_line('hello'); 4 5 end p_hello;
根据参数类型,可以将其分为三类:
-
不带参数的
-
带输入参数
-
带输入输出参数(返回值)
3.4无参存储
【示例】
在PROCEDURES中创建一个新的无参存储,并打印hello:
1 create or replace procedure p_hello is 2 begin 3 dbms_output.put_line('hello'); 4 5 end p_hello;
使用Test Window,调用刚才创建的无参存储:
1 -- Created on 2022/8/22 by ADMINISTRATOR 2 declare 3 -- Local variables here 4 --i integer; 5 begin 6 -- Test statements here 7 p_hello; 8 end;
输出结果:
hello
注意:
-
is和as是可以互用的,用哪一个都可以;
-
过程中没有declare关键字,declare用在语句块中;
3.5带输入参数的存储过程
【示例:使用带输入参数的存储过程打印编号为1的地址】
PROCEDURES带输入参数的存储过程:
1 create or replace procedure p_queryaddr(i_id IN A_XX.A_ID%TYPE) is 2 --变量声明 3 V_ADDR A_XX.ADDRESS%TYPE; 4 begin 5 6 SELECT ADDRESS INTO V_ADDR FROM A_XX WHERE A_ID = I_ID; 7 dbms_output.put_line('地址:' || V_ADDR); 8 9 end p_queryaddr;
Test Window 调用带输入参数的存储过程:
1 declare 2 -- Local variables here 3 --i integer; 4 begin 5 -- Test statements here 6 p_queryaddr(1); 7 end;
输出结果:
地址:xxx
3.6带有输入和输出参数的存储过程
【示例】
PROCEDURES:
1 create or replace procedure p_queryaddr_OUT(i_id IN A_XX.A_ID%TYPE , o_addr OUT A_XX.ADDRESS%TYPE) is 2 3 begin 4 5 SELECT ADDRESS INTO O_ADDR FROM A_XX WHERE A_ID = I_ID; 6 7 end p_queryaddr_OUT;
Test Windows:
1 declare 2 -- Local variables here 3 V_ADDR A_XX.ADDRESS%TYPE; 4 begin 5 -- Test statements here 6 p_queryaddr_OUT(1, V_ADDR); 7 8 dbms_output.put_line(V_ADDR); 9 10 end;
输出结果:
xxx