Что лучше выбрать среди этих 1.sys_refcursor 2. пользовательских JSON 3. пользовательских типов объектов / записей из процедуры Oracle 12c plsql, Java 8? - PullRequest
1 голос
/ 07 ноября 2019

Я хочу получить данные из базы данных Oracle 12c PL / SQL с помощью операции выбора. У меня есть 3 варианта возврата данных. 1. Использование Sys_RefCursor

Oralce Part

Procedure Get_Data(
  o_Cursor In Out SYS_REFCURSOR,
  i_Row_Id In Number
  )
Is 
Begin
   Open o_Cursor For
    Select * From My_Table Where Row_Id = i_Row_Id;         
End;

Java Part

CallableStatement cs = conn.prepareCall("{call My_Package_Name.Get_Data(?,?)}");
            cs.registerOutParameter(1, OracleTypes.CURSOR);
            cs.setInt(2, data.get("row_id").getAsInt());
            cs.execute();
            rs = (ResultSet)cs.getObject(1);

Но в этом случае я не знаю, как сама процедура Oracle закрывает курсор неявноили нет.

Когда я использую

Close o_cursor

в конце процедуры, это не дает мне желаемого результата.

Использование пользовательского Apex Json, так как я использовал Oracle 12c, он поддерживает формат Json, поэтому я могу вернуть строку resultSet, используя пользовательский Json

Select * Into rt From My_Table t Where t.Row_Id = 1; json.Push('row_id', rt.Row_Id); json.Push('row_name', rt.Row_Name); Return json.to_string();

И читая его как строку в Java

Могу ли я использовать

TYPE CUSTOMER_REC IS RECORD ( CUST_NO NUMBER, CUST_CODE VARCHAR2 (50), CUST_NAME VARCHAR2 (500) );

Возвращая мой выбранный результат, устанавливается в формате CUSTOMER_REC, а в Java читается как

cs.registerOutParameter(1, OracleTypes.STRUCT, "typeName");

Может ли кто-нибудь дать подробное объяснение о каждой части, и какую из них лучше использовать (с точки зрения производительности), и какой подход в этом случае старый? и закрыта ли Sys_RefCursor неявно Oracle Environment?

1 Ответ

4 голосов
/ 07 ноября 2019

Как вы можете убедиться в коде для варианта 1, SYS_REFCURSOR отображается на ResultSet в Java, поэтому курсор закрывается при закрытии ResultSet.

. Обратите внимание, чтоОбъекты ResultSet автоматически закрываются, когда закрывается Statement или когда Statement выполняет другой оператор SQL, и что Statement закрывается, когда закрывается Connection.

Даже дляпул соединений, где вызов connection.close() возвращает соединение с пулом, поэтому физическое соединение остается открытым, вызов close() по-прежнему закрывает все объекты Statement на Connection и, следовательно, также закрывает все объекты ResultSet.

Если ваш код выполняется некоторое время после использования ResultSet, и особенно если ваш код выполняет цикл для обработки нескольких объектов ResultSet, вы всегда должны закрывать объекты ResultSet, как только выс ними покончено, желательно с помощью try-with-resources .

Если соединение закрывается вскоре после использования объекта ResultSet, вы можете положиться на закрытие соединения ResultSetобъекты для вас. Если вы не уверены, закройте их самостоятельно.

Что касается вашего вопроса, вариант 1 лучше. Вариант 2 будет намного медленнее, а вариант 3 - больше работы.

...