Java代码调用Oracle的存储过程,存储函数和包

简介:

 Java代码调用存储过程和存储函数要使用CallableStatement接口

查看API文档:

 

上代码:

java代码调用如下的存储过程和函数:

查询某个员工的姓名  月薪 职位

复制代码
1 create or replace procedure queryEmpinfo(eno in number,
2                                          pename out varchar2,
3                                          psal   out number,
4                                          pjob   out varchar2)
5 as
6 begin
7   select ename,sal,empjob into pename,psal,pjob from emp where empno=eno;
8 end;
复制代码

 

 

复制代码
 1 --查询某个员工的年收入
 2 create or replace function queryEmpIncome(eno in number)
 3 return number
 4 as
 5    psal emp.sal%type;
 6    pcomm emp.comm%type;
 7 begin
 8    select sal,comm into psal,pcomm from emp where empno=eno;
 9 
10    --返回年收入
11    return psal*12+nvl(pcomm,0);
12 
13 end;
复制代码

 

 

复制代码
 1 --在out参数中使用光标
 2 查询某个部门中所有员工的所有信息
 3 
 4 
 5 包头
 6 CREATE OR REPLACE PACKAGE MYPACKAGE AS 
 7 
 8   type empcursor is ref cursor;
 9   procedure queryEmpList(dno in number,empList out empcursor);
10 
11 END MYPACKAGE;
12 
13 
14 包体
15 CREATE OR REPLACE
16 PACKAGE BODY MYPACKAGE AS
17 
18   procedure queryEmpList(dno in number,empList out empcursor) AS
19   BEGIN
20     open empList for select * from emp where deptno=dno;
21   END queryEmpList;
22 
23 END MYPACKAGE;
复制代码

 

 

