Java调用Oracle存储过程一

2024-09-08 03:32
文章标签 java oracle 过程 调用 存储

本文主要是介绍Java调用Oracle存储过程一,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、通过PL/SQL工具连接上Oracle数据库,创建表zx_test_procedure



二、创建存储过程

①无返回值的存储过程
存储过程为:
create or replace procedure testa
(para1 in varchar2,para2 in varchar2) as
begin
insert into zx_test_procedure(i_id,i_name) values(para1,para2);
end testa;


Java调用的代码:

import java.sql.*;public class TestProcedureOne {public TestProcedureOne() {}public static void main(String[] args ){String driver = "oracle.jdbc.driver.OracleDriver";String strUrl = "jdbc:oracle:thin:@10.10.1.29:1521:testdb";Statement stmt = null;ResultSet rs = null;Connection conn = null;//CallableStatement cstmt = null;try {Class.forName(driver);conn = DriverManager.getConnection(strUrl, "neb", "testneb");CallableStatement proc = null; //创建执行存储过程的对象proc = conn.prepareCall("{call TESTA(?,?) }"); //设置存储过程 call为关键字.proc.setString(1, "400"); //设置第一个输入参数proc.setString(2, "TestFour");//设置第二个输入参数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) {}}}
}
结果如下:


②有返回值的存储过程(非列表)

存储过程为:

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


Java调用代码如下:

import java.sql.*;public class TestProcedureTwo {public TestProcedureTwo() {}public static void main(String[] args ){String driver = "oracle.jdbc.driver.OracleDriver";String strUrl = "jdbc:oracle:thin:@10.10.1.29:1521:testdb";Statement stmt = null;ResultSet rs = null;Connection conn = null;//CallableStatement cstmt = null;try {Class.forName(driver);conn = DriverManager.getConnection(strUrl, "neb", "testneb");CallableStatement proc = null; //创建执行存储过程的对象proc = conn.prepareCall("{call TESTB(?,?) }"); //设置存储过程 call为关键字.proc.setString(1, "300"); //设置第一个输入参数proc.registerOutParameter(2, Types.VARCHAR); //第二个参数输出参数,是varchar类型的proc.execute();//执行String test = proc.getString(2);//获得输出参数System.out.println(test);}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) {}}}
}

结果如下:

TestThree

注意,这里的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 zx_test_procedure; 
end testc;
可以看到,它是把游标(可以理解为一个指针),作为一个out 参数来返回值的。

Java调用代码:
import java.sql.*;public class TestProcedureThree {public TestProcedureThree() {}public static void main(String[] args ){String driver = "oracle.jdbc.driver.OracleDriver";String strUrl = "jdbc:oracle:thin:@10.10.1.29:1521:testdb";Statement stmt = null;ResultSet rs = null;Connection conn = null;//CallableStatement cstmt = null;try {Class.forName(driver);conn = DriverManager.getConnection(strUrl, "neb", "testneb");CallableStatement proc = null; //创建执行存储过程的对象proc = conn.prepareCall("{call TESTC(?) }"); //设置存储过程 call为关键字.//设置输出参数是一个游标.第一个参数,游标类型proc.registerOutParameter(1, oracle.jdbc.OracleTypes.CURSOR);proc.execute();rs = (ResultSet) proc.getObject(1);while(rs.next()) {System.out.println(rs.getString(1) + ",,," + rs.getString(2));}}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) {}}}
}
结果如下:
100,,,TestOne
200,,,TestTwo
300,,,TestThree
400,,,TestFour


参考资料:

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;
  ...

关于oracle存储过程的若干问题备忘

1.在oracle中,数据表别名不能加as,如:
select a.appname  from appinfo a; -- 正确
select a.appname  from appinfo  as a; -- 错误
 也许,是怕和oracle中的存储过程中的关键字as冲突的问题吧
2.在存储过程中,select某一字段时,后面必须紧跟into,如果select整个记录,利用游标的话就另当别论了。
   select af.keynode  into kn  from APPFOUNDATION af  where af.appid =aid  and af.foundationid =fid; --  有into,正确编译
   select af.keynode  from APPFOUNDATION af  where af.appid =aid  and af.foundationid =fid; --  没有into,编译报错,提示:Compilation 
  Error: PLS - 00428: an  INTO clause  is expected  in this  SELECT statement

3.在利用select...into...语法时,必须先确保数据库中有该条记录,否则会报出"no data found"异常。
可以在该语法之前,先利用 select count(*) from 查看数据库中是否存在该记录,如果存在,再利用select...into...
4.在存储过程中,别名不能和字段名称相同,否则虽然编译可以通过,但在运行阶段会报错
  select keynode  into kn  from APPFOUNDATION  where appid =aid  and foundationid =fid; --  正确运行
select af.keynode  into kn  from APPFOUNDATION af  where  af.appid = appid  and  af.foundationid = foundationid; --  运行阶段报错,提示
ORA - 01422:exact  fetch  returns more than requested  number  of rows
5.在存储过程中,关于出现null的问题
假设有一个表A,定义如下:
create  table A(
id  varchar2( 50primary  key  not  null,
vcount  number( 8not  null,
bid  varchar2( 50not  null  --  外键 
);
如果在存储过程中,使用如下语句:
select sum(vcount) into fcount from A  where bid='xxxxxx';
如果A表中不存在bid="xxxxxx"的记录,则fcount=null(即使fcount定义时设置了默认值,如:fcount number(8):=0依然无效,fcount还是会变成null),这样以后使用fcount时就可能有问题,所以在这里最好先判断一下:
if fcount  is  null then
    fcount:=0;
end  if;
这样就一切ok了。
6.Hibernate调用oracle存储过程
         this.pnumberManager.getHibernateTemplate().execute(
                 new HibernateCallback()  ... {
                    public Object doInHibernate(Session session)
                            throws HibernateException, SQLException ...{
                        CallableStatement cs = session
                                .connection()
                                .prepareCall("{call modifyapppnumber_remain(?)}");
                        cs.setString(1, foundationid);
                        cs.execute();
                        return null;
                    }

                }
);



这篇关于Java调用Oracle存储过程一的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1146994

相关文章

Java Spring 中的监听器Listener详解与实战教程

《JavaSpring中的监听器Listener详解与实战教程》Spring提供了多种监听器机制,可以用于监听应用生命周期、会话生命周期和请求处理过程中的事件,:本文主要介绍JavaSprin... 目录一、监听器的作用1.1 应用生命周期管理1.2 会话管理1.3 请求处理监控二、创建监听器2.1 Ser

Redis指南及6.2.x版本安装过程

《Redis指南及6.2.x版本安装过程》Redis是完全开源免费的,遵守BSD协议,是一个高性能(NOSQL)的key-value数据库,Redis是一个开源的使用ANSIC语言编写、支持网络、... 目录概述Redis特点Redis应用场景缓存缓存分布式会话分布式锁社交网络最新列表Redis各版本介绍旧

C/C++和OpenCV实现调用摄像头

《C/C++和OpenCV实现调用摄像头》本文主要介绍了C/C++和OpenCV实现调用摄像头,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录准备工作1. 打开摄像头2. 读取视频帧3. 显示视频帧4. 释放资源5. 获取和设置摄像头属性

JVisualVM之Java性能监控与调优利器详解

《JVisualVM之Java性能监控与调优利器详解》本文将详细介绍JVisualVM的使用方法,并结合实际案例展示如何利用它进行性能调优,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全... 目录1. JVisualVM简介2. JVisualVM的安装与启动2.1 启动JVisualVM2

Java如何从Redis中批量读取数据

《Java如何从Redis中批量读取数据》:本文主要介绍Java如何从Redis中批量读取数据的情况,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一.背景概述二.分析与实现三.发现问题与屡次改进3.1.QPS过高而且波动很大3.2.程序中断,抛异常3.3.内存消

SpringBoot使用ffmpeg实现视频压缩

《SpringBoot使用ffmpeg实现视频压缩》FFmpeg是一个开源的跨平台多媒体处理工具集,用于录制,转换,编辑和流式传输音频和视频,本文将使用ffmpeg实现视频压缩功能,有需要的可以参考... 目录核心功能1.格式转换2.编解码3.音视频处理4.流媒体支持5.滤镜(Filter)安装配置linu

在Spring Boot中实现HTTPS加密通信及常见问题排查

《在SpringBoot中实现HTTPS加密通信及常见问题排查》HTTPS是HTTP的安全版本,通过SSL/TLS协议为通讯提供加密、身份验证和数据完整性保护,下面通过本文给大家介绍在SpringB... 目录一、HTTPS核心原理1.加密流程概述2.加密技术组合二、证书体系详解1、证书类型对比2. 证书获

Java使用MethodHandle来替代反射,提高性能问题

《Java使用MethodHandle来替代反射,提高性能问题》:本文主要介绍Java使用MethodHandle来替代反射,提高性能问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录一、认识MethodHandle1、简介2、使用方式3、与反射的区别二、示例1、基本使用2、(重要)

MySQL 存储引擎 MyISAM详解(最新推荐)

《MySQL存储引擎MyISAM详解(最新推荐)》使用MyISAM存储引擎的表占用空间很小,但是由于使用表级锁定,所以限制了读/写操作的性能,通常用于中小型的Web应用和数据仓库配置中的只读或主要... 目录mysql 5.5 之前默认的存储引擎️‍一、MyISAM 存储引擎的特性️‍二、MyISAM 的主

Java实现本地缓存的常用方案介绍

《Java实现本地缓存的常用方案介绍》本地缓存的代表技术主要有HashMap,GuavaCache,Caffeine和Encahche,这篇文章主要来和大家聊聊java利用这些技术分别实现本地缓存的方... 目录本地缓存实现方式HashMapConcurrentHashMapGuava CacheCaffe