用java调用oracle存储过程总结

来源:互联网 发布:charles 修改请求数据 编辑:程序博客网 时间:2024/05/30 23:30
用java调用oracle存储过程总结
网址: http://www.eygle.com/digest/2008/05/java_oracle_procedure.html
1、什么是存储过程。存储过程是数据库服务器端的一段程序,它有两种类型。一种类似于SELECT查询,用于检索数据,检索到的数据能够以数据集的形式返回给客户。另一种类似于INSERT或DELETE查询,它不返回数据,只是执行一个动作。有的服务器允许同一个存储过程既可以返回数据又可以执行动作。
2、什么时候需要用存储过程
  如果服务器定义了存储过程,应当根据需要决定是否要用存储过程。存储过程通常是一些经常要执行的任务,这些任务往往是针对大量的记录而进行的。在服务器上执行存储过程,可以改善应用程序的性能。这是因为:
.服务器往往具有强大的计算能力和速度。
.避免把大量的数据下载到客户端,减少网络上的传输量。
  例如,假设一个应用程序需要计算一个数据,这个数据需要涉及到许多记录。如果不使用存储过程的话,把这些数据下载到客户端,导致网络上的流量剧增。
  不仅如此,客户端可能是一台老掉牙的计算机,它的运算速度很慢。而改用存储过程后,服务器会很快地把数据计算出来,并且只需传递一个数据给客户端,其效率之高是非常明显的。
3、存储过程的参数
  要执行服务器上的存储过程,往往要传递一些参数。这些参数分为四种类型:
  第一种称为输入参数,由客户程序向存储过程传递值。
  第二种称为输出参数,由存储过程向客户程序返回结果。
  第三种称为输入/输出参数,既可以由客户程序向存储过程传递值,也可以由存储过程向客户程序返回结果。
  第四种称为状态参数,由存储过程向客户程序返回错误信息。
  要说明的是,并不是所有的服务器都支持上述四种类型的参数,例如,InterBase就不支持状态参数。
4、oracle 存储过程的基本语法

  1.基本结构

    CREATE OR REPLACEPROCEDURE 存储过程名字
    (
        参数1 IN NUMBER,
        参数2 IN NUMBER
    ) IS
    变量1 INTEGER :=0;
    变量2 DATE;
    BEGIN
    END 存储过程名字


2.SELECT INTO STATEMENT
  将select查询的结果存入到变量中,可以同时将多个列存储多个变量中,必须有一条
  记录,否则抛出异常(如果没有记录抛出NO_DATA_FOUND)
  例子:

      BEGIN
      SELECT col1,col2 into 变量1,变量2 FROM typestruct where xxx;
      EXCEPTION
      WHEN NO_DATA_FOUND THEN
          xxxx;
      END;


一:无返回值的存储过程
存储过程为:

    CREATE OR REPLACE PROCEDURE TESTA(PARA1 IN VARCHAR2,PARA2 IN VARCHAR2) AS
    BEGIN
      INSERT INTO HYQ.B_ID (I_ID,I_NAME) S (PARA1, PARA2);
    END TESTA;

然后呢,在java里调用时就用下面的代码:

    package com.hyq.src;

    import java.sql.*;
    import java.sql.ResultSet;

    public class TestProcedureOne {
    public TestProcedureOne() {
    }
    public static void main(String[] args ){
        String driver = "oracle.jdbc.driver.OracleDriver";
        String strUrl = "jdbc:oracle:thin:@127.0.0.1:1521: hyq ";
        Statement stmt = null;
        ResultSet rs = null;
        Connection conn = null;
        CallableStatement cstmt = null;

        try {
          Class.forName(driver);
          conn = DriverManager.getConnection(strUrl, " hyq ", " hyq ");
          CallableStatement proc = null;
          proc = conn.prepareCall("{ call HYQ.TESTA(?,?) }");
          proc.setString(1, "100");
          proc.setString(2, "TestOne");
          proc.execute();
        }
        catch (SQLException ex2) {
          ex2.printStackTrace();
        }
        catch (Exception ex2) {
          ex2.printStackTrace();
        }
        finally{
          try {
            if(rs != null){
              rs.close();
              if(stmt!=null){
                stmt.close();
              }
              if(conn!=null){
                conn.close();
              }
            }
          }
          catch (SQLException ex1) {
          }
        }
    }
    }

当然了,这就先要求要建张表TESTTB,里面两个字段(I_ID,I_NAME)。

二:有返回值的存储过程(非列表)
存储过程为:

    CREATE OR REPLACE PROCEDURE TESTB(PARA1 IN VARCHAR2,PARA2 OUT VARCHAR2) AS
    BEGIN
      SELECT INTO PARA2 FROM TESTTB WHERE I_ID= PARA1;
    END TESTB;

