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

相关文章

在C#中调用Python代码的两种实现方式

《在C#中调用Python代码的两种实现方式》:本文主要介绍在C#中调用Python代码的两种实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#调用python代码的方式1. 使用 Python.NET2. 使用外部进程调用 Python 脚本总结C#调

springboot报错Invalid bound statement (not found)的解决

《springboot报错Invalidboundstatement(notfound)的解决》本文主要介绍了springboot报错Invalidboundstatement(not... 目录一. 问题描述二.解决问题三. 添加配置项 四.其他的解决方案4.1 Mapper 接口与 XML 文件不匹配

MySQL新增字段后Java实体未更新的潜在问题与解决方案

《MySQL新增字段后Java实体未更新的潜在问题与解决方案》在Java+MySQL的开发中,我们通常使用ORM框架来映射数据库表与Java对象,但有时候,数据库表结构变更(如新增字段)后,开发人员可... 目录引言1. 问题背景:数据库与 Java 实体不同步1.1 常见场景1.2 示例代码2. 不同操作

SpringBoot使用OkHttp完成高效网络请求详解

《SpringBoot使用OkHttp完成高效网络请求详解》OkHttp是一个高效的HTTP客户端,支持同步和异步请求,且具备自动处理cookie、缓存和连接池等高级功能,下面我们来看看SpringB... 目录一、OkHttp 简介二、在 Spring Boot 中集成 OkHttp三、封装 OkHttp

JavaScript错误处理避坑指南

《JavaScript错误处理避坑指南》JavaScript错误处理是编程过程中不可避免的部分,它涉及到识别、捕获和响应代码运行时可能出现的问题,本文将详细给大家介绍一下JavaScript错误处理的... 目录一、错误类型:三大“杀手”与应对策略1. 语法错误(SyntaxError)2. 运行时错误(R

SpringBoot如何通过Map实现策略模式

《SpringBoot如何通过Map实现策略模式》策略模式是一种行为设计模式,它允许在运行时选择算法的行为,在Spring框架中,我们可以利用@Resource注解和Map集合来优雅地实现策略模式,这... 目录前言底层机制解析Spring的集合类型自动装配@Resource注解的行为实现原理使用直接使用M

JavaScript Array.from及其相关用法详解(示例演示)

《JavaScriptArray.from及其相关用法详解(示例演示)》Array.from方法是ES6引入的一个静态方法,用于从类数组对象或可迭代对象创建一个新的数组实例,本文将详细介绍Array... 目录一、Array.from 方法概述1. 方法介绍2. 示例演示二、结合实际场景的使用1. 初始化二

Spring Boot 整合 MyBatis 连接数据库及常见问题

《SpringBoot整合MyBatis连接数据库及常见问题》MyBatis是一个优秀的持久层框架,支持定制化SQL、存储过程以及高级映射,下面详细介绍如何在SpringBoot项目中整合My... 目录一、基本配置1. 添加依赖2. 配置数据库连接二、项目结构三、核心组件实现(示例)1. 实体类2. Ma

Java时间轮调度算法的代码实现

《Java时间轮调度算法的代码实现》时间轮是一种高效的定时调度算法,主要用于管理延时任务或周期性任务,它通过一个环形数组(时间轮)和指针来实现,将大量定时任务分摊到固定的时间槽中,极大地降低了时间复杂... 目录1、简述2、时间轮的原理3. 时间轮的实现步骤3.1 定义时间槽3.2 定义时间轮3.3 使用时

Java 中实现异步的多种方式

《Java中实现异步的多种方式》文章介绍了Java中实现异步处理的几种常见方式,每种方式都有其特点和适用场景,通过选择合适的异步处理方式,可以提高程序的性能和可维护性,感兴趣的朋友一起看看吧... 目录1. 线程池(ExecutorService)2. CompletableFuture3. ForkJoi