java存储过程

文章目录

      • 1、PLSQL编程
        • 1.1 程序结构
        • 1.2 变量
        • 1.3 流程控制
      • 2.1 什么是游标
        • 2.2 语法
        • 2.3 游标的属性
        • 2.4 创建和使用
        • 2.5 带参数的游标
      • 3.1 概念作用
        • 3.2 语法
        • 3.4 带输入参数的存储过程
        • 3.5 带输出参数的存储过程
        • 3.6 java程序调用存储过程

1、PLSQL编程

1.1 程序结构

存储过程优点:减少数据库和服务器网络交互,提高执行效率(将写到java程序中的代码抽到数据库)

PLSQL不区分大小写,三个部分组成:

//声明部分:
DECLARE**
-- 声明变量、游标(没有可省略)

//可执行部分:

BEGIN

DBMS_output.put_line('hello world');   --  打印语句

//异常部分:(没有的话可省略)

END;

1.2 变量

1.2.1 普通变量

变量赋值的方式有两种:

1、直接赋值语句 := 比如 v_name :=‘zhangsan’

2、语句赋值,使用 select… into …赋值: (语法:select 值 into 变量)

CREATE OR REPLACE PROCEDURE TEST01 AS 
 -- 薪水
 v_sal NUMBER ;
 -- 地址
 v_addr VARCHAR2(200);
 -- 姓名
 v_name varchar(200) :='zhangsan';
BEGIN
 -- 直接赋值
  v_sal :=  1500;
 -- 语句赋值
 select '北京奥森' into v_addr from dual;
 -- 打印输出
 DBMS_OUTPUT.PUT_line( v_addr||v_name||v_sal );   // 北京奥森zhangsan1500
END TEST01;

注:1、创建新的存储过程直接在AS后面写变量,不需要写declare(可理解为declare优化成as)
   2、需要我们先手动编译,在执行运行(与java语言不同,java语言是运行时自己完成编译)

1.2.2 引用型变量

好处:不需要考虑表中列的类型,使用%TYPE可以使得编码方式更灵活,更加适应数据库更新

通过 表名.列名%TYPE 指定变量的类型和长度,如 : v_name emp.ename%TYPE

create or replace PROCEDURE TEST01 AS 

v_name  a_i_app_use_time.org_name%TYPE;
v_id  a_i_app_use_time.use_time_id%TYPE;

BEGIN

select  org_name,use_time_id  into v_name,v_id from a_i_app_use_time where use_time_id=517861;
 -- 打印输出
  DBMS_OUTPUT.PUT_line( v_name||v_id ); //合肥供电公司517861
  
END TEST01;

1.2.3 记录型变量

慎用!!!接受表中的一整行记录,相当于java中的一个对象

语法: 变量名称 表名%ROWTYPE , 例如: v_emp emp%rowtype;

create or replace PROCEDURE TEST01 AS 
     v_emp a_i_app_use_time%rowtype;  // 格式:变量名称 表名%ROWTYPE
BEGIN

select  *  into v_emp from a_i_app_use_time where use_time_id=517861;
 -- 打印输出 (需要哪个字段用 ‘对象.字段’ 的方式)
 DBMS_OUTPUT.PUT_line(v_emp.org_no||v_emp.emp_no); //34401HF01
END TEST01;

使用场景:如果一个表有100个字段,使用引用变量声明会特别麻烦,这种情况可以使用记录型变量。

1.3 流程控制

1.3.1 条件分支

语法:

BEGIN

     IF  条件1 THEN  执行1

     ELSIF 条件2 THEN 执行2      -- 注意关键字:ELSIF   !!!!!!

     ELSE 执行3  

     END IF;

END
//判断表中数据总条数,进行条件打印
CREATE OR REPLACE PROCEDURE STUDY AS 
v_count NUMBER;

BEGIN

SELECT count(1) into v_count from a_i_app_use_time;  //count(1)效率比count(*)高
if v_count>15 then
DBMS_OUTPUT.put_line('总条数为:'||v_count);
elsif v_count<=5 then                                // elsif 是关键字,不分开
DBMS_OUTPUT.put_line('0000:'||v_count);
else
DBMS_OUTPUT.put_line('1111:'||v_count);
end if;                 //过程执行语句,有开始就要有结束 

END STUDY;

1.3.2 循环

CREATE OR REPLACE PROCEDURE STUDY AS 
v_num number:=1;  //开始的条件
BEGIN
loop
exit when v_num>5;   //结束条件
v_num :=v_num+1;     //循环条件
DBMS_OUTPUT.PUT_LINE(v_num);       // 2、3、4、5、6
end loop;            // 有开始就要有结束
END STUDY;

2.1 什么是游标

用于临时存储一个查询返回的多行数据(结果集,类似于java的jdbc连接返回的ResultSet集合),通过遍历游标,可以逐行访问处理该结果集的数据。

游标的使用方式:声明—>打开—>读取—>关闭

2.2 语法

游标声明:

CURSOR 游标名[(参数列表)] IS 查询语句;

游标的打开:

OPEN 游标名;

游标的取值:

FETCH 游标名 INTO 变量列表;

游标的关闭:

CLOSE 游标名;

2.3 游标的属性

游标的属性 返回值类型 说明
%ROWCOUNT 整型 获得FETCH语句返回的数据行数
%FOUND 布尔型 最近的FETCH语句返回一行数据则为真,否则为假
%NOTFOUND 布尔型 与%FOUND属性返回值相反
%ISOPEN 布尔型 游标已经打开时值为真,否则为假

其中%NOTFOUND是在游标中找不到元素的时候返回TRUE,通常用来判断退出循环。

2.4 创建和使用

