在Java中执行游标
我正在尝试使用Java执行一个存储过程。此SP执行一个游标以删除数据库中的寄存器,但它不起作用。当执行该方法时,它将在不删除所有寄存器的情况下完成。当我调试代码时,它在添加“thread.sleep(30000)”后工作。为什么我的代码在睡眠后还能工作 我的代码: SP(SQL Server)这很好用,我单独试用过。在Java中执行游标,java,sql,cursor,Java,Sql,Cursor,我正在尝试使用Java执行一个存储过程。此SP执行一个游标以删除数据库中的寄存器,但它不起作用。当执行该方法时,它将在不删除所有寄存器的情况下完成。当我调试代码时,它在添加“thread.sleep(30000)”后工作。为什么我的代码在睡眠后还能工作 我的代码: SP(SQL Server)这很好用,我单独试用过。 USE [PRUEBA] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE PROC [dbo].[SP_PUR
USE [PRUEBA]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROC [dbo].[SP_PURGA] (@iDIAS_PURGA INT, @iDIAS_IGNORAR INT)
AS
--DECLARE @iDIAS_PURGA INT = -3, @iDIAS_IGNORAR INT = -3
DECLARE @nvFechaInicio DATETIME, @nvFechaFin DATETIME;
DECLARE @iSeq_num INT;
SELECT @nvFechaFin = DATEADD(DAY,@iDIAS_IGNORAR,GETDATE());
SELECT @nvFechaInicio = DATEADD(DAY,@iDIAS_PURGA+1,@nvFechaFin);
--JL: CREAMOS UN CURSOR PARA ELIMNAR LOS REGISTROS.
DECLARE C_METADATOS CURSOR FOR
SELECT seq_num FROM TLC_VERINT.dbo.Imported_sessions
WHERE CONVERT(NVARCHAR(10),creation_time,103) BETWEEN CONVERT(NVARCHAR(10),@nvFechaInicio,103) AND CONVERT(NVARCHAR(10),@nvFechaFin,103)
AND is_deleted = 1
OPEN C_METADATOS;
FETCH C_METADATOS INTO @iSeq_num;
WHILE(@@FETCH_STATUS=0)
BEGIN
--ELIMINAMOS REGISTROS DE "Imported_sessions_audio"
DELETE FROM Imported_sessions_audio WHERE seq_num = @iSeq_num;
--ELIMINAMOS REGISTROS DE "Imported_sessions"
DELETE FROM Imported_sessions WHERE seq_num = @iSeq_num;
--AVANZAMOS AL SIGUIENTE REGISTROS
FETCH C_METADATOS INTO @iSeq_num;
END
CLOSE C_METADATOS;
DEALLOCATE C_METADATOS;
@Override
public void fEliminarMetadatos(int iDIAS_PURGA,int iDIAS_IGNORAR) {
//JL: Variables
Connection consql = null;
PreparedStatement pstm = null;
//JL: Consulta
try {
consql = new Conexion().getDBConnectionVerint();
pstm = consql.prepareStatement("exec [dbo].[SP_PURGA] ?,?");
pstm.setInt(1, iDIAS_PURGA);
pstm.setInt(2,iDIAS_IGNORAR);
//JL: Ejecutamos
pstm.execute();
//Thread.sleep(60000);
}catch(Exception e) {
new CrearLog().archivoLog("::: ERROR ::: Ocurrio un error mientras se ejecutaba ::: [dbo].[SP_PURGA].");
new CrearLog().archivoLog("::: ERROR ::: "+e);
Var_runtime.exit(1);
}finally {
try {
if(!consql.isClosed()) {consql.close();}
if(!pstm.isClosed()) { pstm.close();}
}catch (Exception e) {
new CrearLog().archivoLog("::: ADVERTENCIA ::: Ocurrio un error mientras se trataba de cerrar la conexión para la consulta ::: [dbo].[SP_PURGA].");
new CrearLog().archivoLog("::: ADVERTENCIA ::: " + e);
new CrearLog().archivoLog("::: ADVERTENCIA ::: El error no es grave, el proceso de extración continuará.");
}
}
}
我用Java编写的代码,我把睡眠和工作放在一起。
USE [PRUEBA]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROC [dbo].[SP_PURGA] (@iDIAS_PURGA INT, @iDIAS_IGNORAR INT)
AS
--DECLARE @iDIAS_PURGA INT = -3, @iDIAS_IGNORAR INT = -3
DECLARE @nvFechaInicio DATETIME, @nvFechaFin DATETIME;
DECLARE @iSeq_num INT;
SELECT @nvFechaFin = DATEADD(DAY,@iDIAS_IGNORAR,GETDATE());
SELECT @nvFechaInicio = DATEADD(DAY,@iDIAS_PURGA+1,@nvFechaFin);
--JL: CREAMOS UN CURSOR PARA ELIMNAR LOS REGISTROS.
DECLARE C_METADATOS CURSOR FOR
SELECT seq_num FROM TLC_VERINT.dbo.Imported_sessions
WHERE CONVERT(NVARCHAR(10),creation_time,103) BETWEEN CONVERT(NVARCHAR(10),@nvFechaInicio,103) AND CONVERT(NVARCHAR(10),@nvFechaFin,103)
AND is_deleted = 1
OPEN C_METADATOS;
FETCH C_METADATOS INTO @iSeq_num;
WHILE(@@FETCH_STATUS=0)
BEGIN
--ELIMINAMOS REGISTROS DE "Imported_sessions_audio"
DELETE FROM Imported_sessions_audio WHERE seq_num = @iSeq_num;
--ELIMINAMOS REGISTROS DE "Imported_sessions"
DELETE FROM Imported_sessions WHERE seq_num = @iSeq_num;
--AVANZAMOS AL SIGUIENTE REGISTROS
FETCH C_METADATOS INTO @iSeq_num;
END
CLOSE C_METADATOS;
DEALLOCATE C_METADATOS;
@Override
public void fEliminarMetadatos(int iDIAS_PURGA,int iDIAS_IGNORAR) {
//JL: Variables
Connection consql = null;
PreparedStatement pstm = null;
//JL: Consulta
try {
consql = new Conexion().getDBConnectionVerint();
pstm = consql.prepareStatement("exec [dbo].[SP_PURGA] ?,?");
pstm.setInt(1, iDIAS_PURGA);
pstm.setInt(2,iDIAS_IGNORAR);
//JL: Ejecutamos
pstm.execute();
//Thread.sleep(60000);
}catch(Exception e) {
new CrearLog().archivoLog("::: ERROR ::: Ocurrio un error mientras se ejecutaba ::: [dbo].[SP_PURGA].");
new CrearLog().archivoLog("::: ERROR ::: "+e);
Var_runtime.exit(1);
}finally {
try {
if(!consql.isClosed()) {consql.close();}
if(!pstm.isClosed()) { pstm.close();}
}catch (Exception e) {
new CrearLog().archivoLog("::: ADVERTENCIA ::: Ocurrio un error mientras se trataba de cerrar la conexión para la consulta ::: [dbo].[SP_PURGA].");
new CrearLog().archivoLog("::: ADVERTENCIA ::: " + e);
new CrearLog().archivoLog("::: ADVERTENCIA ::: El error no es grave, el proceso de extración continuará.");
}
}
}
如何在没有睡眠的情况下使此代码工作?我没有找到如何使我的方法与数据库中的游标一起工作,因此我使用@stickybit指示的事务在代码中模拟游标 看起来是这样的:
@Override
public void fEliminarMetadatos(int iDIAS_PURGA,int iDIAS_IGNORAR) {
//JL: Variables
Connection consql = null;
PreparedStatement pstm1,pstm2,pstm3;
ResultSet rs = null;
int iContador = 0;
//JL: Inicializamos pstm's
pstm1 = pstm2 = pstm3 = null;
//JL: Consulta
try {
consql = new Conexion().getDBConnectionVerint();
//JL: Cambiamos el commit de la base a false
consql.setAutoCommit(false);
pstm1 = consql.prepareStatement("exec [SP_PURGA_GET_SEQNUM] ?,?");
pstm1.setInt(1, iDIAS_PURGA);
pstm1.setInt(2,iDIAS_IGNORAR);
//JL: Ejecutamos
rs = pstm1.executeQuery();
//JL: Iteramos sobre el resultado del SP [SP_PURGA_GET_SEQNUM]
while(rs.next()) {
iContador ++;
//JL: eliminamos registro de la tabla Imported_sessions_audio
pstm2 = consql.prepareStatement("DELETE FROM Imported_sessions_audio WHERE seq_num = ?");
pstm2.setInt(1, rs.getInt(1));
pstm2.executeUpdate();
//JL: eliminamos registro de la tabla Imported_sessions
pstm3 = consql.prepareStatement("DELETE FROM Imported_sessions WHERE seq_num = ?");
pstm3.setInt(1, rs.getInt(1));
pstm3.executeUpdate();
//JL: Confirmamos la ejecución de ambas query's
consql.commit();
}
new CrearLog().archivoLog("::: INFORMACIÓN ::: Se eliminarón ["+iContador+"] registros de la base de datos.");
}catch(Exception e) {
new CrearLog().archivoLog("::: ERROR ::: Ocurrio un error mientras se ejecutaba ::: [dbo].[SP_PURGA_GET_SEQNUM].");
new CrearLog().archivoLog("::: ERROR ::: "+e);
new CrearLog().archivoLog("::: ERROR ::: Ocurrio un error grave al ejecutar el proceso de purga, revise los mensajes anteriores a este para mayor información.");
new CrearLog().archivoLog("::: INFORMACIÓN ::: El proceso de purga finalizó.");
new CrearLog().archivoLog(":::::::::::::::::::::::::::::::::::::::::::::::::::::");
Var_runtime.exit(1);
}finally {
try {
if(!consql.isClosed()) {consql.close();}
if(!pstm1.isClosed()) { pstm1.close();}
if(!pstm2.isClosed()) { pstm2.close();}
if(!pstm3.isClosed()) { pstm3.close();}
}catch (Exception e) {
new CrearLog().archivoLog("::: ADVERTENCIA ::: Ocurrio un error mientras se trataba de cerrar la conexión para la consulta ::: [dbo].[SP_PURGA_GET_SEQNUM].");
new CrearLog().archivoLog("::: ADVERTENCIA ::: " + e);
new CrearLog().archivoLog("::: ADVERTENCIA ::: El error no es grave, el proceso de extración continuará.");
}
}
}
这对我很有用。如果有人知道如何更好地使用此代码,我会阅读他们。您使用的是事务吗?我无法在您的代码中看到提交。也许这就是问题所在?@stickybit我在这个操作中不使用事务,它只是删除寄存器。您认为我需要尝试提交吗?我不确定您在这里使用的到底是什么,因为您的代码没有向我显示(
连接是什么?它是如何在新建Conexion().getDBConnectionVerint()
中创建的?)。但是尝试添加一行consql.commit()代码>行后pstm.execute()代码>。毕竟,可能发生的最糟糕的事情是它没有帮助我尝试使用“consql.commit()”;而这不起作用,在“new Conexion().getDBConnectionVerint()”中,我只获取与数据库“dbConnection=DriverManager.getConnection”的连接(DB\u Conexion\u VERINT、DB\u USUARIO\u VERINT、BD\u PASS\u VERINT);')(该方法有很多代码,但我不能放在这里。)