Oracle学习(十二):存储过程/存储函数

简介: 本文主要讲Oracle存储过程/存储函数

1.知识点


--第一个存储过程
/*
打印Hello World
create [or replace] PROCEDURE 过程名(参数列表)  
AS 
        PLSQL子程序体;
调用存储过程:
1. exec sayHelloWorld();
2. begin
      sayHelloWorld();
      sayHelloWorld();
   end;
   /
*/
create or replace procedure sayHelloWorld<span style="white-space:pre"> </span>--sayHelloWorld为过程名
as
--declare
--变量说明
begin
  dbms_output.put_line('Hello World');
end;
/
----------------------------------------------
/*
给指定的员工涨100的工资,并打印涨前和涨后的薪水
create [or replace] PROCEDURE 过程名(参数列表)  --in为输入参数,out为输出参数
AS 
        PLSQL子程序体;
SQL> begin
  2     raiseSalary(7839);
  3     raiseSalary(7566);
  4     commit;
  5  end;
  6  /
涨前:7986  涨后:8086
涨前:5024.53  涨后:5124.53
PL/SQL 过程已成功完成。        
*/
create or replace procedure raiseSalary(eno in number)<span style="white-space:pre">  </span>--带输入参数的存储过程
as
  --变量
  psal emp.sal%type;
begin
  --得到涨前薪水
  select sal into psal from emp where empno=eno;
  --涨工资
  update emp set sal=sal+100 where empno=eno;
  --问题:要不要commit??答:不需要,因为整个事务还没有结束,等调用此存储过程后,再commit
  --打印
  dbms_output.put_line('涨前:'||psal||'  涨后:'||(psal+100));
end;
/
-------------------------------------------------------------------
/*
查询某个员工的年收入
CREATE [OR REPLACE] FUNCTION 函数名(参数列表) 
 RETURN  函数值类型
AS
PLSQL子程序体;
*/
create or replace function queryEmpIncome(eno in number)
return number<span style="white-space:pre"> </span>
as
  --变量
  psal emp.sal%type;
  pcomm emp.comm%type;
begin
  select sal,comm into psal,pcomm from emp where empno=eno;
  return psal*12+nvl(pcomm,0);
end;
/
---------------------------------------------------------------------
--OUT参数
/*
查询某个员工的姓名 月薪 职位
*/
create or replace procedure queryEmpInfo(eno in number,
                                         pename out varchar2,
                                         psal   out number,
                                         pjob   out varchar2)
as
begin
  select ename,sal,empjob into pename,psal,pjob from emp where empno=eno;
end;
/
--------------------------------------------------------------------
--查询某个部门中所有员工的所有信息
--1.创建一个包:MYPACKAGE 
--2.在该包中定义一个自定义类型:empcursor 类型为游标,一个存储过程:queryemp
CREATE OR REPLACE 
PACKAGE MYPACKAGE AS 
  type empcursor is ref cursor; --empcursor是一个自定义类型:引用cursor的类型作为empcursor的类型
  procedure queryEmpList(dno in number,empList out empcursor);  
END MYPACKAGE;
==============================================
CREATE OR REPLACE
PACKAGE BODY MYPACKAGE AS
  procedure queryEmpList(dno in number,empList out empcursor) AS
  BEGIN
      open empList for select * from emp where deptno=dno;
  END queryEmpList;
END MYPACKAGE;
------------------------------------------------------------------

2.JAVA程序中测试存储过程/存储函数


package demo.util;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import oracle.jdbc.OracleCallableStatement;
import oracle.jdbc.OracleTypes;
import org.junit.Test;
/*
 * 
 * 性能:
 * Statement < PreparedStatement  < CallableStatement
 * PreparedStatement:预编译SQL语句,执行的时候告诉参数,至少编辑一次
 * CallableStatement:完成对存储过程/存储函数的调用,没有编译过程,直接调用
 */
