Замена oracle "OracleTypes.CURSOR" на эквивалент в mysql при использовании функции registerOutParameter

Уважаемый коллектив stackoverflow

Я пытаюсь обновить систему, разработанную в JAVA, от использования Oracle до DB базы данных.

Я дошел до того, что для использования хранимой процедуры в Java-коде используется определенная структура оракула - 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.CURSOR на java.sql.Types.INTEGER без каких-либо результатов.

Вы можете мне помочь?

Примечание. У меня есть следующая информация о переполнении стека, а также в других местах: http://bugs.mysql.com/bug.php?id=17898

1 ответ

MySql, к сожалению, не реализует ref cursors. Однако хранимые процедуры в MySql могут возвращать набор результатов клиенту, см. Эту ссылку: http://dev.mysql.com/doc/refman/5.6/en/faqs-stored-procs.html#qandaitem-B-4- 1-14

<span>B.4.14: Могут ли хранимые процедуры MySQL 5.6 возвращать наборы результатов?</span> Сохраненные процедуры могут, но сохраненные функции не могут. Если вы выполняете обычный SELECT внутри хранимой процедуры, набор результатов возвращается непосредственно клиенту.

Просто запустите обычный SELECT - и результат возвращается клиенту. Resulset - очень похожая концепция для ref cursor в Oracle. Самое существенное различие заключается в том, что в MySql набор результатов полностью извлекается с сервера клиенту и сохраняется в памяти на стороне клиента (в то время как cursors Oracle извлекают строки в кусках). Однако MySql может имитировать это поведение (с некоторыми ограничениями), см. Эту ссылку: http://dev.mysql.com/doc/connector-j/en/connector-j-reference-implementation-notes.html

<span>ResultSet</span> По умолчанию ResultSets полностью извлекаются и сохраняются в памяти. В большинстве случаев это самый эффективный способ работы, и благодаря дизайну сетевого протокола MySQL проще реализовать. Если вы работаете с ResultSets, которые имеют большое количество строк или больших значений, и не могут выделить кучу пространства в вашей JVM для требуемой памяти, вы можете сообщить драйверу передать результаты назад по одной строке за раз.

Чтобы включить эту функцию, создайте экземпляр Statement следующим образом:

stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); stmt.setFetchSize(Integer.MIN_VALUE); </pre> <p> Комбинация набора результатов только для чтения, доступного только для чтения, с размером выборки Integer.MIN_VALUE служит сигналом для драйвера для потоковых результирующих наборов строк за строкой. После этого любые результирующие наборы, созданные с помощью инструкции, будут загружаться по строкам.

Как это работает - пример. Скажем, у нас есть процедура оракула, которую мы хотим перенести на MySql:

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- Результаты-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 );
 }

licensed under cc by-sa 3.0 with attribution.