[英]Can't retrieve ID from an insert in JDBC with PreparedStatement
I'm trying to get the ID of an insert row which is auto_increment
in MySQL.我正在尝试获取在 MySQL 中为
auto_increment
的插入行的ID 。 I'm using the parameter Statement.RETURN_GENERATED_KEYS
in the prepareStatement
method and trying to obtain it via the getGeneratedKeys
method.我在
prepareStatement
方法中使用参数Statement.RETURN_GENERATED_KEYS
并尝试通过getGeneratedKeys
方法获取它。 Somehow, it is not retrieving the ID .不知何故,它没有检索ID 。
It should be noted that the insertion is done, but since the ID is not obtained, I cannot perform the other inserts and that is why it gives me the error "MySQL ERROR 1452"
, because an insert is being made later with the ID 0 that does not exist.应该注意的是,插入已完成,但由于未获得ID ,我无法执行其他插入,这就是为什么它给我错误
"MySQL ERROR 1452"
,因为稍后将使用ID 0进行插入那不存在。
public int insertar(Compra objC, ArrayList<DetalleCompra> listaDetalle) {
try {
conexion = MySQLConexion.conexion();
conexion.setAutoCommit(false);
procedimientoAlmacenado = conexion.prepareStatement("{call insertar_compra (?, ?)}", Statement.RETURN_GENERATED_KEYS);
fecha = FORMATO_FECHA.parse(objC.getFecha());
fechaSQL = new java.sql.Date(fecha.getTime());
procedimientoAlmacenado.setDate(1, fechaSQL);
procedimientoAlmacenado.setInt(2, objC.getIdCliente());
resultado = procedimientoAlmacenado.executeUpdate();
int idCompra = 0;
ResultSet idGenerada = procedimientoAlmacenado.getGeneratedKeys();
if (idGenerada.next()) {
idCompra = idGenerada.getInt(1);
}
if (resultado != 0) {
for (DetalleCompra x : listaDetalle) {
procedimientoAlmacenado = conexion.prepareCall("{call insertar_detalle_compra (?, ?, ?)}");
procedimientoAlmacenado.setInt(1, idCompra);
procedimientoAlmacenado.setInt(2, x.getIdProducto());
procedimientoAlmacenado.setInt(3, x.getCantidad());
resultado = procedimientoAlmacenado.executeUpdate();
procedimientoAlmacenado = conexion.prepareCall("{disminuir_stock (?, ?)}");
procedimientoAlmacenado.setInt(1, x.getIdProducto());
procedimientoAlmacenado.setInt(2, x.getCantidad());
resultado = procedimientoAlmacenado.executeUpdate();
}
}
conexion.commit();
} catch (Exception e) {
System.out.println(e.getMessage());
try {
conexion.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
} finally {
try {
if (procedimientoAlmacenado != null)
procedimientoAlmacenado.close();
if (conexion != null)
conexion.close();
} catch (SQLException e) {
System.out.println(e.getMessage());
}
}
return resultado;
}
I also tried to create a variable:我还尝试创建一个变量:
String[] generatedId = { "ID" };
and place it in the method prepareStatement
:并将其放在方法
prepareStatement
中:
procedimientoAlmacenado = conexion.prepareStatement("{call insertar_compra (?, ?)}", generatedId);
However, it doesn't work either.但是,它也不起作用。 I'm suspecting that it has to do with the fact that I'm doing the statement inside a stored procedure, or with
setAutoCommit(false)
, but I can't think of anything else.我怀疑这与我在存储过程中或与
setAutoCommit(false)
执行语句有关,但我想不出其他任何事情。
Ok so what I did was make the stored procedure return me the last inserted ID:好的,我所做的就是让存储过程返回最后插入的 ID:
delimiter $$
create procedure insertar_compra (in fec datetime, in client_id int, out id int)
begin
insert into compra values (null, fec, client_id, 'P');
set id = LAST_INSERT_ID();
end; $$
delimiter ;
And then I got it with the registerOutParameter()
method:然后我用
registerOutParameter()
方法得到了它:
public int insertar(Compra objC, ArrayList<DetalleCompra> listaDetalle) {
try {
conexion = MySQLConexion.conexion();
conexion.setAutoCommit(false);
procedimientoAlmacenado = conexion.prepareCall("{call insertar_compra (?, ?, ?)}");
fecha = FORMATO_FECHA.parse(objC.getFecha());
fechaSQL = new Timestamp(fecha.getTime());
procedimientoAlmacenado.setTimestamp(1, fechaSQL);
procedimientoAlmacenado.setInt(2, objC.getIdCliente());
procedimientoAlmacenado.registerOutParameter(3, Types.INTEGER);
resultado = procedimientoAlmacenado.executeUpdate();
int idCompra = 0;
idCompra = procedimientoAlmacenado.getInt(3);
if (resultado != 0) {
for (DetalleCompra x : listaDetalle) {
procedimientoAlmacenado = conexion.prepareCall("{call insertar_detalle_compra (?, ?, ?)}");
procedimientoAlmacenado.setInt(1, idCompra);
procedimientoAlmacenado.setInt(2, x.getIdProducto());
procedimientoAlmacenado.setInt(3, x.getCantidad());
resultado = procedimientoAlmacenado.executeUpdate();
procedimientoAlmacenado = conexion.prepareCall("{call disminuir_stock (?, ?)}");
procedimientoAlmacenado.setInt(1, x.getIdProducto());
procedimientoAlmacenado.setInt(2, x.getCantidad());
resultado = procedimientoAlmacenado.executeUpdate();
}
}
conexion.commit();
} catch (Exception e) {
System.out.println(e.getMessage());
try {
conexion.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
} finally {
try {
if (procedimientoAlmacenado != null)
procedimientoAlmacenado.close();
if (conexion != null)
conexion.close();
} catch (SQLException e) {
System.out.println(e.getMessage());
}
}
return resultado;
}
Thanks to Mark Rotteveel for the suggestion!感谢Mark Rotteveel的建议!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.