public class TestOracle {
  /*
   * create or replace
procedure queryEmpInfo(eno in number,
                                         pename out varchar2,
                                         psal   out number,
                                         pjob   out varchar2)
   */
  @Test
  public void testProcedure(){
    //调用存储过程
    //{call <procedure-name>[(<arg1>,<arg2>, ...)]}
    String sql = "{call queryEmpInfo(?,?,?,?)}";
    Connection conn=null;
    CallableStatement call = null;
    try{
      conn = JDBCUtils.getConnection();
      call = conn.prepareCall(sql);
      //赋值
      call.setInt(1, 7839);
      //对于out参数,申明
      call.registerOutParameter(2, OracleTypes.VARCHAR);
      call.registerOutParameter(3, OracleTypes.NUMBER);
      call.registerOutParameter(4, OracleTypes.VARCHAR);
      //调用
      call.execute();
      //取出结果
      String name = call.getString(2);
      double sal  = call.getDouble(3);
      String job = call.getString(4);
      System.out.println(name);
      System.out.println(sal);
      System.out.println(job);
    }catch (Exception e) {
      e.printStackTrace();
    }finally{
      JDBCUtils.release(conn, call, null);
    }
  }
  /*
   * create or replace
function queryEmpIncome(eno in number)
return number
   */
  @Test
  public void testFunction(){
    //存储函数例子
    //{?= call <procedure-name>[(<arg1>,<arg2>, ...)]}
    String sql = "{?=call queryEmpIncome(?)}";
    Connection conn = null;
    CallableStatement call = null;
    try{
      conn = JDBCUtils.getConnection();
      call = conn.prepareCall(sql);
      call.registerOutParameter(1, OracleTypes.NUMBER);
      call.setInt(2, 7839);
      //执行
      call.execute();
      //取出年收入
      double income = call.getDouble(1);
      System.out.println(income);
    }catch (Exception e) {
      e.printStackTrace();
    }finally{
      JDBCUtils.release(conn, call, null);
    }
  }
  /*
   * 问题:
   * 1. 光标是否被关?:是,结构集关掉后光标就关掉了。
   * 2. 是否能在MYSQL上执行?:不能
   */
  @Test
  public void testCursor(){
    String sql = "{call MYPACKAGE.queryEmpList(?,?)}";
    Connection conn = null;
    CallableStatement call = null;
    ResultSet rs  =null;
    try {
      conn = JDBCUtils.getConnection();
      call = conn.prepareCall(sql);
      call.setInt(1, 10);
      call.registerOutParameter(2, OracleTypes.CURSOR);
      //执行
      call.execute();
      //取出集合
      rs = ((OracleCallableStatement)call).getCursor(2);
      while(rs.next()){
        String name = rs.getString("ename");
        String job = rs.getString("job");
        System.out.println(name+"的职位是"+job);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }finally{
      JDBCUtils.release(conn, call, rs);
    }
  }
}

3.用到的JDBC类


package demo.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCUtils {
  private static String driver="oracle.jdbc.OracleDriver";
  private static String url="jdbc:oracle:thin:@localhost:1521:orcl";
  private static String user="scott";
  private static String password="tiger";
  static{
    try {
      Class.forName(driver);
    } catch (ClassNotFoundException e) {
      throw new ExceptionInInitializerError(e);
    }
  }
  public static Connection getConnection(){
    try {
      return DriverManager.getConnection(url, user, password);
    } catch (SQLException e) {
      e.printStackTrace();
    }
    return null;
  }
  /*
   * 执行java程序
   * java -Xms100M -Xmx200M HelloWorld
   */
  public static void release(Connection conn,Statement stmt,ResultSet rs){
    if(rs!=null){
      try {
        rs.close();
      } catch (SQLException e) {
        e.printStackTrace();
      }finally{
        rs=null;//垃圾回收:是否可以通过代码干预垃圾回收?
      }
    }
    if(stmt!=null){
      try {
        stmt.close();
      } catch (SQLException e) {
        e.printStackTrace();
      }finally{
        rs=null;//垃圾回收:是否可以通过代码干预垃圾回收?
      }
    }
    if(conn!=null){
      try {
        conn.close();
      } catch (SQLException e) {
        e.printStackTrace();
      }finally{
        rs=null;//垃圾回收:是否可以通过代码干预垃圾回收?
      }
    }
  }
}
相关文章
|
8月前
|
存储 Oracle 关系型数据库
服务器数据恢复—光纤存储上oracle数据库数据恢复案例
一台光纤服务器存储上有16块FC硬盘,上层部署了Oracle数据库。服务器存储前面板2个硬盘指示灯显示异常,存储映射到linux操作系统上的卷挂载不上,业务中断。 通过storage manager查看存储状态,发现逻辑卷状态失败。再查看物理磁盘状态,发现其中一块盘报告“警告”,硬盘指示灯显示异常的2块盘报告“失败”。 将当前存储的完整日志状态备份下来,解析备份出来的存储日志并获得了关于逻辑卷结构的部分信息。
|
9月前
|
存储 Oracle 关系型数据库
Oracle存储过程插入临时表优化与慢查询解决方法
优化是一个循序渐进的过程,就像雕刻一座雕像,需要不断地打磨和细化。所以,耐心一点,一步步试验这些方法,最终你将看到那个让你的临时表插入操作如同行云流水、快如闪电的美丽时刻。
407 14
|
SQL 存储 Oracle
【YashanDB知识库】Oracle pipelined函数在YashanDB中的改写
【YashanDB知识库】Oracle pipelined函数在YashanDB中的改写
|
Oracle 关系型数据库 网络安全
Oracle 19c 安装教程学习
Oracle 19c 安装教程学习
4040 2
|
存储 Oracle 关系型数据库
服务器数据恢复—华为S5300存储Oracle数据库恢复案例
服务器存储数据恢复环境: 华为S5300存储中有12块FC硬盘,其中11块硬盘作为数据盘组建了一组RAID5阵列,剩下的1块硬盘作为热备盘使用。基于RAID的LUN分配给linux操作系统使用,存放的数据主要是Oracle数据库。 服务器存储故障: RAID5阵列中1块硬盘出现故障离线,热备盘自动激活开始同步数据,在同步数据的过程中又一块硬盘离线,RAID5阵列瘫痪,上层LUN无法使用。
|
存储 Oracle 关系型数据库
【赵渝强老师】Oracle的物理存储结构
Oracle的物理存储结构包括数据文件、联机重做日志文件、控制文件、归档日志文件、参数文件、告警日志文件、跟踪文件和备份文件。这些文件在硬盘上存储数据库的各种数据和日志信息,确保数据库的正常运行和故障恢复。视频讲解和详细说明见原文。
255 0
|
存储 Oracle 关系型数据库
oracle服务器存储过程中调用http
通过配置权限、创建和调用存储过程,您可以在Oracle数据库中使用UTL_HTTP包发起HTTP请求。这使得Oracle存储过程可以与外部HTTP服务进行交互,从而实现更复杂的数据处理和集成。在实际应用中,根据具体需求调整请求类型和错误处理逻辑,以确保系统的稳定性和可靠性。
856 0
|
SQL Oracle 关系型数据库
|
Oracle 关系型数据库 数据挖掘
|
Oracle 关系型数据库
Oracle常用函数整理
今天再给大家分享一下Oracle的常用函数。
Oracle常用函数整理