Выполнение анонимного блока pl / sql и получение набора результатов в java

Я хотел бы выполнить анонимный PL / SQL и получить объект resultset. Я получил код, который можно сделать, используя курсоры внутри блока PL / SQL.

Но сам блок PL / SQL будет поступать из базы данных в виде текста. Поэтому я не могу редактировать этот блок PL / SQL. И он вернет только два значения, имена столбцов которых будут одинаковыми всегда. Он вернет список из двух значений комбинации столбцов.

Здесь я даю образец PL / SQL.

BEGIN RETURN 'select distinct fundname d, fundname r from  where condition order by 1'; EXCEPTION WHEN OTHERS THEN RETURN 'SELECT ''Not Available'' d, ''Not Available'' r FROM dual'; END;

Любой ответ будет настолько полезен.

Ниже приведен собственный пример того, как «выполнить анонимный PL / SQL и получить объект набора результатов»,

 import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Types; import oracle.jdbc.OracleTypes; public class CallPLSQLBlockWithOneInputStringAndOneOutputStringParameterAndOneOutputCursorParameter { public static void main(String[] args) throws Exception { DriverManager.registerDriver(new oracle.jdbc.OracleDriver()); // Warning: this is a simple example program : In a long running application, // error handlers MUST clean up connections statements and result sets. final Connection c = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE", "system", "manager"); String plsql = "" + " declare " + " p_id varchar2(20) := null; " + " l_rc sys_refcursor;" + " begin " + " p_id := ?; " + " ? := 'input parameter was = ' || p_id;" + " open l_rc for " + " select 1 id, 'hello' name from dual " + " union " + " select 2, 'peter' from dual; " + " ? := l_rc;" + " end;"; CallableStatement cs = c.prepareCall(plsql); cs.setString(1, "12345"); cs.registerOutParameter(2, Types.VARCHAR); cs.registerOutParameter(3, OracleTypes.CURSOR); cs.execute(); System.out.println("Result = " + cs.getObject(2)); ResultSet cursorResultSet = (ResultSet) cs.getObject(3); while (cursorResultSet.next ()) { System.out.println (cursorResultSet.getInt(1) + " " + cursorResultSet.getString(2)); } cs.close(); c.close(); } } 

Вышеупомянутый пример запроса «выберите 1 id, ‘hello’ name из двойного объединения select 2, ‘peter’ из double;” может быть заменен любым запросом.

Во-первых, код, который вы опубликовали, недействителен. Анонимный блок PL / SQL не может вернуть выражение. И ни один PL / SQL-блок не может вернуть результат такого запроса. Вам нужно будет сделать что-то вроде объявления REF CURSOR и открытия этого курсора с помощью различных операторов SQL.

Поскольку анонимный блок PL / SQL ничего не может вернуть вызывающему абоненту, описываемая вами архитектура является проблематичной. Как минимум, вам нужно будет изменить анонимный блок, чтобы была зарегистрирована переменная связывания, которую может зарегистрировать код JDBC. Что-то вроде (адаптировано из примера в Menon’s Expert Oracle JDBC Programming (обратите внимание, что я, возможно, ввел некоторые незначительные синтаксические ошибки)

 CallableStatement stmt := null; ResultSet rset := null; String query := 'DECLARE FUNCTION get_result RETURN SYS_REFCURSOR AS l_rc SYS_REFCURSOR; BEGIN OPEN l_rc FOR SELECT DISTINCT fundname d, fundname r FROM some_table WHERE some_condition ORDER BY 1; RETURN l_rc; EXCEPTION WHEN others THEN OPEN l_rc FOR SELECT 'Not Available' d, 'Not Available' r FROM dual; RETURN l_rc; END get_result; BEGIN ? := get_result; END;'; try { cstmt := conn.prepareCall( query ); cstmt.registerOutParameter( 1, OracleTypes.CURSOR ); cstmt.execute(); rset := (ResultSet) cstmt.getObject( 1 ); } finally { <> } 

Попробуйте что-то вроде этого (псевдокод):

 [create or replace] function get_dataset (p_query in varchar2) return sys_refcursor as l_returnvalue sys_refcursor; begin open l_returnvalue for p_query; return l_returnvalue; end get_dataset; 

Возвращаемый REF CURSOR может обрабатываться как обычный dataset.

И будьте осторожны с SQL-инъекцией, когда вы используете такой подход …

Давайте будем гением компьютера.