复制代码
  1 import java.sql.CallableStatement;
  2 import java.sql.Connection;
  3 import java.sql.ResultSet;
  4 import java.sql.SQLException;
  5 
  6 import oracle.jdbc.driver.OracleCallableStatement;
  7 import oracle.jdbc.driver.OracleTypes;
  8 
  9 import org.junit.Test;
 10 
 11 public class TestOracle {
 12     
 13     /*
 14      * CallableStatement 接口
 15      *     调用存储函数,等号左边有一个返回值
 16      *    {?= call <procedure-name>[(<arg1>,<arg2>, ...)]}
 17      *  调用存储过程. 没有返回值 
 18              {call <procedure-name>[(<arg1>,<arg2>, ...)]}
 19 
 20      * 
 21      */
 22     
 23     /*存储过程 查询某个员工的姓名  月薪 职位
 24      * create or replace procedure queryEmpinfo(eno in number,
 25                                              pename out varchar2,
 26                                              psal   out number,
 27                                              pjob   out varchar2)
 28      */    
 29     
 30     @Test
 31     public void testProcedure(){
 32         //{call <procedure-name>[(<arg1>,<arg2>,...)]}
 33         String sql = "{call queryEmpinfo(?,?,?,?)}";//4个问号中,第一个是输入参数,其余是输出参数
 34         Connection conn = null;
 35         //要用CallableStatement这个接口,用于执行 SQL 存储过程的接口
 36         CallableStatement call = null;
 37         
 38         try {
 39             conn = JDBCUtils.getConnection();
 40             call = conn.prepareCall(sql);
 41             //对于in参数,需要赋值
 42             call.setInt(1,7839);
 43             //对于out参数,需要声明
 44             call.registerOutParameter(2, OracleTypes.VARCHAR);//第二个是字符串
 45             call.registerOutParameter(3, OracleTypes.NUMBER);//第三个是数字
 46             call.registerOutParameter(4, OracleTypes.VARCHAR);//第四个是字符串
 47             
 48             call.execute();
 49             //取出结果
 50             String name = call.getString(2);
 51             double sal = call.getDouble(3);
 52             String job = call.getString(4);
 53             System.out.println(name+"\t"+sal+"\t"+job+"\t");
 54         } catch (SQLException e) {
 55             e.printStackTrace();
 56         }finally{
 57             JDBCUtils.release(conn, call, null);//没有最后一个参数就传入null
 58         }
 59     }
 60 
 61     /*存储函数  查询某个员工的姓名,月薪和职位
 62      * create or replace function queryEmpIncome(eno in number)
 63         return number
 64      */    
 65     @Test
 66     public void testFunction(){
 67         //{?= call <procedure-name>[(<arg1>,<arg2>, ...)]}
 68         //第一个问号是函数的返回值,第二个问号是输入参数.  返回值的作用和输出参数是一样的.
 69         String sql = "{?=call QUERYEMPINCOME(?)}";//这个call后面的存储过程名或者是存储函数名大写或者是小写是没有要求的.
 70         Connection conn = null;
 71         //要用CallableStatement这个接口,用于执行 SQL 存储过程的接口
 72         CallableStatement call = null;
 73         
 74         try {
 75             conn = JDBCUtils.getConnection();
 76             call = conn.prepareCall(sql);
 77             
 78             //对于in参数,赋值
 79             call.setInt(2,7839);
 80             
 81             //对于out参数,申明
 82             call.registerOutParameter(1, OracleTypes.NUMBER);
 83             call.execute();
 84             //取出结果
 85             //取出结果
 86             double income = call.getDouble(1);
 87             System.out.println(income);
 88         } catch (SQLException e) {
 89             e.printStackTrace();
 90         }finally{
 91             JDBCUtils.release(conn, call, null);//没有最后一个参数就传入null
 92         }
 93         
 94         
 95     }
 96     
 97     /*
 98         查询某个部门中所有员工的所有信息
 99         包头
100         CREATE OR REPLACE PACKAGE MYPACKAGE AS 
101         
102           type empcursor is ref cursor;
103           procedure queryEmpList(dno in number,empList out empcursor);
104         
105         END MYPACKAGE;
106         
107         
108         包体
109         CREATE OR REPLACE
110         PACKAGE BODY MYPACKAGE AS
111         
112           procedure queryEmpList(dno in number,empList out empcursor) AS
113           BEGIN
114             open empList for select * from emp where deptno=dno;
115           END queryEmpList;
116         
117         END MYPACKAGE;    
118      */
119     @Test
120     public void testCursor(){
121         //{call <procedure-name>[(<arg1>,<arg2>, ...)]}
122         String sql = "{call MYPACKAGE.queryEmpList(?,?)}";
123         
124         Connection conn = null;
125         CallableStatement call = null;
126         //有游标,就有结果集
127         ResultSet rest = null;
128         try {
129             conn = JDBCUtils.getConnection();
130             call = conn.prepareCall(sql);
131             
132             //对于in参数,赋值
133             call.setInt(1, 20);
134             
135             //对于out参数,申明
136             call.registerOutParameter(2, OracleTypes.CURSOR);
137             call.execute();        
138             //取出集合
139             //这个地方要强转!!!OracleCallableStatement是抽象类,继承了CallableStatement
140             //不强转没有getCursor()方法...
141             rest = ((OracleCallableStatement)call).getCursor(2);
142             while(rest.next()){
143                 String name = rest.getString("ename");
144                 double sal = rest.getDouble("sal");
145                 System.out.println(name+"\t"+sal);
146             }
147         }catch (Exception e) {
148             e.printStackTrace();
149         }finally{
150             JDBCUtils.release(conn, call, rest);//上面打开了光标,再这个地方关闭结果集rest,也就关闭了光标
151         }
152     }
153 }
复制代码

 

关于Oracle中的包对象:

之前的存储函数中查询的是某一个员工的信息:

复制代码
1 create or replace procedure queryEmpinfo(eno in number,
2                                          pename out varchar2,
3                                          psal   out number,
4                                          pjob   out varchar2)
5 as
6 begin
7   select ename,sal,empjob into pename,psal,pjob from emp where empno=eno;
8 end;
复制代码

但是①如果要查询一个员工的所有信息,而这个员工的信息对应的有几百列

在存储函数中括号的函数要把这几百列都声明出来?

②如果要查询某个部门中所有员工的所有信息...这个信息对应的是一个集合.

第二个问题解决了第一个问题也就解决了.