CREATE OR REPLACE PROCEDURE STUDY AS 
-- 声明游标
CURSOR v_data is select org_name,user_mobile from a_i_app_use_time ;
-- 声明变量去接收游标里的值
v_name   a_i_app_use_time.org_name%TYPE;
v_mobile a_i_app_use_time.user_mobile%TYPE;
BEGIN
-- 打开游标
open v_data;
-- 遍历游标,注意要先fetch
LOOP
-- 获取游标数据赋值,注意赋值的顺序
FETCH v_data into v_name,v_mobile;   
-- 结束循环的条件
exit when v_data%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_name||'----'||v_mobile);
end loop;
-- 关闭游标
close v_data;
END STUDY;

2.5 带参数的游标

基于参数做具体的查询,有点类似于多了个条件

create or replace PROCEDURE STUDY AS 

-- 声明游标(带参数)
CURSOR v_data(id a_i_app_use_time.use_time_id%TYPE) is select org_name,user_mobile from a_i_app_use_time where use_time_id=id ; 
-- 声明变量去接收游标里的值
v_name   a_i_app_use_time.org_name%TYPE;
v_mobile a_i_app_use_time.user_mobile%TYPE;
BEGIN
-- 打开游标(输入参数的具体数值)
open v_data(517866);
-- 遍历游标
LOOP
-- 获取游标数据赋值,注意赋值的顺序
FETCH v_data into v_name,v_mobile; 
-- 结束循环的条件
exit when v_data%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_name||'----'||v_mobile);   // 根据参数只查询到一条数据
end loop;
-- 关闭游标
close v_data;
END STUDY;

3.1 概念作用

之前我们编写的PLSQL程序可以进行表的操作,判断、循环逻辑处理的工作,但无法重复调用。

可以理解为之前的代码全部编写在了main方法中,是匿名程序。Java可以通过封装对象和方法来解决服用问题。

PLSQL是将一个个PLSQL的业务处理过程存储起来进行复用,这些被存储起来的PLSQL程序称之为存储过程。

存储过程作用:

1、在一个开发过程中,为了一个特定的业务功能,会向数据库进行多次连接关闭(非常耗费资源),需要对数据库进行多次的I/O读写,性能比较低。如果把这些业务放到PLSQL中,在应用程序中,只需要调用PLSQL就可以做到连接关闭一次数据库就可以实现我们的业务,大大提高了效率。

2、ORACLE官方给的建议:能够让数据库操作的不要放在程序中,在数据库中实现基本不会出现错误,在程序中操作可能会存在错误(如果在数据库中操作数据,可以有一定的日志恢复功能)。

3.2 语法

create or replace PROCEDURE 过程名称[(参数列表)]  AS


BEGIN

END[过程名称]; 

```plsql
根据参数的类型,我们将其分为3类讲解:

1、不带参数的

2、带参数的

3、带输入输出(返回值)参数的

3.3 无参存储

**3.3.1 创建存储**

通过工具直接创建即可。

**3.3.2 调用存储过程**

​```plsql
// set serveroutput on;   -- 当调用时,显示过程已经完成,却没有显示结果时执行该条语句可解决
BEGIN
STUDY; -- 调用day02写好的名为STUDY的存储过程
STUDY; -- 又调用了一遍,写几遍即调用几遍
end;

3.4 带输入参数的存储过程

【示例】

CREATE OR REPLACE PROCEDURE DEMOTEST ( ID IN NUMBER DEFAULT 517866) AS  -- 入参给定一个默认值

v_name a_i_app_use_time.org_name%TYPE;
v_ym a_i_app_use_time.stat_ym%TYPE;

BEGIN  
select org_name ,stat_ym into v_name ,v_ym FROM a_i_app_use_time where use_time_id=id;
DBMS_OUTPUT.put_line(v_name||v_ym);  //  合肥供电公司20200506
END DEMOTEST;

===================================调用上面存储过程如下===================================
begin
DEMOTEST(517867);  
end;

3.5 带输出参数的存储过程

带输出参数的存储过程通常都是给第三方使用的,比如我们的java

CREATE OR REPLACE PROCEDURE DEMO_IN_OUT 
(
  ID IN NUMBER         -- 输入参数作为条件
, V_YM OUT VARCHAR2    -- 输出参数,需返回
) AS 
BEGIN
SELECT
    stat_ym into v_ym   FROM a_i_app_use_time where  use_time_id=id;
END DEMO_IN_OUT;

================================调用上述存储过程=====================================
DECLARE  -- 声明变量接收返回值
v_ym a_i_app_use_time.stat_ym%TYPE;
begin
DEMO_IN_OUT(517866,v_ym);     --    注意入参、出参的顺序
DBMS_OUTPUT.put_line(v_ym);   //    20200506
end;

3.6 java程序调用存储过程

​ 通常指带输出参数的存储过程,我们给一个参数,过程让其完成返回一个结果集,减少了网络了交互。

​ 通过JDBC连接中的Connection的prepareCall方法来调用存储过程

//1. 加载驱动
Class.forName("oracle.jdbc.driver.OracleDriver");
//2. 获取连接对象
Connection conn=DriverManager.getConnect(url,user,password);

//3.获得语句对象
String sql=“{call 存储过程名称(?,?)}”; -- 转义sql,专门用来调取存储过程,这里有两个参数,两个 ? ?
Callableable call=conn.prepareCall(sql);

//4设置输入参数
call.setInt(1,100); -- 什么类型就设置什么类型,与之前sql无异

//5.注册输出参数
call.registerOutParameter(2,OracleTypes.Varchar); -- 注册类型对应Oracle里面的类型

//6.执行存储过程
call.execute();

//7.获取输出参数
String result=call.getString(2);

你可能感兴趣的:(javase,java,数据库,开发语言)