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

相关文章

IDEA运行spring项目时,控制台未出现的解决方案

《IDEA运行spring项目时,控制台未出现的解决方案》文章总结了在使用IDEA运行代码时,控制台未出现的问题和解决方案,问题可能是由于点击图标或重启IDEA后控制台仍未显示,解决方案提供了解决方法... 目录问题分析解决方案总结问题js使用IDEA,点击运行按钮,运行结束,但控制台未出现http://

解决Spring运行时报错:Consider defining a bean of type ‘xxx.xxx.xxx.Xxx‘ in your configuration

《解决Spring运行时报错:Considerdefiningabeanoftype‘xxx.xxx.xxx.Xxx‘inyourconfiguration》该文章主要讲述了在使用S... 目录问题分析解决方案总结问题Description:Parameter 0 of constructor in x

解决IDEA使用springBoot创建项目,lombok标注实体类后编译无报错,但是运行时报错问题

《解决IDEA使用springBoot创建项目,lombok标注实体类后编译无报错,但是运行时报错问题》文章详细描述了在使用lombok的@Data注解标注实体类时遇到编译无误但运行时报错的问题,分析... 目录问题分析问题解决方案步骤一步骤二步骤三总结问题使用lombok注解@Data标注实体类,编译时

JSON字符串转成java的Map对象详细步骤

《JSON字符串转成java的Map对象详细步骤》:本文主要介绍如何将JSON字符串转换为Java对象的步骤,包括定义Element类、使用Jackson库解析JSON和添加依赖,文中通过代码介绍... 目录步骤 1: 定义 Element 类步骤 2: 使用 Jackson 库解析 jsON步骤 3: 添

Java中注解与元数据示例详解

《Java中注解与元数据示例详解》Java注解和元数据是编程中重要的概念,用于描述程序元素的属性和用途,:本文主要介绍Java中注解与元数据的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参... 目录一、引言二、元数据的概念2.1 定义2.2 作用三、Java 注解的基础3.1 注解的定义3.2 内

Java中使用Java Mail实现邮件服务功能示例

《Java中使用JavaMail实现邮件服务功能示例》:本文主要介绍Java中使用JavaMail实现邮件服务功能的相关资料,文章还提供了一个发送邮件的示例代码,包括创建参数类、邮件类和执行结... 目录前言一、历史背景二编程、pom依赖三、API说明(一)Session (会话)(二)Message编程客

Java中List转Map的几种具体实现方式和特点

《Java中List转Map的几种具体实现方式和特点》:本文主要介绍几种常用的List转Map的方式,包括使用for循环遍历、Java8StreamAPI、ApacheCommonsCollect... 目录前言1、使用for循环遍历:2、Java8 Stream API:3、Apache Commons

C++中使用vector存储并遍历数据的基本步骤

《C++中使用vector存储并遍历数据的基本步骤》C++标准模板库(STL)提供了多种容器类型,包括顺序容器、关联容器、无序关联容器和容器适配器,每种容器都有其特定的用途和特性,:本文主要介绍C... 目录(1)容器及简要描述‌php顺序容器‌‌关联容器‌‌无序关联容器‌(基于哈希表):‌容器适配器‌:(

JavaScript中的isTrusted属性及其应用场景详解

《JavaScript中的isTrusted属性及其应用场景详解》在现代Web开发中,JavaScript是构建交互式应用的核心语言,随着前端技术的不断发展,开发者需要处理越来越多的复杂场景,例如事件... 目录引言一、问题背景二、isTrusted 属性的来源与作用1. isTrusted 的定义2. 为

Java循环创建对象内存溢出的解决方法

《Java循环创建对象内存溢出的解决方法》在Java中,如果在循环中不当地创建大量对象而不及时释放内存,很容易导致内存溢出(OutOfMemoryError),所以本文给大家介绍了Java循环创建对象... 目录问题1. 解决方案2. 示例代码2.1 原始版本(可能导致内存溢出)2.2 修改后的版本问题在