Spring StoredProcedure调用ORACLE存储过程或函数

Spring StoredProcedure调用ORACLE存储过程或函数废话不说,直接上代码:应用实例//引用方式package.function或package.procedureStoredProceduresp=neworg.springframework.jdbc.object.StoredProcedure(ds,”PACKAGE_NAME.PROCEDURE_NAME”);//调用函数时必须,调用存储过程不要sp.setFun

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

废话不说,直接上代码:

应用实例

//引用方式package.function或package.procedure
StoredProcedure sp = new org.springframework.jdbc.object.StoredProcedure(ds, "PACKAGE_NAME.PROCEDURE_NAME");
//调用函数时必须,调用存储过程不要
sp.setFunction(true);
//设置返回参数名(将来通过此名称获取输出的返回结果),返回参数需在IN参数前定义
//返回类型Types.ARRAY,自定义类型名称(自定义oracle的TYPE必须在package之上定义,可以在schema层次定义,package内不支持,参见下段“无效的名称模式”)
//sp.declareParameter(new SqlOutParameter("result", Types.INTEGER)); //输出INTEGER类型
sp.declareParameter(new SqlOutParameter("result", Types.ARRAY, "NUMBER_ARRAY")); //返回table类型

//设置输入参数
sp.addParameter("p_name", "广州");
//定义返回对象
Map<String, Object> result = null;
//执行。存在ORA04068异常的可能,若发生则再试执行一次。
try{
	result = sp.execute();
}catch(UncategorizedSQLException e){				
	String state = e.getSQLException().getSQLState();
	int code = e.getSQLException().getErrorCode();
	if("72000".equals(state) && code == 4068){ //ORA-04068 detected
		result = sp.execute();
	}else{
		throw e;
	}
}finally{
	
}

//强制转换返回结果,对应oracle.sql.ARRAY
//Integer returnCode = (Integer) result.get("result");
ARRAY r = (ARRAY)result.get("result");
//结果处理
long[] la = null;
try{
	la = r.getLongArray();   //简单获取,复杂的使用Datum获取
	if(la!=null && la.length>0){
		System.out.println(la[0]);
	}else{
		System.out.println("no data");
	}
}catch(Exception e){
	System.out.println("ERROR");
}

关于包失效

当前session处在活动状态,如果此时ORACLE的package在另外一个session中被重新编译,那么当前session再执行其中的procedure就会报包失效,异常STACK见下。

报错后oracle会自动更新此session中的包状态,所以再次执行则会成功,如前文代码所示。

org.springframework.jdbc.UncategorizedSQLException: CallableStatementCallback; uncategorized SQLException for SQL [{? = call PACKAGE_NAME.FUNCTION_NAME(?)}]; SQL state [72000]; error code [4068]; ORA-04068: 已丢弃程序包  的当前状态
ORA-04061:  的当前状态失效
ORA-04061: package body "SCHEMA_NAME.PACKAGE_NAME" 的当前状态失效
ORA-04065: 未执行, 已变更或删除 package body "SCHEMA_NAME.PACKAGE_NAME"
ORA-06508: PL/SQL: 无法找到正在调用 : "SCHEMA_NAME.PACKAGE_NAME" 的程序单元
ORA-06512: 在 "SCHEMA_NAME.PACKAGE_NAME", line 432
ORA-06512: 在 "SCHEMA_NAME.PACKAGE_NAME", line 192
ORA-06512: 在 line 1
; nested exception is java.sql.SQLException: ORA-04068: 已丢弃程序包  的当前状态
ORA-04061:  的当前状态失效
ORA-04061: package body "SCHEMA_NAME.PACKAGE_NAME" 的当前状态失效
ORA-04065: 未执行, 已变更或删除 package body "SCHEMA_NAME.PACKAGE_NAME"
ORA-06508: PL/SQL: 无法找到正在调用 : "SCHEMA_NAME.PACKAGE_NAME" 的程序单元
ORA-06512: 在 "SCHEMA_NAME.PACKAGE_NAME", line 432
ORA-06512: 在 "SCHEMA_NAME.PACKAGE_NAME", line 192
ORA-06512: 在 line 1
	at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.translate(SQLStateSQLExceptionTranslator.java:124)
	at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.translate(SQLErrorCodeSQLExceptionTranslator.java:322)
	at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:952)
	at org.springframework.jdbc.core.JdbcTemplate.call(JdbcTemplate.java:985)
	at org.springframework.jdbc.object.StoredProcedure.execute(StoredProcedure.java:117)

