Выполнить курсор в Java

Я пытаюсь выполнить хранимую процедуру с помощью Java. Этот SP запускает курсор для удаления регистров в моей базе данных, но он не работает. Когда метод выполняется, он завершается без удаления всех регистров. Когда я отлаживаю свой код, он работает после добавления «thread.sleep (30,000)». Почему мой код работает после того, как он засыпает?

Мой код:

SP (SQL Server) Работает хорошо, я пробовал индивидуально.

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;

Мой код на Java, я сплю и работает.

@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á.");
            }
    }

}

Как мне заставить этот код работать без сна?

Вы используете транзакции? Я не вижу фиксации в вашем коде. Может в этом проблема?

sticky bit 24.04.2018 23:52

@stickybit Я не использую транзакцию в этой операции, просто удаляю регистры. Как вы думаете, мне нужно было попробовать совершить коммит?

JesusLopez 25.04.2018 00:43

Я не уверен, что именно вы здесь используете, поскольку ваш код мне этого не показывает (Connection - это это? И как он создается в new Conexion().getDBConnectionVerint()?). Но не помешает попробовать добавить строку с consql.commit(); после строки pstm.execute();. В конце концов, худшее, что может случиться, - это то, что это не поможет. ;)

sticky bit 25.04.2018 01:00

Я пробовал с ´consql.commit (); ´ и это не работает, в ´new Conexion (). GetDBConnectionVerint () ´ я получаю соединение только с базой данных ´dbConnection = DriverManager.getConnection (DB_CONEXION_VERINT, DB_USUARIO_ ´VERINT); (У метода много кода, но я не могу его сюда выложить.)

JesusLopez 25.04.2018 17:59
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
4
384
1

Ответы 1

Я не нашел, как заставить мой метод работать с моим курсором из базы данных, поэтому я смоделировал курсор в своем коде, используя транзакцию, указанную @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á.");
            }
    }

}

Это подходит для меня. Если у кого-то есть идеи, как сделать этот код лучше, я их читаю.

Другие вопросы по теме