Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Groovy Oracle Stored Proc - índice de coluna inválido


O código a seguir pode ajudá-lo a obter a variável de SYS_REFCURSOR do bloco anônimo Oracle.

Devemos nos concentrar em alguns detalhes importantes:
  1. Classe groovy.sql.Sql não tem OutParameter correspondente e fazemos manualmente como CURSOR_PARAMETER e passe para sql.call método
  2. Considere que o bloco começa com {call DECLARE e termina com END } sem ponto e vírgula após END. Caso contrário, podemos obter uma SQLException pouco reconhecível na cara.
  3. Os pontos de interrogação ? dentro do sqlString são locais para ligações de parâmetros. As ligações são feitas na ordem natural tomando valores de parametersList .
    • Neste exemplo, temos a única ligação, então o ? vincula com CURSOR_PARAMETER tratando o valor como OUT parâmetro do tipo passado;
  4. Há apenas uma entrada em encerramento após sql.call e ResultSet rs fornecer linhas de cursor my_cur declarado em bloco anônimo.
  5. Podemos simplificar sqlString usando uma função que retorna SYS_REFCURSOR ao invés de um procedimento com OUT parâmetro. Então poderia ficar assim "{call BEGIN ? := MY_FUNC(); END}" ou mesmo "{? = 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")
  }
};

P.S. E obrigado pela pergunta.