2

亲爱的 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 中可以做到这一点,所以我什至尝试替换OracleTypes.CURSORjava.sql.Types.INTEGER没有任何结果。

你能帮助我吗?

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

4

1 回答 1

3

不幸的是,MySql 没有实现ref cursors.

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

B.4.14:MySQL 5.6 存储例程可以返回结果集吗?
存储过程可以,但存储函数不能。如果在存储过程中执行普通的 SELECT,结果集会直接返回给客户端。

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

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

ResultSet
默认情况下,ResultSet 被完全检索并存储在内存中。在大多数情况下这是最有效的操作方式,并且由于 MySQL 网络协议的设计更容易实现。如果您正在使用具有大量行或大值的 ResultSet,并且无法在 JVM 中为所需的内存分配堆空间,您可以告诉驱动程序一次将结果流回一行。

要启用此功能,请按以下方式创建 Statement 实例:

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

只进、只读结果集与 Integer.MIN_VALUE 提取大小的组合用作驱动程序逐行流式传输结果集的信号。在此之后,将逐行检索使用该语句创建的任何结果集。



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

假设我们有一个要迁移到 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-结果参数

      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 );
      }
于 2013-10-06T23:06:39.147 回答