【本文介绍】

熟悉了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));
} }

oracle入门(7)——存储过程的更多相关文章

  1. Oracle入门4-REF Cursor

    Oracle入门4-REF Cursor 转自:http://blog.sina.com.cn/s/blog_55dbebb00100gxsc.html 自:http://blog.csdn.net/ ...

  2. Dapper完美兼容Oracle,执行存储过程,并返回结果集。

    Dapper完美兼容Oracle,执行存储过程,并返回结果集. 这个问题,困扰了我整整两天. 刚刚用到Dapper的时候,感觉非常牛掰.特别是配合.net 4.0新特性dynamic,让我生成泛型集合 ...

  3. Oracle中执行存储过程call和exec区别

    Oracle中执行存储过程call和exec区别 在sqlplus中这两种方法都可以使用: exec pro_name(参数1..); call pro_name(参数1..); 区别: 1. 但是e ...

  4. Oracle job procedure 存储过程定时任务

    Oracle job procedure 存储过程定时任务 oracle job有定时执行的功能,可以在指定的时间点或每天的某个时间点自行执行任务. 一.查询系统中的job,可以查询视图 --相关视图 ...

  5. Oracle dbms_lock.sleep()存储过程使用技巧-场景-分析-实例

    <Oracle dbms_lock.sleep()存储过程使用技巧>-场景-分析-实例 摘要:今天是2014年3月10日,北京,雾霾,下午组织相关部门开会.会议的结尾一名开发工程师找到了我 ...

  6. oracle 中的存储过程

      oracle 中的存储过程 --oracle 中的存储过程, --不带任何参数的 CREATE OR REPLACE PROCEDURE PRO_TEST AS -- AS 和is 没有任何区别 ...

  7. 【转】Oracle job procedure 存储过程定时任务

    原文:Oracle job procedure 存储过程定时任务 oracle job有定时执行的功能,可以在指定的时间点或每天的某个时间点自行执行任务. 一.查询系统中的job,可以查询视图 --相 ...

  8. oracle函数和存储过程有什么区别

    oracle函数和存储过程有什么区别 1. 返回值的区别,函数有1个返回值,而存储过程是通过参数返回的,可以有多个或者没有 2.调用的区别,函数可以在查询语句中直接调用,而存储过程必须单独调用. 函数 ...

  9. Oracle通用分页存储过程的创建与使用

    Oracle通用分页存储过程的创建与使用 1.创建Oracle包的定义.使用 REF CURSOR 数据类型来处理 Oracle 结果集.REF CURSOR 是一个指向 PL/SQL 查询所返回的结 ...

  10. 用sql语句导出oracle中的存储过程和函数

    用sql语句导出oracle中的存储过程和函数: SET echo off ; SET heading off ; SET feedback off ; SPOOL 'C:/PRC.SQL' repl ...

随机推荐

  1. PS中进程状态

    PROCESS STATE CODES       Here are the different values that the s, stat and state output       spec ...

  2. Swing与AWT在事件模型处理上是一致的

    Swing与AWT在事件模型处理上是一致的. Jframe实际上是一堆窗体的叠加. Swing比AWT更加复杂且灵活. 在JDK1.4中,给JFRAME添加Button不可用jf.add(b).而是使 ...

  3. java----EL表达式

     Java Web中的EL(表达式语言)详解 表达式语言(Expression Language)简称EL,它是JSP2.0中引入的一个新内容.通过EL可以简化在JSP开发中对对象的引用,从而规范页面 ...

  4. Web设计的速查卡(转)

    一.排版 1.VisiBone Font Card Download: GIF 2.常用字体表 (HTML) 3.混合字体 (PDF) 二.单元/尺寸 1.Points 和Pixels近似转换表 (H ...

  5. jquery -- 触屏设备touch事件

    几种普及得比较好的触摸事件,你可以在绝大多数现代浏览器中来测试这一事件(必须是触屏设备哦): touchstart:触摸开始的时候触发 touchmove:手指在屏幕上滑动的时候触发 touchend ...

  6. php -- 文件操作(创建、复制、移动、删除)

    创建 文件夹 bool mkdir ( string $pathname [, int $mode = 0777 [, bool $recursive = false [, resource $con ...

  7. 利用QtGraphicalEffects来使得自己的图像显示更加生动

    有兴趣的开发人员能够參阅连接http://doc.qt.io/qt-5/qtgraphicaleffects-qmlmodule.html来深度学习Qt对Graphics方面的处理. 在今天的这篇文章 ...

  8. [转]seajs详解

    [转]seajs详解 SeaJS 是一个遵循commonJS规范的javascript模块加载框架,可以实现javascript的模块化开发和模块化加载(kk:模块可按需加载或全部加载). SeaJS ...

  9. VS2008链接错误fatal error LNK1104: cannot open file '*.obj'

    This particular issue is caused by specifying a dependency to a lib file that had spaces in its path ...

  10. P2483 [SDOI2010]魔法猪学院

    P2483 [SDOI2010]魔法猪学院 摘要 --> 题目描述 iPig在假期来到了传说中的魔法猪学院,开始为期两个月的魔法猪训练.经过了一周理论知识和一周基本魔法的学习之后,iPig对猪世 ...