Esegui blocco anonimo pl / sql e ottieni set di risultati in java

Vorrei eseguire il PL / SQL anonimo e ho bisogno di ottenere l’object del set di risultati. Ho ottenuto il codice che può essere fatto usando i cursori all’interno del blocco PL / SQL.

Ma il blocco PL / SQL arriverà dal database come testo. Quindi non posso modificare quel blocco PL / SQL. E restituirà solo due valori i cui nomi di colonna saranno sempre uguali. Restituirà un elenco di 2 valori di combinazione di colonne.

Qui sto dando esempio 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;

Ogni risposta sarà così utile.

Ecco un esempio autonomo di come “eseguire il PL / SQL anonimo e ottenere l’object del set di risultati”

 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(); } } 

La query di esempio sopra “seleziona 1 id, nome ‘hello’ da dual union select 2, ‘peter’ da dual;” può essere sostituito da qualsiasi query.

Prima di tutto, il codice che hai postato non è valido. Un blocco PL / SQL anonimo non può restituire un’espressione. E nessun blocco PL / SQL può restituire il risultato di una query del genere. Dovresti fare qualcosa come dichiarare un REF CURSOR e aprire quel cursore usando le varie istruzioni SQL.

Poiché un blocco PL / SQL anonimo non può restituire nulla a un chiamante, l’architettura che si sta descrivendo è problematica. Come minimo, avresti bisogno di modificare il blocco anonimo in modo che ci fosse una variabile di binding che il tuo codice JDBC poteva registrare. Qualcosa di simile (adattato da un esempio in Menon’s Expert Oracle JDBC Programming (nota che potrei aver introdotto alcuni errori di syntax minori)

 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 { <> } 

Prova qualcosa come questo (pseudo-codice):

 [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; 

Il REF CURSOR che viene restituito può essere elaborato come un normale set di dati.

E fai attenzione all’iniezione SQL quando usi un approccio come questo …