2012-01-25 14 views
7

Recibo esta excepción sobre confirmaciones y reversiones, pero no estoy seguro de cuál es exactamente el problema con mi Procedimiento almacenado. He leído las respuestas en otras preguntas similares y no puedo encontrar dónde exactamente se está arruinando el recuento de compromisos.El recuento de transacciones después de EXECUTE indica un número no coincidente de instrucciones BEGIN y COMMIT. Recuento anterior

Por lo tanto, este es el procedimiento almacenado que utilice:

-- this is a procedure used for the purge utility. This procedure uses the parameters of a date and lets user select 
-- if the leads that should be purge must be closed either before, on or since that date. 
-- operator: 0-->less 1-->equal 2-->greater 
-- @closed: closing date 
-- leadscount: returns the count of leads deleted 

IF OBJECT_ID ('LEAD_PURGE', 'P') IS NOT NULL 
    DROP PROCEDURE LEAD_PURGE 
go 

CREATE PROCEDURE LEAD_PURGE 
@purgextns INT, 
@leadscount INT OUTPUT 
AS 
BEGIN 
BEGIN TRANSACTION 
CREATE TABLE #ASSIGNMENTS_DELETED 
(
    ID NUMERIC(19, 0) 
    PRIMARY KEY (ID) 
) 

CREATE TABLE #MAPRESULTS_DELETED 
(
    ID NUMERIC(19, 0) 
    PRIMARY KEY (ID) 
) 

CREATE TABLE #COMMAND_DELETED 
(
    ID NUMERIC(19, 0) 
    PRIMARY KEY (ID) 
) 

CREATE TABLE #PROGRESS_STATUS_DELETED 
(
    ID NUMERIC(19, 0) 
    PRIMARY KEY (ID) 
) 

CREATE TABLE #DETAILS_DELETED 
(
    ID NUMERIC(19, 0) 
    PRIMARY KEY (ID) 
) 

CREATE TABLE #NEEDS_DELETED 
(
    ID NUMERIC(19, 0) 
    PRIMARY KEY (ID) 
) 

insert into #ASSIGNMENTS_DELETED 
select SEQID FROM ASSIGNMENT WHERE LEADSEQ IN (SELECT ID FROM PURGE_LEAD); 

SELECT @leadscount = (SELECT COUNT(*) FROM PURGE_LEAD); 