在java里调用时就用下面的代码:

    package com.hyq.src;

    public class TestProcedureTWO {
    public TestProcedureTWO() {
    }
    public static void main(String[] args ){
        String driver = "oracle.jdbc.driver.OracleDriver";
        String strUrl = "jdbc:oracle:thin:@127.0.0.1:1521:hyq";
        Statement stmt = null;
        ResultSet rs = null;
        Connection conn = null;
        try {
          Class.forName(driver);
          conn = DriverManager.getConnection(strUrl, " hyq ", " hyq ");
          CallableStatement proc = null;
          proc = conn.prepareCall("{ call HYQ.TESTB(?,?) }");
          proc.setString(1, "100");
          proc.registerOutParameter(2, Types.VARCHAR);
          proc.execute();
          String testPrint = proc.getString(2);
          System.out.println("=testPrint=is="+testPrint);
        }
        catch (SQLException ex2) {
          ex2.printStackTrace();
        }
        catch (Exception ex2) {
          ex2.printStackTrace();
        }
        finally{
          try {
            if(rs != null){
              rs.close();
              if(stmt!=null){
                stmt.close();
              }
              if(conn!=null){
                conn.close();
              }
            }
          }
          catch (SQLException ex1) {
          }
        }
    }
    }

    }

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

三:返回列表
由于oracle存储过程没有返回值,它的所有返回值都是通过out参数来替代的,列表同样也不例外,但由于是集合,所以不能用一般的参数,必须要用pagkage了.所以要分两部分,
1, 建一个程序包。如下:

    CREATE OR REPLACE PACKAGE TESTPACKAGE  AS
    TYPE Test_CURSOR IS REF CURSOR;
    end TESTPACKAGE;

2,建立存储过程,存储过程为:

    CREATE OR REPLACE PROCEDURE TESTC(p_CURSOR out TESTPACKAGE.Test_CURSOR) IS
    BEGIN
        OPEN p_CURSOR FOR SELECT * FROM HYQ.TESTTB;
    END TESTC;

可以看到,它是把游标(可以理解为一个指针),作为一个out 参数来返回值的。
在java里调用时就用下面的代码:

    package com.hyq.src;
    import java.sql.*;
    import java.io.OutputStream;
    import java.io.Writer;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import oracle.jdbc.driver.*;


    public class TestProcedureTHREE {
    public TestProcedureTHREE() {
    }
    public static void main(String[] args ){
        String driver = "oracle.jdbc.driver.OracleDriver";
        String strUrl = "jdbc:oracle:thin:@127.0.0.1:1521:hyq";
        Statement stmt = null;
        ResultSet rs = null;
        Connection conn = null;

        try {
          Class.forName(driver);
          conn = DriverManager.getConnection(strUrl, "hyq", "hyq");

          CallableStatement proc = null;
          proc = conn.prepareCall("{ call hyq.testc(?) }");
          proc.registerOutParameter(1,oracle.jdbc.OracleTypes.CURSOR);
          proc.execute();
          rs = (ResultSet)proc.getObject(1);

          while(rs.next())
          {
              System.out.println("<tr><td>" + rs.getString(1) + "</td><td>"+rs.getString(2)+"</td></tr>");
          }
        }
        catch (SQLException ex2) {
          ex2.printStackTrace();
        }
        catch (Exception ex2) {
          ex2.printStackTrace();
        }
        finally{
          try {
            if(rs != null){
              rs.close();
              if(stmt!=null){
                stmt.close();
              }
              if(conn!=null){
                conn.close();
              }
            }
          }
          catch (SQLException ex1) {
          }
        }
    }
    }

在这里要注意,在执行前一定要先把oracle的驱动包放到class路径里,否则会报错。
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 庭院竹子黄叶子怎么办 水培竹子水发臭怎么办 没生根的富贵竹怎么办 床垫气味太重怎么办 艾灸后经期延长怎么办 花叶上长白点怎么办 经期20天不止怎么办 尤加利叶尖干了怎么办 水培竹子根发黄怎么办 水培的竹子发黄怎么办 鱼缸水草长黑毛怎么办 水草上长黑毛怎么办 鱼缸的水草长毛怎么办 鱼缸水草长白毛怎么办 被狐狸咬了怎么办 经常咳嗽有痰怎么办 嗓子痒经常咳嗽怎么办 冬季咳嗽老不好怎么办 孩子得喉炎咳嗽怎么办 夏天嗓子痒咳嗽怎么办 大人咳嗽老不好怎么办 孩子过敏咳嗽怎么办啊 过敏导致的咳嗽怎么办 奶水多营养不足怎么办 水培富贵竹叶尖发黄怎么办 水培富贵竹干尖怎么办 富贵竹叶子变黄了怎么办 富贵竹叶子变黄怎么办 富贵竹的叶子黄了怎么办 土栽富贵竹发黄怎么办 富贵竹的黄叶子怎么办 土培富贵竹发黄怎么办 富贵竹根变黄了怎么办 富贵竹叶子尖发黄怎么办 富贵竹新叶子发黄怎么办 富贵竹杆变黄了怎么办 水培观音竹叶子发黄怎么办 富贵竹叶子根部发黄怎么办 观音竹叶子干了怎么办 富贵竹叶子发干怎么办 观音竹老叶发黄怎么办