怎么在存储过程或者存储函数中返回一个集合.

学到现在有多少种方式可以代表一个集合?

第一个是表,第二个是select语句也可以.第三个是光标.

在out参数中使用光标.但是有一个要求,必须要声明一个包,包分为包头和包体.也是数据库的对象.跟表,视图,等是一样的是数据库的对象.

包头只负责声明,包体只负责实现.

复制代码
 1 --在out参数中使用光标
 2 查询某个部门中所有员工的所有信息
 3 
 4 
 5 包头
 6 CREATE OR REPLACE PACKAGE MYPACKAGE AS 
 7 
 8   type empcursor is ref cursor;
 9   procedure queryEmpList(dno in number,empList out empcursor);
10 
11 END MYPACKAGE;
12 
13 
14 包体
15 CREATE OR REPLACE
16 PACKAGE BODY MYPACKAGE AS
17 
18   procedure queryEmpList(dno in number,empList out empcursor) AS
19   BEGIN
20     open empList for select * from emp where deptno=dno;
21   END queryEmpList;
22 
23 END MYPACKAGE;
复制代码

 

分析图:

参看包:

包无法在plsqldeveloper和sqldeveloper等工具中右键运行....必须通过java代码应用程序来调用执行(代码在上面)

 


本文转自SummerChill博客园博客,原文链接:http://www.cnblogs.com/DreamDrive/p/6239021.html,如需转载请自行联系原作者

相关文章
|
10月前
|
Java 开发工具
【Azure Storage Account】Java Code访问Storage Account File Share的上传和下载代码示例
本文介绍如何使用Java通过azure-storage-file-share SDK实现Azure文件共享的上传下载。包含依赖引入、客户端创建及完整示例代码,助你快速集成Azure File Share功能。
639 6
|
11月前
|
IDE Java 关系型数据库
Java 初学者学习路线(含代码示例)
本教程为Java初学者设计,涵盖基础语法、面向对象、集合、异常处理、文件操作、多线程、JDBC、Servlet及MyBatis等内容,每阶段配核心代码示例,强调动手实践,助你循序渐进掌握Java编程。
1335 3
|
11月前
|
安全 Java 应用服务中间件
Spring Boot + Java 21:内存减少 60%,启动速度提高 30% — 零代码
通过调整三个JVM和Spring Boot配置开关,无需重写代码即可显著优化Java应用性能:内存减少60%,启动速度提升30%。适用于所有在JVM上运行API的生产团队,低成本实现高效能。
1203 3
|
11月前
|
Java API 开发工具
【Azure Developer】Java代码实现获取Azure 资源的指标数据却报错 "invalid time interval input"
在使用 Java 调用虚拟机 API 获取指标数据时,因本地时区设置非 UTC,导致时间格式解析错误。解决方法是在代码中手动指定时区为 UTC,使用 `ZoneOffset.ofHours(0)` 并结合 `withOffsetSameInstant` 方法进行时区转换,从而避免因时区差异引发的时间格式问题。
452 4
|
Java 数据安全/隐私保护
快手小红书抖音留痕工具,自动留痕插件工具,java代码开源
这个框架包含三个核心模块:主操作类处理点赞评论、配置管理类和代理管理类。使用时需要配合
|
12月前
|
人工智能 监控 安全
智慧工地解决方案,java智慧工地程序代码
智慧工地系统融合物联网、AI、大数据等技术,实现对施工现场“人、机、料、法、环”的全面智能监控与管理,提升安全、效率与决策水平。
341 2
|
11月前
|
Java
java入门代码示例
本文介绍Java入门基础,包含Hello World、变量类型、条件判断、循环及方法定义等核心语法示例,帮助初学者快速掌握Java编程基本结构与逻辑。
760 0
|
10月前
|
Java 数据处理 API
为什么你的Java代码应该多用Stream?从循环到声明式的思维转变
为什么你的Java代码应该多用Stream?从循环到声明式的思维转变
422 115
|
10月前
|
安全 Java 编译器
为什么你的Java代码需要泛型?类型安全的艺术
为什么你的Java代码需要泛型?类型安全的艺术
320 98

推荐镜像

更多