Oracle
 sql >> Database >  >> RDS >> Oracle

Groovy Oracle Stored Proc:indice di colonna non valido

Il codice seguente può aiutarti a ottenere la variabile di SYS_REFCURSOR dal blocco anonimo Oracle.

Dovremmo concentrarci su alcuni dettagli chiave:

  1. Classe groovy.sql.Sql non ha OutParameter corrispondente e lo facciamo manualmente come CURSOR_PARAMETER e passalo a sql.call metodo
  2. Considera che il blocco inizi con {call DECLARE e termina con END } senza punto e virgola dopo END. Altrimenti possiamo ottenere una SQLException scarsamente riconoscibile in faccia.
  3. I punti interrogativi ? all'interno di sqlString sono posti per le associazioni dei parametri. Le associazioni vengono effettuate nell'ordine naturale prendendo i valori da parametersList .
    • In questo esempio abbiamo l'unico binding, quindi il ? si lega con CURSOR_PARAMETER trattando il valore come OUT parametro di tipo passato;
  4. C'è solo un ingresso in chiusura dopo sql.call e ResultSet rs fornire righe del cursore my_cur dichiarato in blocco anonimo.
  5. Possiamo semplificare sqlString utilizzando una funzione che restituisce SYS_REFCURSOR invece di una procedura con OUT parametro. Quindi potrebbe assomigliare a questo "{call BEGIN ? := MY_FUNC(); END}" o anche "{? = call MY_FUNC()}"
import groovy.sql.OutParameter
import groovy.sql.Sql
import oracle.jdbc.OracleTypes

import java.sql.ResultSet

def driver = 'oracle.jdbc.driver.OracleDriver'
def sql = Sql.newInstance('jdbc:oracle:thin:@my-server:1521:XXX', 'usr', 'psw', driver)

// special OutParameter for cursor type
OutParameter CURSOR_PARAMETER = new OutParameter() {
    public int getType() {
        return OracleTypes.CURSOR;
    }
};

// look at some ceremonial wrappers around anonymous block
String sqlString = """{call
    DECLARE
      my_cur SYS_REFCURSOR;
    BEGIN
        STORED_PROCEDURE_NAME(my_cur);
        ? := my_cur;
    END
}
""";

// the order of elements matches the order of bindings
def parametersList = [CURSOR_PARAMETER];


// rs contains the result set of cursor my_cur
sql.call(sqlString, parametersList) { ResultSet rs ->
  while (rs.next()) {
      println rs.getString("my_column")
  }
};

PS E grazie per la domanda.