gpt4 book ai didi

java - 使用 registerOutParameter 函数时将 oracle 的 "OracleTypes.CURSOR"替换为 mysql 中的等效项

转载 作者:行者123 更新时间:2023-11-29 01:59:20 26 4
gpt4 key购买 nike

亲爱的 stackoverflow 社区

我正在尝试将使用 JAVA 开发的系统从使用 oracle DB 升级到 mysql DB。

我已经到了使用存储过程的地步,java 代码使用特定的 oracle 结构 - OracleTypes.CURSOR。请看下面的代码。

private int getUserID(String username) {
int UserID = -1;
CallableStatement cs = null;
ResultSet rs = null;
try {
con = this.getConnection();
cs = con.prepareCall("{call getUserID(?,?)}");
cs.setString(1, username);
cs.registerOutParameter(2, OracleTypes.CURSOR);
cs.execute();
rs = (ResultSet) cs.getObject(2);

if (rs.next()) {
UserID = rs.getInt(1);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
cs.close();
rs.close();
} catch (SQLException ex) {
Logger.getLogger(DBConnector.class.getName()).log(Level.SEVERE, null, ex);
}
closeConnection();
return UserID;
}
}

我想做的是将 OracleTypes.CURSOR 的使用转换为 mysql 友好的方式。我确实读到过可以在较新版本的 mysql 中执行此操作,所以我什至尝试用 java.sql.Types.INTEGER 替换 OracleTypes.CURSOR 但没有任何结果.

你能帮帮我吗?

注意:我在这里有以下关于堆栈溢出和其他地方的信息,比如: http://bugs.mysql.com/bug.php?id=17898

最佳答案

不幸的是,MySql 没有实现ref 游标

但是,MySql 中的存储过程可以将结果集返回给客户端,请参见此链接:http://dev.mysql.com/doc/refman/5.6/en/faqs-stored-procs.html#qandaitem-B-4-1-14

B.4.14: Can MySQL 5.6 stored routines return result sets?
Stored procedures can, but stored functions cannot. If you perform an ordinary SELECT inside a stored procedure, the result set is returned directly to the client.

只需运行一个普通的 SELECT - 结果集就会返回给客户端。

结果集的概念与 Oracle 中的 ref cursor 非常相似。最显着的区别在于,在 MySql 中,结果集完全从服务器检索到客户端,并存储在客户端的内存中(而 Oracle cursors 以 block 的形式检索行)。
但是, MySql 可以模拟此行为(有一些限制),请参阅此链接:http://dev.mysql.com/doc/connector-j/en/connector-j-reference-implementation-notes.html

ResultSet
By default, ResultSets are completely retrieved and stored in memory. In most cases this is the most efficient way to operate, and due to the design of the MySQL network protocol is easier to implement. If you are working with ResultSets that have a large number of rows or large values, and cannot allocate heap space in your JVM for the memory required, you can tell the driver to stream the results back one row at a time.

To enable this functionality, create a Statement instance in the following manner:

stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
java.sql.ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(Integer.MIN_VALUE);

The combination of a forward-only, read-only result set, with a fetch size of Integer.MIN_VALUE serves as a signal to the driver to stream result sets row-by-row. After this, any result sets created with the statement will be retrieved row-by-row.



它是如何工作的 - 一个例子。

假设我们有一个要迁移到 MySql 的 oracle 过程:

create or replace procedure getUserId( p_name varchar2, p_ref OUT sys_refcursor )
is
begin
open p_ref for
select id, username from users
where username = p_name;
end;
/

在 MySql 中,此过程可能如下所示:

delimiter %%
drop procedure if exists getUserId %%
create procedure getUserId( p_name varchar(100) )
begin
SELECT id, username FROM users
WHERE username = p_name;
end;%%
delimiter ;

和 Java 代码 - 基于文档中的示例:http://dev.mysql.com/doc/connector-j/en/connector-j-usagenotes-statements-callable.html#connector-j-examples-retrieving-results-params

      cs = conn.prepareCall("{call getUserID(?)}");
cs.setString(1, "user1");
boolean hasResultSet = cs.execute();
if( hasResultSet ){
rs = cs.getResultSet();
if (rs.next()) {
userId = rs.getInt(1);
}
System.out.println( "Userid = " + userId );
}

关于java - 使用 registerOutParameter 函数时将 oracle 的 "OracleTypes.CURSOR"替换为 mysql 中的等效项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19210871/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com