【本文介绍】

熟悉了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. Datatable添加数据,提示该行已经属于另一个表的解决方法

    一.DataTable.Rows.Add(DataRow.ItemArray); 二.DataTable.ImportRow(DataRow) 三.设置DataTable的tablename,然后.R ...

  2. Java中的阻塞队列(BlockingQueue)

    1. 什么是阻塞队列 阻塞队列(BlockingQueue)是 Java 5 并发新特性中的内容,阻塞队列的接口是 java.util.concurrent.BlockingQueue,它提供了两个附 ...

  3. PHP多进程编程(一)

    虽然PHP 中,多进程用的比较的少.但是毕竟可能是会用到了.我最近就遇到这样一个问题,用户提交几百个url以后,要读出这个url 中的标题. 当然,你不希望用户等待的太久,10s 钟应该给出个答案.但 ...

  4. 模板题 + KMP + 求最小循环节 --- HDU 3746 Cyclic Nacklace

    Cyclic Nacklace Problem's Link: http://acm.hdu.edu.cn/showproblem.php?pid=3746 Mean: 给你一个字符串,让你在后面加尽 ...

  5. javascript -- 事件捕获,事件冒泡

    使用js的时候,当给子元素和父元素定义了相同的事件,比如都定义了onclick事件,单击子元素时,父元素的onclick事件也会被触发.js里称这种事件连续发生的机制为事件冒泡或者事件捕获. 为什么会 ...

  6. ie中自动识别单屏与双屏(js)

    <!DOCTYPE html> <html> <head> <meta name="viewport" content="wid ...

  7. vue-cli打包构建时常见的报错解决方案

    报错1:vue-cli项目本地npm run dev启动后,chrome打开是空白页 解决方案:将config下的index.js中的assetsPublicPath路径都设置为‘/’绝对路径 报错2 ...

  8. PHPExcel IE导出乱码问题

    引用改网站介绍:http://blog.chinaunix.net/uid-22414998-id-113450.html PHPExcel是微软认证的一个PHP操作Excel表格的类库,功能强大,所 ...

  9. iOS开发之--使用storyboard进行跳转

    iOS开发中使用故事板进行开发是非常高效的一种方式,虽然有这样那样的问题,但是不得不承认,使用sb可以在最短的时间内完成整个项目的布局,节约开发者大量的时间,而且便于修改,非常直观,虽然可能不太灵活, ...

  10. Python 正则表达式贪婪模式

    贪婪模式也就是我们使用 .* 匹配任意字符时会尽可能长地向后匹配,如果我们想阻止这种贪婪模式,需要加个问号,尽可能少地匹配,如下例子: In []: import re In []: html = ' ...