Cómo utilizar el parámetro OUT IN en Oracle procedimiento almacenado con la primavera-JDBC?

Thiagarajan Ramanathan:

En mi procedimiento almacenado, tengo cuatro parámetros. Uno de los parámetros tiene tanto dentro como fuera. Estoy frente a los problemas mientras se accede a los parámetros de entrada y salida.

En el enfoque normal (usando CallableStatement) Soy capaz de obtener los resultados. Estoy frente a este problema cuando se utiliza CallableStatementCreatorFactory (utilizando este tema para evitar sonarqube). Busco a una solución utilizando CallableStatementCreatorFactory. No puedo hacer ningún cambio en el procedimiento almacenado.

Procedimiento

PROCEDURE SOMENAME (
applicationname           IN     VARCHAR2,
username                  IN OUT VARCHAR2,
sessionid                 IN     VARCHAR2 DEFAULT NULL,
usertype                  OUT    VARCHAR2,

Código de inicio de primavera

public static final String STORED_PROCEDURE_SOME_NAME = "{call TEST.PKG.SOMENAME(?,?,?,?)}";

CallableStatementCreatorFactory callableStatementCreatorFactory = new CallableStatementCreatorFactory(STORED_PROCEDURE_SOME_NAME);
callableStatementCreatorFactory.addParameter(new SqlParameter("APPLICATIONNAME", OracleTypes.VARCHAR));
callableStatementCreatorFactory.addParameter(new SqlParameter("USERNAME", OracleTypes.VARCHAR));
callableStatementCreatorFactory.addParameter(new SqlParameter("sessionid", OracleTypes.VARCHAR));
//callableStatementCreatorFactory.addParameter(new SqlOutParameter("USERNAME", OracleTypes.VARCHAR));  - throwing issue
callableStatementCreatorFactory.addParameter(new SqlOutParameter("usertype", OracleTypes.VARCHAR));

final Map<String, Object> param = new HashMap<>();
param.put("APPLICATIONNAME", applicationName);
param.put("USERNAME", userName);
param.put("sessionid", sessionGuid);


CallableStatementCallback<User> callableStatementCallback = new CallableStatementCallback<User>()
{
@Override
public User doInCallableStatement(CallableStatement callableStatement) throws SQLException
{
  try
  {
    callableStatement.execute();
    User userModel = new User();
    //userModel.setUserName(callableStatement.getString(2));  - throwing issue
    userModel.setUserType(callableStatement.getString(4));
    return populateUser(callableStatement);
  }
  finally
  {
    try
    {
      callableStatement.close();
    }
    catch (SQLException e)
    {
      LOGGER.error(MESSAGE_ERROR_CALLABLESTATEMENT_CLOSE, e);
    }
  }
}
};

CallableStatementCreator callableStatementCreator = callableStatementCreatorFactory.newCallableStatementCreator(param);
userModel = jdbcTemplate.execute(callableStatementCreator, callableStatementCallback);

Al agregar un adicional '? 'En la consulta, me sale el siguiente excepción:

org.springframework.jdbc.BadSqlGrammarException: CallableStatementCallback; bad SQL grammar [{call TEST.PKG.SOMENAME(?,?,?,?,?)}]; nested exception is java.sql.SQLException: ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'SOMENAME'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored

Cuando elimine la línea siguiente me sale el siguiente tema (eliminado signo de interrogación adicional):

callableStatementCreatorFactory.addParameter(new SqlOutParameter("USERNAME", OracleTypes.VARCHAR)); 

Excepción

org.springframework.jdbc.InvalidResultSetAccessException: CallableStatementCallback; invalid ResultSet access for SQL [{call TEST.PKG.SOMENAME(?,?,?,?)}]; nested exception is java.sql.SQLException: Invalid column index

Cuando habilite la línea siguiente me sale el siguiente error:

userModel.setUserName(callableStatement.getString(TWO));  (after commenting previous line and removing one addtional ?)

Excepción

org.springframework.jdbc.UncategorizedSQLException: CallableStatementCallback; uncategorized SQLException for SQL [{call TEST.PKG.SOMENAME(?,?,?,?)}]; SQL state [99999]; error code [17021]; Missing defines; nested exception is java.sql.SQLException: Missing defines
Lucas Woodward:

Su parámetro es un IN OUTparámetro de lo que debe utilizar una SqlInOutParameterpara él.

Vuelva a colocar la línea

    callableStatementCreatorFactory.addParameter(new SqlParameter("USERNAME", OracleTypes.VARCHAR));

con

    callableStatementCreatorFactory.addParameter(new SqlInOutParameter("USERNAME", OracleTypes.VARCHAR));

No añadir el extra ?, hay cuatro parámetros al procedimiento almacenado.

Eliminar la línea comentada, que intenta crear una SqlOutParameterpara USERNAME. Sin embargo, usted debe ser capaz de comentar la línea

    //userModel.setUserName(callableStatement.getString(2));  - throwing issue

y utilizar esta línea para leer el nombre de usuario que vuelva de la base de datos.

Hice estas modificaciones a su código y era capaz de utilizarlo para llamar a un procedimiento con la misma firma que la suya y vuelve a leer los datos del procedimiento.

Por cierto, no cierre la declaración dentro del CallableStatementCallback: He encontrado que esto provoca una excepción porque la primavera va a hacer otras cosas con la declaración después de que haya terminado con él, pero no puedo hacer esto si ha cerrado el comunicado. Primavera cerrará la declaración cuando haya terminado con él. Uno de los beneficios del uso de la primavera a hacer JDBC es que maneja una gran cantidad de las cosas repetitivo tedioso como este.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=239677&siteId=1
Recomendado
Clasificación