PLSQL--Oracle的存储过程

一.普通变量
-- 打印人员个人信息,包括:姓名,薪水,地址
declare
  --姓名
  v_name varchar2(20) := 'XXX';  --声明变量直接赋值
  --薪水
  v_sal number;
  --地址
  v_addr varchar2(200);
begin
  -- 在程序中直接赋值
  v_sal := 2300;
  --语句赋值
  select  'XXX公司'  into v_addr from dual;

  --打印输出
  dbms_output.put_line('姓名:'||v_name|| ',薪水:' ||v_sal|| ',地址:' ||v_addr);

end;
=========================================================================

二.引用型变量
   1.变量的类型和长度取决于表中字段的类型和长度
   2.通过表名.列名%TYPE指定变量的类型和长度, v_name emp.ename%TYPE

-- 查询工号为7839 的  姓名和薪水
declare
  --姓名
  v_name emp.ename%TYPE;
  --薪水
  v_sal emp.sal%TYPE;

begin

    
  select ename, sal into v_name, v_sal from emp where empno = 7839;

  --打印输出
  dbms_output.put_line('姓名:' || v_name || ',薪水:' || v_sal);

end;


========================================================================
三.
   1.接收表中的一整行记录,相当于Java中的一个对象
    语法:变量名称  表名%ROWTYPE, 例如:v_emp emp%rowtype;

--查询 emp 表中 7839 号员工的个人信息,打印姓名和薪水
declare 
  --记录型变量
  v_emp  emp%ROWTYPE;    --记录变量  就相当于一条记录

begin
  --错误使用:  1.SELECT  ename   INTO V_EMP FROM EMP WHERE EID = 7839;(报错:值过多)
 ---错误使用: 2.SELECT * INTO V_EMP FROM EMP(报错:超出请求行数)

   SELECT * INTO V_EMP FROM EMP WHERE EID = 7839;
   
   --打印输出
   DBMS_OUTPUT.PUT_LINE('姓名:' || v_emp.v_ename || ',薪水:' || v_emp.v_sal);   

end;
--记录型变量  慎用   会增加数据库的负担

--使用场景 : 如果有一个表,有100个字段,如果你使用引用型变量一个个声明会特别麻烦,记录型变量可以解决这个问题

=========================================================================

四.流程控制(条件分支)
      1.if    elsif    else   多条件判断    

例:
--判断emp表中记录是否超过20条,10-20之间,或者10条一下
declare
  --声明变量接受emp中的数量
  v_count number;

begin

  SELECT  count(1)   INTO   v_count   FROM   EMP;

  if v_count > 20 then
    dbms_output.put_line('emp表中记录数量超过20条为:' || v_count);
  elsif v_count >= 10 then
    dbms_output.put_line('emp表中记录数量超过10-20条为:' || v_count);
  else
    dbms_output.put_line('emp表中记录数量超过10条以下为:' || v_count);
  
  end if;

end;

=========================================================================

五.循环
  1.oracle循环有三种   第一种:loop循环   第二种:for   第三种:while
  2  loop循环:

示例:

--打印1-10数字
declare
  --声明一个循环变量
  v_num number := 1;

begin

  loop--开始循环
  
    exit when v_num > 10;    --退出条件的判断
  
    dbms_output.put_line(v_num);  -- 打印
  
    --循环变量的自增
    v_num := v_num + 1;
  
  end loop; --结束循环

end;

=========================================================================

六.游标
一.
    1.什么是游标  :用于临时存储一个查询返回的多行数据(结果集,类似于Java的JDBC连接返回ResultSet集合),通过遍历游标,可以
 逐行访问处理该结果集的数据
    2.游标的使用方式:声明-->打开-->读取-->关闭
 二.语法 :
  游标声明 :
    CURSOR 游标名{(参数列表)} IS 查询语句;

游标的打开:
   
OPEN游标名;
游标的取值;
FETCH 游标名  INTO 变量列表;
游标的关闭:
CLOSE  游标名;
  
3.游标的属性

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

4.游标的创建和使用
       
         (1)无参游标


     示例:
      -- 使用游标查询emp表中所有的员工姓名和工资。并且将其依次打印出来
declare
  --声明游标
  cursor c_emp is
    select ename, sal from emp;

  --声明变量接收游标中的数据
  v_ename emp.ename%TYPE;
  v_sal   emp.sal%TYPE;

begin

  --打开游标
  open c_emp;

  --循环遍历游标
  loop
  
    --获取游标中的数据
  
    fetch c_emp
      into v_ename, v_sal;
  
    --退出循环条件的判断
    exit when  c_emp%NOTFOUND;
  
    dbms_output.put_line(v_ename||'-'||v_sal);
    
  end loop;

  --关闭游标
  close c_emp;

