Java调用存储过程返回数组

Java调用存储过程:

结合SQL操作与存储过程

create procedure set_death_age(poet VARCHAR2, poet_age NUMBER)

poet_id NUMBER;

begin SELECT id INTO poet_id FROM poets WHERE name = poet;

INSERT INTO deaths (mort_id, age) VALUES (poet_id, poet_age);

end set_death_age;

下面是调用上面存储过程的Java代码:

public static void setDeathAge(Poet dyingBard, int age) throws SQLException{

Connection con = null;

CallableStatement proc = null;

try {

con = connectionPool.getConnection();

proc = con.prepareCall("{ call set_death_age(?, ?) }");

proc.setString(1, dyingBard.getName());

proc.setInt(2, age);

proc.execute();

}

finally {

try { proc.close(); }

catch (SQLException e) {}

con.close();

}

}

Functions

存储过程可以有返回值,所以CallableStatement类有类似getResultSet这样的方法来获取返回值。当存储过程返回一个值时,你必须使用registerOutParameter方法告诉JDBC驱动器该值的SQL类型是什么。你也必须调整存储过程调用来指示该过程返回一个值。

下面接着上面的例子。这次我们查询Dylan Thomas逝世时的年龄。这次的存储过程使用:

create function snuffed_it_when (VARCHAR) returns integer ‘‘declare

poet_id NUMBER;

poet_age NUMBER;

begin

--first get the id associated with the poet.

SELECT id INTO poet_id FROM poets WHERE name = $1;

--get and return the age.

SELECT age INTO poet_age FROM deaths WHERE mort_id = poet_id;

return age;

end;

下面是调用这个存储过程的Java代码:

connection.setAutoCommit(false);

CallableStatement proc = connection.prepareCall("{ ? = call snuffed_it_when(?) }"); proc.registerOutParameter(1, Types.INTEGER);

proc.setString(2, poetName); cs.execute();

int age = proc.getInt(2);

在使用存储过程中,我们有时需要传递可变数组,存在两种情况,存储过程有输入或输出参数为自定义可变数组的。在java代码中,如何正确调用oracle存储过程的自定义可变数组类型,在这里做一下示例说明.

java调用oracle存储过程的自定义类型:

plsql定义字符串和数值型可变数组:

一.定义全局类型:

CREATE OR REPLACE TYPE USERSEQID_ARRAY IS VARRAY(50000) OF NUMBER(9)

CREATE OR REPLACE TYPE USERNAME_ARRAY  AS VARRAY(32) of varchar(32)

CREATE OR REPLACE TYPE USERPWD_ARRAY  AS VARRAY(50000) of varchar(60)

二.java调用输出参数为自定义数组的存储过程:

2.1 输出参数为自定义数组的存储过程make_logincard_pro:

procedure make_logincard_pro (

p_cardsuitcode in varchar,

p_userseqidArr out USERSEQID_ARRAY ,

p_usernameArr out USERNAME_ARRAY

)

IS

v_addedtime date:= sysdate;

BEGIN

FOR ii IN 1 .. 10 LOOP

IF p_userseqidArr IS NULL THEN

p_userseqidArr := USERSEQID_ARRAY(ii);

ELSE

p_userseqidArr.EXTEND;   --超过数组定义大小(50000)将抛出异常

p_userseqidArr(ii) := ii;

END IF;

IF p_usernameArr IS NULL THEN

p_usernameArr := USERSEQID_ARRAY(ii || ‘TT‘);

ELSE

p_usernameArr.EXTEND;      --超过数组定义大小(32)将抛出异常

p_usernameArr(ii) := ii || ‘TT‘;

END IF;

END LOOP

END make_logincard_pro ;

2.2JAVA调用存储过程make_logincard_pro:

//代码片段

Connection con = session.connection();

java.sql.CallableStatement cst = con

prepareCall("call CNBT.test_pro(?,?,?)");

cst.setString(1, cardSuitCode);

cst.registerOutParameter(2, OracleTypes.ARRAY,"USERSEQID_ARRAY");

cst.registerOutParameter(3, OracleTypes.ARRAY,"USERNAME_ARRAY");

java.sql.Array userSeqIdArr = cst.getArray(2);

java.sql.Array userNameArr = cst.getArray(3);

if ( userSeqIdArr  != null ) ...{

BigDecimal userSeqIdList[] = (BigDecimal[])userSeqIdArr.getArray();//数据库的number映射为BigDecimal

//。。。。。。

}

if ( userNameArr  != null ) ...{

String userNameList[] = (String[])userNameArr.getArray();

//。。。。。。

}

--------------------------------------------------------------------------------

三. java调用输入参数为自定义数组的存储过程:

3.1 输入参数为自定义数组的存储过程update_logincard_pwd:

/**//**********************************************

*          update_logincard_pwd               *

*功能描述:更新密码存储过程         *

*输入参数:                                         *

*输出参数:                                         *

*作者:hanjiong                                    *

***********************************************/

procedure update_logincard_pwd (

p_userSeqIdList in USERSEQID_ARRAY,

p_userPwdList in USERPWD_ARRAY,

p_resultcode out number

);

3.2 java调用存储过程update_logincard_pwd:

//代码片段

..........................

Connection con = session.connection();//使用的weblogic数据源

oracle.jdbc.OracleCallableStatement cst2 = (oracle.jdbc.OracleCallableStatement)con

.prepareCall(

"call CNBT.update_logincard_pwd(?,?,?)");

weblogic.jdbc.wrapper.Connection weblogicConn = (weblogic.jdbc.wrapper.Connection)con;

