zoukankan      html  css  js  c++  java
  • oracle入门(7)——存储过程

    【本文介绍】

    熟悉了PL/SQL语法后,实现java调用oracle存储过程才是主要目的。本文将介绍如何写存储过程,java如何调用存储过程。

    【存储过程介绍】

    抛开专业的描述,存储过程就是在数据库里面写了一些函数,我们在代码(如java)里面调用这些函数实现对数据库的操作,避免了数据库对SQL语句的解析,对于需要发送多条SQL语句才能完成的数据库操作功能来说,速度上升了一个档次。不过程序在操纵数据库这一块 的维护性会降低,因为存储过程是写在数据库,不是写在程序里。

    【如何写有能传值 并且 有返回值(非返回列表)存储过程】

      非返回列表的存储过程比较容易,直接在函数名后面带参数就好,同时赋予参数的类型。

      下面举一个例子:

    存储过程代码:

    CREATE OR REPLACE 
    procedure serachUserMethod(para1 IN VARCHAR2, para2 OUT VARCHAR2)
    as
    BEGIN
    select "user"."name" into para2 from "user" where "user"."name"=para1;
    end;

    java代码

    package com.zjm.www.test;
     
    import java.sql.CallableStatement;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.sql.Types;
    import java.util.Date;
     
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
     
    public class test {
         
        private static String driverclass="oracle.jdbc.driver.OracleDriver";  
        // 本地
        private static String url="jdbc:oracle:thin:@localhost:1521:orcl";  
        private static String username="test";  
        private static String password="Aaa38324836";  
     
        private static String sql="";     
        private static Connection conn = null;
        private static Statement stmt = null;
        private static ResultSet rs = null;
        private static CallableStatement proc = null;;
     
     
        @Before
        public void before(){
            try {
                Class.forName(driverclass).newInstance(); //加载驱动  
                conn=DriverManager.getConnection(url,username,password); //获得连接
                stmt=conn.createStatement();  
            } catch (Exception e) {
                e.printStackTrace();
            }
             
        }
         
        @After
        public void after(){
            try {
                if(conn != null){
                    conn.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                if(stmt != null){
                    stmt.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                if(rs != null){
                    rs.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
             
        }
         
        /**
         * 测试调用存储过程用时
         * @throws SQLException 
         */
        @Test
        public void getDateByMethod(){
             
            int pre = (int) System.currentTimeMillis();
             
            try {
           // 调用存储过程,问号个数代表参数存储过程的个数,且顺序要一一对应 proc
    = conn.prepareCall("{ call serachUserMethod(?,?) }");
           // 传值 proc.setString(
    1, "AAAFB7E4B4D14475AD994310EF62EBA7");
           // 注册返回值 proc.registerOutParameter(
    2, Types.VARCHAR);
           // 提交 proc.execute();
           // 取出返回值 System.out.println(proc.getString(
    2)); } catch (SQLException e) { e.printStackTrace(); } finally {
            proc.close();
         } 
             
            int post=(int) System.currentTimeMillis();
             
            System.out.println("测试调用存储过程用时"+(post-pre));
        }
         
    }

      注意,这里的proc.getString(2)中的数值2并非任意的,而是和存储过程中的 参数 列对应的,如果out是在第一个位置,那就是proc.getString(1),如果是第三个位置,就是proc.getString(3),当然也可以同时有多个返回值,那就是再多加几个out参数了。

    【返回列表的存储过程】

      通过上面的例子,返回普通的int ,Stirng 类型的参数还是没问题的,可是这永远不能满足需求,我们一般要的是返回数据库里一个表的所有属性?当然可以。

    第一步:建包(游标)。

      存储过程是不能直接返回一个对象(这个对象有N个属性)的,但它有另外一种方式,通过建立一个”指针“一样的”游标“ 指向某些数据,最后返回这个 ”游标“ ,我们就能顺着这个游标拿到我们想要的数据了。

    create or replace package testpackage as    
    type Test_CURSOR is ref cursor;   
    end testpackage; 

    第二步:创建存储过程。

      注意:返回参数的类型为我们刚刚建立的 ”游标“ 类型

    create or replace procedure testc(p_cursor out testpackage.Test_CURSOR)   
    is   
    begin    
    open p_cursor for select * from T_AP_ZA_LYT_GNLK;   
    end  testc;  

    第三步:java代码:

    package com.zjm.www.test;
     
    import java.sql.CallableStatement;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.sql.Types;
    import java.util.Date;
     
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
     
    public class test {
         
        private static String driverclass="oracle.jdbc.driver.OracleDriver";  
        // 本地
        private static String url="jdbc:oracle:thin:@localhost:1521:orcl";  
        private static String username="test";  
        private static String password="Aaa38324836";  
     
        private static String sql="";     // 记得表名要用""括起来
        private static Connection conn = null;
        private static Statement stmt = null;
        private static ResultSet rs = null;
        private static CallableStatement proc = null;;
     
     
        @Before
        public void before(){
            try {
                Class.forName(driverclass).newInstance(); //加载驱动  
                conn=DriverManager.getConnection(url,username,password); //获得连接
                stmt=conn.createStatement();  
            } catch (Exception e) {
                e.printStackTrace();
            }
             
        }
         
        @After
        public void after(){
            try {
                if(conn != null){
                    conn.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                if(stmt != null){
                    stmt.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                if(rs != null){
                    rs.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
             
        }
        @Test
        public void getDateByMethod2(){
            int pre = (int) System.currentTimeMillis();
             
            try {
                proc = conn.prepareCall("{ call testc(?) }");
           // 注册返回值参数,注意是游标类型 proc.registerOutParameter(
    1,oracle.jdbc.OracleTypes.CURSOR); proc.execute();
           // 返回的数据存储在一个ResultSet里面 ResultSet rs
    = (ResultSet)proc.getObject(1); while(rs.next()) {
                  // getString(...)里面填的对应数据库 表 的字段名 System.out.println(
    "<tr><td>" + rs.getString("id") + "</td><td>"+rs.getString("name")+"</td></tr>"); } proc.close(); } catch (SQLException e) { e.printStackTrace(); } int post=(int) System.currentTimeMillis(); System.out.println("测试调用存储过程用时"+(post-pre)); } }
  • 相关阅读:
    path.join()和path.resolve()
    __dirname和__filename
    使用css-loader
    博客主题
    Python使用pandas库读取txt文件中的Json数据,并导出到csv文件
    为什么一个星期工作量的工作,我做了一个多月,还没结束 (基于socket的分布式数据处理程序Java版)
    Docker 命令
    Python使用pandas库读取csv文件,并分组统计的一个例子
    Linux 进程守护脚本
    Linux 安装 JDK
  • 原文地址:https://www.cnblogs.com/xiaoMzjm/p/3884948.html
Copyright © 2011-2022 走看看