无效的名称模式

当package中使用了自定义array类型时,jdbc调用会出现”无效的名称模式”错误提示。

原因摘自网络:

To my knowledge, the Oracle JDBC driver does not support using the ArrayDescriptor for array data types (varray or nested table) that are defined inside of a package. The same is true for StructDescriptor as well. If you want to use array and object data types, you must define them outside of a package. Then you’ll be able to use the descriptors in your JDBC programs.

As far as I know, you can only create an “ArrayDescriptor” and a “StructDescriptor” for database types.
In other words, types that were created using the CREATE TYPE (DDL) statement.
You cannot create an “ArrayDescriptor” or a “StructDescriptor” for types created in PL/SQL packages

oracle jdbc代码中

ArrayDescriptor.createDescriptor(type, conn);

其中的type只是单独的名字,默认前面是schema,但是不能加package。只有schema级别对象类型是可以的。
解决的办法供参考(1)尝试对package.type建立一个同义词了(2)定义schema级别的对象(自定义类型放在包外)

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/164517.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Win10文件资源管理器右键卡死「建议收藏」

    Win10文件资源管理器右键卡死「建议收藏」Windows10文件资源管理器操作变慢Windows10自动更新太烦人了,尝试了很多中方法也没禁用成功。昨天自动更新以后,今天使用Windows10,发现文件资源管理器打开的时候慢了很多,打开之后里面的文件夹、文件图标要好久才能显示正常。然后想在文件资源管理器里右键某个文件之后,文件资源管理器就卡死了。此时系统其他部分,如网页浏览器,其他功能软件运行正常。这样确定不是系统卡死,而只是文件资源管……

    2025年9月3日
    7
  • 计算机毛利润的函数,毛利率计算公式

    计算机毛利润的函数,毛利率计算公式

    2021年8月16日
    171
  • 球迷 如何在Linux纯命令行玩转谷歌浏览器,边看欧洲杯,边看足球宝贝[通俗易懂]

    球迷 如何在Linux纯命令行玩转谷歌浏览器,边看欧洲杯,边看足球宝贝[通俗易懂]lsp们,如何在Linux命令行,玩转谷歌浏览器,边看欧洲杯,边搜索足球宝贝

    2022年4月30日
    83
  • 2021最新Java零基础自学教程,java从入门到精通

    2021最新Java零基础自学教程,java从入门到精通Java是一门用途广泛的语言,不但可以用来开发网站后台、PC客户端和AndroidAPP,还在数据分析、网络爬虫、云计算领域大显身手。从学术的角度讲,Java是一门面向对象的编程语言,初学者需要花费不少时间来熟悉面向对象的概念、语法和编程思想,有不理解的地方请一定要坚持,多花时间编写代码自然会豁然开朗。只有一步一个脚印,踏踏实实学习,才能从零基础到入门,再到精通。大家在学习的过程中也要多看几套Java教程,不要死啃一本书,这样才能才能博采众长,进步更快。今天分享的也是我在自

    2022年6月20日
    34
  • matlab三维图怎么改变颜色_matlab画复杂函数图像

    matlab三维图怎么改变颜色_matlab画复杂函数图像当我们学习surface命令时,已经看到了三维作图的一些端倪。在matlab中我么可以调用mesh(x,y,z)函数来产生三维图像。首先,我们用z=cos(x)sin(y)在-2pi≤x,y≤2pi内的图像来看看:[x,y]=meshgrid(-2*pi:0.1:2*pi);z=cos(x).*sin(y);mesh(x,y,z),xlabel(‘x’),ylabel(‘y’),zla…

    2022年8月31日
    6
  • java 怎么更新session值_java – 如何更新session.setAttribute(name,value)值,其中名称相同?…「建议收藏」

    java 怎么更新session值_java – 如何更新session.setAttribute(name,value)值,其中名称相同?…「建议收藏」我有一种情况,我需要更新名称保持不变的setAttribute的值.考虑以下情况作为示例–假设我有三个JSP:abc.jsp,xyz.jsp,pqr.jsp.现在首先运行abc.jsp然后控制前进到xyz.jsp&然后转发到pqr.jsp.现在执行pqr.jspt后,再次使用setAttribute中的更新值控制回xyz.jsp.abc.jsp:ArrayListgetSupplyS…

    2022年10月16日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号