SimpleJdbcCall 在 windows 中有效,但在 linux 中无效
SimpleJdbcCall works in windows but not linux
我有一个 spring 引导应用程序,我在其中使用 SimpleJdbcCall 执行存储过程,在 Windows (jdk1.8.0_111) 中一切正常,但是当我尝试运行 它在 Linux 服务器上(使用 java 1.8.0_131)它抛出错误:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Incorrect number of arguments for PROCEDURE banco.spcon_sesion; expected 18, got 0
这是我的代码:
@Override
public Usuario sesion(Credenciales credenciales) {
SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate)
.withProcedureName("spcon_sesion")
.declareParameters(new SqlParameter("in_usuario", Types.CHAR))
.declareParameters(new SqlParameter("in_contrasena", Types.CHAR))
.declareParameters(new SqlParameter("in_idSistema", Types.INTEGER))
.declareParameters(new SqlOutParameter("out_idUsuario", Types.INTEGER))
.declareParameters(new SqlOutParameter("out_nombre", Types.CHAR))
.declareParameters(new SqlOutParameter("out_paterno", Types.CHAR))
.declareParameters(new SqlOutParameter("out_materno", Types.CHAR))
.declareParameters(new SqlOutParameter("out_idPerfil", Types.INTEGER))
.declareParameters(new SqlOutParameter("out_nombrePerfil", Types.CHAR))
.declareParameters(new SqlOutParameter("out_idComercio", Types.INTEGER))
.declareParameters(new SqlOutParameter("out_nombreComercio", Types.CHAR))
.declareParameters(new SqlOutParameter("out_idTerminal", Types.INTEGER))
.declareParameters(new SqlOutParameter("out_nombreTerminal", Types.CHAR))
.declareParameters(new SqlOutParameter("out_idSucursal", Types.INTEGER))
.declareParameters(new SqlOutParameter("out_referenciaRetiroEfectivo", Types.CHAR))
.declareParameters(new SqlOutParameter("out_idProveedorSucursal", Types.INTEGER))
.declareParameters(new SqlOutParameter("out_codigo", Types.CHAR))
.declareParameters(new SqlOutParameter("out_mensaje", Types.CHAR));
SqlParameterSource in = new MapSqlParameterSource()
.addValue("in_usuario", credenciales.getUsuario())
.addValue("in_contrasena", credenciales.getContrasena())
.addValue("in_idSistema", credenciales.getIdSistema());
Map<String, Object> result = jdbcCall.execute(in);
@SuppressWarnings("unchecked")
List<Menu> menus = Menu
.obtenerListaMenus((List<Map<String, Object>>) result.get("#result-set-1"));
String codigo = (String) result.get("out_codigo");
if (codigo != null && codigo.equals("00")) {
try {
return new Usuario(
Util.ifNullToLong(result.get("out_idUsuario"), 0L),
Util.ifNullToString(result.get("out_nombre"), ""),
Util.ifNullToString(result.get("out_paterno"), ""),
Util.ifNullToString(result.get("out_materno"), ""),
Util.ifNullToString(result.get("out_referenciaRetiroEfectivo"), ""),
Util.ifNullToLong(result.get("out_idComercio"), 0L),
Util.ifNullToString(result.get("out_nombreComercio"), ""),
Util.ifNullToLong(result.get("out_idTerminal"), 0L),
Util.ifNullToString(result.get("out_nombreTerminal"), ""),
Util.ifNullToLong(result.get("out_idPerfil"), 0L),
Util.ifNullToString(result.get("out_nombrePerfil"), ""),
Util.ifNullToLong(result.get("out_idSucursal"), 0L),
Util.ifNullToLong(result.get("out_idProveedorSucursal"), 0L),
menus
);
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
我也尝试使用带有 openjdk8 的 docker 容器并出现同样的错误,有人可以帮我解决这个问题吗?
您似乎遇到了区分大小写的问题(在某些情况下,Win 和 MacOS 会忽略标识符的大小写)。按照 documentation.
检查您的设置
首先,尝试删除所有 declareParameters
- 不需要它们。
SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate)
.withProcedureName("spcon_sesion");
SqlParameterSource in =
new MapSqlParameterSource()
.addValue("in_usuario", credenciales.getUsuario())
.addValue("in_contrasena", credenciales.getContrasena())
.addValue("in_idSistema", credenciales.getIdSistema());
Map<String, Object> result = jdbcCall.execute(in);
如果这没有帮助 - 在这段特定的代码中使用纯 callable statement 而不是 SpringBoot 工具来定位问题。最好创建一个参数名称都采用相同大小写(小写或大写)的存储过程并测试其调用。
PS。我想 jdbcTemplate
中可能存在问题(如果可能,请在问题中提供其定义),因此为了简化情况,请考虑使用 new SimpleJdbcCall(dataSource)
.
我找到了答案,我需要添加
.withoutProcedureColumnMetaDataAccess()
像这样调用 simpleJdbcCall:
SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate)
.withProcedureName("spcon_sesion")
.withoutProcedureColumnMetaDataAccess()
.declareParameters(new SqlParameter("in_usuario", Types.CHAR))
.declareParameters(new SqlParameter("in_contrasena", Types.CHAR))
.declareParameters(new SqlParameter("in_idSistema", Types.INTEGER))
.declareParameters(new SqlOutParameter("out_idUsuario", Types.INTEGER))
.declareParameters(new SqlOutParameter("out_nombre", Types.CHAR))
.declareParameters(new SqlOutParameter("out_paterno", Types.CHAR))
.declareParameters(new SqlOutParameter("out_materno", Types.CHAR))
.declareParameters(new SqlOutParameter("out_idPerfil", Types.INTEGER))
.declareParameters(new SqlOutParameter("out_nombrePerfil", Types.CHAR))
.declareParameters(new SqlOutParameter("out_idComercio", Types.INTEGER))
.declareParameters(new SqlOutParameter("out_nombreComercio", Types.CHAR))
.declareParameters(new SqlOutParameter("out_idTerminal", Types.INTEGER))
.declareParameters(new SqlOutParameter("out_nombreTerminal", Types.CHAR))
.declareParameters(new SqlOutParameter("out_idSucursal", Types.INTEGER))
.declareParameters(new SqlOutParameter("out_referenciaRetiroEfectivo", Types.CHAR))
.declareParameters(new SqlOutParameter("out_idProveedorSucursal", Types.INTEGER))
.declareParameters(new SqlOutParameter("out_codigo", Types.CHAR))
.declareParameters(new SqlOutParameter("out_mensaje", Types.CHAR));
希望这对某人有所帮助:)
我有一个 spring 引导应用程序,我在其中使用 SimpleJdbcCall 执行存储过程,在 Windows (jdk1.8.0_111) 中一切正常,但是当我尝试运行 它在 Linux 服务器上(使用 java 1.8.0_131)它抛出错误:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Incorrect number of arguments for PROCEDURE banco.spcon_sesion; expected 18, got 0
这是我的代码:
@Override
public Usuario sesion(Credenciales credenciales) {
SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate)
.withProcedureName("spcon_sesion")
.declareParameters(new SqlParameter("in_usuario", Types.CHAR))
.declareParameters(new SqlParameter("in_contrasena", Types.CHAR))
.declareParameters(new SqlParameter("in_idSistema", Types.INTEGER))
.declareParameters(new SqlOutParameter("out_idUsuario", Types.INTEGER))
.declareParameters(new SqlOutParameter("out_nombre", Types.CHAR))
.declareParameters(new SqlOutParameter("out_paterno", Types.CHAR))
.declareParameters(new SqlOutParameter("out_materno", Types.CHAR))
.declareParameters(new SqlOutParameter("out_idPerfil", Types.INTEGER))
.declareParameters(new SqlOutParameter("out_nombrePerfil", Types.CHAR))
.declareParameters(new SqlOutParameter("out_idComercio", Types.INTEGER))
.declareParameters(new SqlOutParameter("out_nombreComercio", Types.CHAR))
.declareParameters(new SqlOutParameter("out_idTerminal", Types.INTEGER))
.declareParameters(new SqlOutParameter("out_nombreTerminal", Types.CHAR))
.declareParameters(new SqlOutParameter("out_idSucursal", Types.INTEGER))
.declareParameters(new SqlOutParameter("out_referenciaRetiroEfectivo", Types.CHAR))
.declareParameters(new SqlOutParameter("out_idProveedorSucursal", Types.INTEGER))
.declareParameters(new SqlOutParameter("out_codigo", Types.CHAR))
.declareParameters(new SqlOutParameter("out_mensaje", Types.CHAR));
SqlParameterSource in = new MapSqlParameterSource()
.addValue("in_usuario", credenciales.getUsuario())
.addValue("in_contrasena", credenciales.getContrasena())
.addValue("in_idSistema", credenciales.getIdSistema());
Map<String, Object> result = jdbcCall.execute(in);
@SuppressWarnings("unchecked")
List<Menu> menus = Menu
.obtenerListaMenus((List<Map<String, Object>>) result.get("#result-set-1"));
String codigo = (String) result.get("out_codigo");
if (codigo != null && codigo.equals("00")) {
try {
return new Usuario(
Util.ifNullToLong(result.get("out_idUsuario"), 0L),
Util.ifNullToString(result.get("out_nombre"), ""),
Util.ifNullToString(result.get("out_paterno"), ""),
Util.ifNullToString(result.get("out_materno"), ""),
Util.ifNullToString(result.get("out_referenciaRetiroEfectivo"), ""),
Util.ifNullToLong(result.get("out_idComercio"), 0L),
Util.ifNullToString(result.get("out_nombreComercio"), ""),
Util.ifNullToLong(result.get("out_idTerminal"), 0L),
Util.ifNullToString(result.get("out_nombreTerminal"), ""),
Util.ifNullToLong(result.get("out_idPerfil"), 0L),
Util.ifNullToString(result.get("out_nombrePerfil"), ""),
Util.ifNullToLong(result.get("out_idSucursal"), 0L),
Util.ifNullToLong(result.get("out_idProveedorSucursal"), 0L),
menus
);
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
我也尝试使用带有 openjdk8 的 docker 容器并出现同样的错误,有人可以帮我解决这个问题吗?
您似乎遇到了区分大小写的问题(在某些情况下,Win 和 MacOS 会忽略标识符的大小写)。按照 documentation.
检查您的设置首先,尝试删除所有 declareParameters
- 不需要它们。
SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate)
.withProcedureName("spcon_sesion");
SqlParameterSource in =
new MapSqlParameterSource()
.addValue("in_usuario", credenciales.getUsuario())
.addValue("in_contrasena", credenciales.getContrasena())
.addValue("in_idSistema", credenciales.getIdSistema());
Map<String, Object> result = jdbcCall.execute(in);
如果这没有帮助 - 在这段特定的代码中使用纯 callable statement 而不是 SpringBoot 工具来定位问题。最好创建一个参数名称都采用相同大小写(小写或大写)的存储过程并测试其调用。
PS。我想 jdbcTemplate
中可能存在问题(如果可能,请在问题中提供其定义),因此为了简化情况,请考虑使用 new SimpleJdbcCall(dataSource)
.
我找到了答案,我需要添加
.withoutProcedureColumnMetaDataAccess()
像这样调用 simpleJdbcCall:
SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate)
.withProcedureName("spcon_sesion")
.withoutProcedureColumnMetaDataAccess()
.declareParameters(new SqlParameter("in_usuario", Types.CHAR))
.declareParameters(new SqlParameter("in_contrasena", Types.CHAR))
.declareParameters(new SqlParameter("in_idSistema", Types.INTEGER))
.declareParameters(new SqlOutParameter("out_idUsuario", Types.INTEGER))
.declareParameters(new SqlOutParameter("out_nombre", Types.CHAR))
.declareParameters(new SqlOutParameter("out_paterno", Types.CHAR))
.declareParameters(new SqlOutParameter("out_materno", Types.CHAR))
.declareParameters(new SqlOutParameter("out_idPerfil", Types.INTEGER))
.declareParameters(new SqlOutParameter("out_nombrePerfil", Types.CHAR))
.declareParameters(new SqlOutParameter("out_idComercio", Types.INTEGER))
.declareParameters(new SqlOutParameter("out_nombreComercio", Types.CHAR))
.declareParameters(new SqlOutParameter("out_idTerminal", Types.INTEGER))
.declareParameters(new SqlOutParameter("out_nombreTerminal", Types.CHAR))
.declareParameters(new SqlOutParameter("out_idSucursal", Types.INTEGER))
.declareParameters(new SqlOutParameter("out_referenciaRetiroEfectivo", Types.CHAR))
.declareParameters(new SqlOutParameter("out_idProveedorSucursal", Types.INTEGER))
.declareParameters(new SqlOutParameter("out_codigo", Types.CHAR))
.declareParameters(new SqlOutParameter("out_mensaje", Types.CHAR));
希望这对某人有所帮助:)