EXECUTE之后的事务计数表示BEGIN和COMMIT语句的数量不匹配.以前算了

Moz*_*ath 7 java database sql-server stored-procedures jdbc

我得到关于提交和回滚的这个例外,但我不确定我的存储过程究竟出了什么问题.我已经阅读了其他类似问题的答案,但我无法找到确切的提交计数在哪里搞砸了.

所以,这是我使用的存储过程:

-- 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
Run Code Online (Sandbox Code Playgroud)

现在我在以下代码中调用此过程:

    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());
    }
Run Code Online (Sandbox Code Playgroud)

我在线上说了一个例外 int rowcount = cs.getInt(2);

例外情况是:

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)
Run Code Online (Sandbox Code Playgroud)

请帮帮我.在com.microsoft.sqlserver.jdbc.SQLServerCallableStatement.getValue(SQLServerCallableStatement.java:393)位于marketsoft.tools.purge.PurgeUtils.PurgeLeads(PurgeUtils)的com.microsoft.sqlserver.jdbc.SQLServerCallableStatement.getInt(SQLServerCallableStatement.java:437)的.java:283)

编辑:

因为我自己已经回答了这个问题......我现在想改变一下这个问题.

为什么在execute方法中没有抛出异常???

gbn*_*gbn 14

您的COMMIT未被命中,可能是因为错误.该事务不会自动回滚

最好的方法(和最佳实践)是添加一些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
Run Code Online (Sandbox Code Playgroud)

有关此处发生了什么的更多详细信息,请参阅此处的答案包含TRY CATCH ROLLBACK模式的嵌套存储过程?

注意:当存储过程退出时,您不需要删除临时表,因为它们超出范围


Ole*_*Dok 7

尝试在程序开始时添加

SET XACT_ABORT ON
Run Code Online (Sandbox Code Playgroud)

要么

用你的陈述包裹你的陈述

begin try 
  BEGIN TRANSACTION 
 Your TSQL code

  COMMIT
end try 
begin catch 
  ROLLBACK
  RAISERROR('Gotcha!', 16, 1)
end catch
Run Code Online (Sandbox Code Playgroud)

要检查BEGIN TRAN打开的未提交的数量,请测试@@TRANCOUNT系统变量


Moz*_*ath 2

对不起大家!感谢大家的努力,最后,这是我在存储过程中的一个很小的错误:

看行:

if @purgextns = 1 begin
    DELETE FROM LEADEXTENSIONS WHERE 
        SEQID  IN (SELECT ID FROM PURGE_LEAD_E)
end
Run Code Online (Sandbox Code Playgroud)

它应该是#PURGE_LEAD_E

您的所有回答都帮助我对存储过程开发有了不同的看法。多谢!