INSERT INTO #MAPRESULTS_DELETED 
SELECT ID FROM MAPRESULT WHERE ASSIGNMENTSEQ IN (SELECT ID FROM #ASSIGNMENTS_DELETED) 

INSERT INTO #COMMAND_DELETED 
SELECT ID FROM EXECUTERULECOMMAND WHERE MAPRESULTID IN (SELECT ID FROM #MAPRESULTS_DELETED) 

INSERT INTO #PROGRESS_STATUS_DELETED 
SELECT PROGRESS_STATUS_ID FROM COMMAND WHERE ID IN (SELECT ID FROM #COMMAND_DELETED) 

INSERT INTO #DETAILS_DELETED 
SELECT DETAILID FROM LEAD WHERE SEQID IN (SELECT ID FROM PURGE_LEAD) 

INSERT INTO #NEEDS_DELETED 
SELECT NEEDSID FROM LEAD WHERE SEQID IN (SELECT ID FROM PURGE_LEAD) 



DELETE FROM PROGRESS_STATUS WHERE ID IN (SELECT ID FROM #PROGRESS_STATUS_DELETED) 

DELETE FROM EXECUTERULECOMMAND WHERE ID IN (SELECT ID FROM #COMMAND_DELETED) 

DELETE FROM COMMAND WHERE ID IN (SELECT ID FROM #COMMAND_DELETED) 

DELETE FROM SIMPLECONDITIONAL WHERE RESULT IN (SELECT ID FROM #MAPRESULTS_DELETED) 

DELETE FROM MAPPREDICATE WHERE ROWBP IN (SELECT ID FROM MAPROW WHERE RESULT IN (SELECT ID FROM #MAPRESULTS_DELETED)) 

DELETE FROM MAPROW WHERE RESULT IN (SELECT ID FROM #MAPRESULTS_DELETED) 

DELETE FROM MAPRESULT WHERE ID IN (SELECT ID FROM #MAPRESULTS_DELETED) 

DELETE FROM ASSIGNMENTATTACHMENTS WHERE ASSIGNMENTSEQ IN (SELECT ID FROM #ASSIGNMENTS_DELETED) 

DELETE FROM LEADOBSERVER WHERE ASSIGNSEQ IN (SELECT ID FROM #ASSIGNMENTS_DELETED) 

DELETE FROM MAPDESTINATIONS WHERE SUGGESTEDASSIGNID IN 
    (SELECT ID FROM SUGGESTEDASSIGNMENT WHERE ASSIGNMENT_SEQID IN (SELECT ID FROM #ASSIGNMENTS_DELETED)) 

DELETE FROM SUGGESTEDASSIGNMENT WHERE ASSIGNMENT_SEQID IN (SELECT ID FROM #ASSIGNMENTS_DELETED) 

DELETE FROM PRODUCTINTEREST WHERE LEADSEQ IN (SELECT ID FROM PURGE_LEAD) 



CREATE TABLE #SALE_DELETED_EX 
(
    ID NUMERIC(19, 0) 
    PRIMARY KEY (ID) 
) 
INSERT into #SALE_DELETED_EX SELECT SALEEXSEQ FROM SALE WHERE SEQID IN (SELECT SALEID FROM LEADSALES WHERE LEADID IN (SELECT ID FROM PURGE_LEAD)) 


DELETE FROM SALE WHERE SEQID IN (SELECT SALEID FROM LEADSALES WHERE LEADID IN (SELECT ID FROM PURGE_LEAD)) 


DELETE FROM SALEEXTENSIONS WHERE 
    SEQID IN (SELECT ID FROM #SALE_DELETED_EX) 

DELETE FROM LEADSALES WHERE LEADID IN (SELECT ID FROM PURGE_LEAD) 


DELETE FROM NOTES WHERE OBJECTID IN (SELECT ID FROM #NEEDS_DELETED) OR OBJECTID IN (SELECT ID FROM #DETAILS_DELETED) 

DELETE FROM HISTORYRECORD WHERE OBJECTID IN (SELECT ID FROM #DETAILS_DELETED) 

DELETE FROM DETAIL WHERE SEQID IN (SELECT ID FROM #NEEDS_DELETED UNION SELECT ID FROM #DETAILS_DELETED) 

DELETE FROM MESSAGES WHERE PROVIDERID IN (SELECT ID FROM PURGE_LEAD) 

DELETE FROM ASSIGNMENT WHERE LEADSEQ IN (SELECT ID FROM PURGE_LEAD) 

DELETE FROM LEAD WHERE SEQID IN (SELECT ID FROM PURGE_LEAD) 

CREATE TABLE #PURGE_LEAD_E 
(
    ID NUMERIC(19, 0) 
    PRIMARY KEY (ID) 
) 

INSERT into #PURGE_LEAD_E Select SEQID FROM LEADEXTENSIONS WHERE 
    SEQID NOT IN (SELECT LEADEXSEQ FROM LEAD) 

if @purgextns = 1 begin 
    DELETE FROM LEADEXTENSIONS WHERE 
     SEQID IN (SELECT ID FROM PURGE_LEAD_E) 
end 


DELETE FROM PURGE_LEAD; 

DROP TABLE #ASSIGNMENTS_DELETED 

DROP TABLE #MAPRESULTS_DELETED 

DROP TABLE #COMMAND_DELETED 

DROP TABLE #PROGRESS_STATUS_DELETED 

DROP TABLE #DETAILS_DELETED 

DROP TABLE #NEEDS_DELETED 

DROP TABLE #PURGE_LEAD_E 

DROP TABLE #SALE_DELETED_EX 

COMMIT 
END 
go 

ahora llamar a este procedimiento en el siguiente código:

try { 
     c = new ConnectionHelper().getConnection(); 
     String sql = ""; 
     if (shouldPurgeExtns) { 
      progressModel.makeProgress("progress.deleting.dependents"); 
      purgeMultiselect(c, LEAD, isMSSQL); 
     } 
     sql = "{CALL " + TOPLinkManager.getSchemaPrefix() 
       + "LEAD_PURGE (?,?)}"; 
     cs = c.prepareCall(sql); 
     cs.setInt(1, shouldPurgeExtns ? 0 : 1); 
     cs.registerOutParameter(2, java.sql.Types.INTEGER); 
     cs.executeUpdate(); 
     int rowcount = cs.getInt(2); 
     cs.close(); 
     progressModel.makeProgress("progress.recording.history"); 
     recordHistory(c, isMSSQL, LEAD, DateTypeDecorator.CLOSED, date, 
       rowcount); 
     done(progressModel); 
     c.close(); 
     return true; 
    } catch (Exception e) { 
     Logs.main.error("Error Purging Leads", e); 
     throw new Exception(e.getMessage()); 
    } 

Y consigo una excepción en la línea que dice int rowcount = cs.getInt(2);

La excepción es:

com.microsoft.sqlserver.jdbc.SQLServerException: Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 0, current count = 1. 
    at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:196) 
    at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1454) 
    at com.microsoft.sqlserver.jdbc.SQLServerStatement.processResults(SQLServerStatement.java:1083) 
    at com.microsoft.sqlserver.jdbc.SQLServerCallableStatement.getOutParameter(SQLServerCallableStatement.java:112) 
    at com.microsoft.sqlserver.jdbc.SQLServerCallableStatement.getterGetParam(SQLServerCallableStatement.java:387) 

Por favor, ayúdenme. en com.microsoft.sqlserver.jdbc.SQLServerCallableStatement.getValue (SQLServerCallableStatement.java:393) en com.microsoft.sqlserver.jdbc.SQLServerCallableStatement.getInt (SQLServerCallableStatement.java:437) en marketsoft.tools.purge.PurgeUtils. PurgeLeads (PurgeUtils.java:283)

EDIT:

como he respondido a esta pregunta a mí mismo ... me gustaría cambiar la pregunta un poco ahora.

¿Por qué no se arrojó ninguna excepción en el método de ejecución ???

Respuesta

2

¡Lo siento muchachos! Gracias por todos sus esfuerzos, al final, que era un muy pequeño error de mi parte en el procedimiento almacenado:

mirada en línea:

if @purgextns = 1 begin 
    DELETE FROM LEADEXTENSIONS WHERE 
     SEQID IN (SELECT ID FROM PURGE_LEAD_E) 
end 

Cabe #PURGE_LEAD_E

Todas sus respuestas me ayudó a obtener una perspectiva diferente del desarrollo de procedimientos de la tienda. ¡Muchas gracias!

+0

¿Todavía estoy buscando la respuesta de por qué exactamente no se lanzó el error en el método de ejecución? – MozenRath

+0

debe cambiar para usar el manejo de errores de todos modos – gbn

+0

sí! Eso es lo que quise decir con perspectiva :) – MozenRath

7

intenta agregar en el inicio del procedimiento de

SET XACT_ABORT ON 

O

envoltura de sus estados de cuenta con

begin try 
    BEGIN TRANSACTION 
Your TSQL code 

    COMMIT 
end try 
begin catch 
    ROLLBACK 
    RAISERROR('Gotcha!', 16, 1) 
end catch 

Para comprobar cuántos no comprometida BEGIN TRAN se abre prueba el sistema @@TRANCOUNT variable

14

Su COMMIT no está siendo golpeado, probablemente debido a un error. La transacción no se revertirá automáticamente

la mejor manera (y mejores prácticas) es añadir un poco de manipulación de errores de SQL

CREATE PROCEDURE LEAD_PURGE 
    @purgextns INT, 
    @leadscount INT OUTPUT 
AS 
SET NOCOUNT, XACT_ABORT ON; 

BEGIN TRY 
    BEGIN TRANSACTION 

    CREATE TABLE #ASSIGNMENTS_DELETED 
    (
     ID NUMERIC(19, 0) 
     PRIMARY KEY (ID) 
) 

    ... 
    DROP TABLE #SALE_DELETED_EX 

    COMMIT TRANSACTION 
END TRY 
BEGIN CATCH 
    IF XACT_STATE() <> 0 
     ROLLBACK TRANSACTION 
    RAISERROR ('it broke', 16, 1) 
END CATCH 
go 

Para más detalles sobre lo que está pasando aquí, véase mi respuesta aquí Nested stored procedures containing TRY CATCH ROLLBACK pattern?

Nota: no es necesario eliminar las tablas temporales, ya que ir fuera de alcance cuando el procedimiento almacenado sale

+0

Si se produce un error al ejecutar el procedimiento, ¿por qué no se lanza en el método de ejecución? Además, solo estoy usando un solo procedimiento almacenado. – MozenRath

+0

@MozenRath: No lo sé, pero el proceso no se está ejecutando hasta su finalización ... – gbn

1

¿Cómo funciona exactamente la variable @leadscount contiene el recuento de clientes potenciales eliminados?

Este es el único lugar que veo beeing utilizado:

@leadscount SELECT = (SELECT COUNT (*) a partir de PURGE_LEAD);

De todos modos, para probarlo, ¿por qué no ejecuta el código anterior fuera del contexto de la transacción?

Si realmente necesita que esté dentro de una transacción, intente cargar el valor en una variable de tabla (cree una tabla con solo una columna). Como no participan en transacciones, puede probar si la transacción es su problema real.

+0

la tabla purge_lead contiene los identificadores de plomo que se eliminarán, de modo que ese es el conteo de cables eliminados – MozenRath

+0

bien, pero no es necesario estar dentro del alcance de la transacción. – Diego

+0

sí lo hace! También estoy alterando el contenido de la tabla más tarde – MozenRath

3

Esto normalmente ocurre cuando la transacción se inicia y no se confirma o no se revierte.

En caso de que el error ocurra en su procedimiento almacenado, esto puede bloquear las tablas de la base de datos porque la transacción no se completó debido a algunos errores de tiempo de ejecución en ausencia de manejo de excepciones Puede usar el manejo de excepciones como se muestra a continuación. SET XACT_ABORT

SET XACT_ABORT ON 
SET NoCount ON 
Begin Try 
    BEGIN TRANSACTION 
     //Insert ,update queries  
    COMMIT 
End Try 
Begin Catch 
    ROLLBACK 
End Catch 
Cuestiones relacionadas