oracle.jdbc.OracleConnection oracleConn = (oracle.jdbc.OracleConnection)weblogicConn.getVendorConnection();//转化connection

oracle.sql.ArrayDescriptor des_USERSEQID_ARRAY =

oracle.sql.ArrayDescriptor.createDescriptor("USERSEQID_ARRAY",oracleConn);

oracle.sql.ArrayDescriptor des_USERPWD_ARRAY =

oracle.sql.ArrayDescriptor.createDescriptor("USERPWD_ARRAY",oracleConn);

oracle.sql.ARRAY ora_array1 = new oracle.sql.ARRAY(des_USERSEQID_ARRAY, oracleConn, userAccSeqIdArr);

oracle.sql.ARRAY ora_array2 = new oracle.sql.ARRAY(des_USERPWD_ARRAY, oracleConn, userPwdList);

cst2.setArray(1, ora_array1);

cst2.setArray(2, ora_array2);

cst2.registerOutParameter(3, java.sql.Types.INTEGER);

cst2.execute();

updateCode = cst2.getInt(3);

.....................................

....................................

因为我使用的是weblogic配置的数据源,在取得的connection对象时需要注意,通过数据源取得的Connection对象为weblogic.jdbc.wrapper.Connection,所以不能直接转化为oracle.jdbc.OracleConnection,否则会出现java.lang.ClassCastException异常,所以我们要通过weblogic.jdbc.wrapper.Connection.getVendorConnection()取得java.sql.Connection,在强制转化为oracle.jdbc.OracleConnection。

--------------------------------------------------------------------------------

通过上述两种情况,就可以在Oracle存储过程中使用zid

时间: 2024-10-25 21:52:02

Java调用存储过程返回数组的相关文章

java调用存储过程

这段时间开始学习写存储过程,主要原因还是因为工作需要吧,本来以为很简单的,但几经挫折,豪气消磨殆尽,但总算搞通了,为了避免后来者少走弯路,特记述与此,同时亦对自己进行鼓励. 一:无返回值的存储过程 存储过程为: CREATE OR REPLACE PROCEDURE TESTA(PARA1 IN VARCHAR2,PARA2 IN VARCHAR2)  AS BEGIN INSERT INTO HYQ.B_ID (I_ID,I_NAME) VALUES (PARA1, PARA2); END T

”Java 方法可以返回数组类型“ 所想到的

在C和C++中不能返回一个局部变量,因为函数中的局部变量分配的存储空间在栈上,当函数执行完后会被重新利用,所以想要返回数组类型,有两种方式:1)静态变量(static in a function可以在函数调用之间保持值有效),2)利用malloc动态分配,但是最终要记得释放.下面是几个简单测试程序: 1.错误的示例: #include <stdio.h> int *func(int n){ int x = n *n; int a[] = {1,3,4,5,7}; a[0] = x; retur

Java调用存储过程时报 The user specified as a definer (&#39;root&#39;@&#39;%&#39;) does not exist 解决方法

Caused by: java.sql.SQLException: The user specified as a definer (''@'') does not exist        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1075)        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3566)        at com.mysql

Java调用存储过程(有返回值)

1:创建存储过程 此存储过程通过传入的参数(Name),返回一个参数(address). create or replace procedure demo_procedure(namedemo in varchar2,addressdemo out varchar2)asbegin select address into addressdemo from system.demo where name=namedemo;end; 2:Java代码: import java.sql.Callable

【转】java调用存储过程和函数

一.概述 如果想要执行存储过程,我们应该使用 CallableStatement 接口. CallableStatement 接口继承自PreparedStatement 接口.所以CallableStatement 接口包含有Statement 接口和PreparedStatement 接口定义的全部方法,但是并不是所有的方法我们都要使用,主要使用的方法有这样几个: CallableStatement 常用方法: 返回类型 方法签名 说明 boolean execute() 执行 SQL 语句

java调用存储过程mysql

在java中调用带返回值的存储过程的实现 直接上代码: DELIMITER $$ CREATE /*[DEFINER = { user | CURRENT_USER }]*/ PROCEDURE `test`.`text_e`(IN param1 INT ,OUT param2 VARCHAR(20)) /*LANGUAGE SQL | [NOT] DETERMINISTIC | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DA

mybatis 调用存储过程 返回游标 实例

存储过程示例: create or replace procedure Fsp_Plan_CheckPrj(v_grantno varchar2, v_deptcode number, v_cursor out sys_refcursor) is ……………… ---返回统计结果 open v_Cursor for select s.plan_code, s.plan_dept, s.plan_amount, s.exec_amount, p.cname as plan_name, d.cnam

java调用存储过程和函数

以对表test进行增,删,改,查进行说明:1.新建表test create table TEST ( TID NUMBER not null, TNAME VARCHAR2(32), TCODE VARCHAR2(32), CREATEDATE DATE )alter table TEST add constraint PK_TEST_ID primary key (TID)2.数据库中存储过程的脚本:create or replace package test_package is proce

Java调用存储过程,你应该好好了解一下

存储过程是指保存在数据库并在数据库端执行的程序.你可以使用特殊的语法在Java类中调用存储过程.在调用时,存储过程的名称及指定的参数通过JDBC连接发送给DBMS,执行存储过程并通过连接(如果有)返回结果. 使用存储过程拥有和使用基于EJB或CORBA这样的应用服务器一样的好处.区别是存储过程可以从很多流行的DBMS中免费使用,而应用服务器大都非常昂贵.这并不只是许可证费用的问题.使用应用服务器所需要花费的管理.编写代码的费用,以及客户程序所增加的复杂性,都可以通过DBMS中的存储过程所整个地替