end;

(2).带参数的游标

-- 使用游标查询emp表中所有的员工姓名和工资。并且将其依次打印出来
declare
  --声明游标
  cursor c_emp(v_deptno emp.deptno%TYPE) is
    select ename, sal from emp where deptno = v_deptno  ;

  --声明变量接收游标中的数据
  v_ename emp.ename%TYPE;
  v_sal   emp.sal%TYPE;

begin

  --打开游标
  open c_emp(10088);

  --循环遍历游标
  loop
  
    --获取游标中的数据
  
    fetch c_emp
      into v_ename, v_sal;
  
    --退出循环条件的判断
    exit when  c_emp%NOTFOUND;
  
    dbms_output.put_line(v_ename||'-'||v_sal);
    
  end loop;

  --关闭游标
  close c_emp;

end;


注意: fetch   不能放错位置  否则默认有值


=========================================================================

七.存储过程

    1.概念和作用

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

       可以理解之前的代码全部编写在了main方法中,是匿名程序,JAVA可以通过封装对象和方法来解决复用问题
             
      PLSQL是将一个个PLSQL的业务处理过程存储起来进行复用,这些被存储起来的PLSQL程序称之为存储过程

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

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


    二.无参存储过程

    新建一个程序窗口 在程序窗口中选择过程

    在过程中写


   示例:
             create or replace procedure p_hello as
             --在这里直接声明变量   

             begin

             dbms_output.put_line('hello word');

             end p_hello;


然后在测试窗口,调用存储过程
      示例:

                begin
                 --PLSQL调用存储过程
                p_hello;

                end;

       
三.带参存储过程
     
             新建一个程序窗口 在程序窗口中选择过程

             在存储过程中写


           示例:
              -- 查询并打印某个员工(如7839号员工)的姓名和薪水--存储过程:要求调用的时候传入员工编号,自动控制台打印
             create or replace procedure p_querynameandsal(i_empno in  emp.empno%TYPE) as
             --声明变量
             v_name emp.ename%TYPE;
             v_sal  emp.sal%TYPE;
             begin
  
             --查询emp表中某个员工的姓名和薪水并赋值给变量
             select  ename,sal  into  v_name,v_sal  from  emp  where  empno = i_empno;
             dbms_output.put_line(v_name||'_'||v_sal);

            end p_querynameandsal;

然后在测试窗口,调用存储过程
      示例:

     -- Created on 2022/11/24 by 王宇超 
    declare 
    -- Local variables here    或者在这里声明一个参数
    i integer;
   begin
    -- Test statements here
   p_querynameandsal(7839);--直接赋值
  
   end;


三.带输出参数的存储过程

     新建一个程序窗口 在程序窗口中选择过程

    在过程中写

    示例:
   

-- 输入工号查询某个员工(7839号员工)信息,要求,将薪水作为返回值输出,给调用的程序使用
create or replace procedure p_querysal_out(i_empno in emp.empno%TYPE,
                                           o_sal   out emp.sal%TYPE) as

begin

  --查询emp表中某个员工的姓名和薪水并赋值给变量
  select sal into o_sal from emp where empno = i_empno;

end;


然后在测试窗口,调用存储过程
      示例:


     -- Created on 2022/11/24 by 王宇超 
declare 
  -- 声明变量接收存储过程中的输出参数
  v_sal  emp.sal%TYPE;
  
begin

   p_querysal_out(7839,v_sal);
   dbms_output.put_line(v_sal);
  
end;

=========================================================================

八.JAVA程序调用存储过程

jar包使用Ojdbc8

 在测试类测试一下


代码:


 public static void main(String[] args) throws Exception {

//        OracleDriver

        //1.加载驱动
        Class.forName("oracle.jdbc.driver.OracleDriver");

        //2.获取链接对象
        String  url = "jdbc:oracle:thin:@localhost:1521:orcl";
        String  user = "wyc";
        String  password = "123";
        //返回对象
        Connection conn = DriverManager.getConnection(url, user, password);

        //3.获得语句对象
        //call 调取  存储过程名
        String sql ="{call p_querysal_out(?,?)}";
        CallableStatement call = conn.prepareCall(sql);

        //4.设置输出参数
        //下标从1开始
        call.setInt(1,7839);

        //5.注册输出参数
        call.registerOutParameter(2, OracleTypes.DOUBLE);

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

        //7.获取输出参数
        double sal = call.getDouble(2);
        System.out.println(sal);

        //8.释放资源
        call.close();
        conn.close();

    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值