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

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

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

-- 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 

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

  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()); } 

我在行上得到一个exception,说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) 

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

编辑:

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

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

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

最好的方法(和最佳实践)是添加一些SQLerror handling

 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 

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

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

尝试在程序开始时添加

 SET XACT_ABORT ON 

要么

用你的语句包装

 begin try BEGIN TRANSACTION Your TSQL code COMMIT end try begin catch ROLLBACK RAISERROR('Gotcha!', 16, 1) end catch 

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

这通常发生在事务启动并且未提交或未回滚时。

如果存储过程中出现错误,则可能会锁定数据库表,因为在没有exception处理的情况下由于某些运行时错误而未完成事务您可以使用如下所述的exception处理。 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 

对不起大家! 感谢您的所有努力,最后,我在存储过程中犯了一个非常小的错误:

看看行:

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

它应该是#PURGE_LEAD_E

您的所有答案都帮助我了解了商店流程开发的不同视角。 非常感谢!

@leadscount变量究竟是如何包含已删除的潜在客户数的?

这是我看到它唯一使用的地方:

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

无论如何,要测试它,为什么不在事务的上下文之外运行上面的代码?

如果您确实需要它在事务内部,请尝试将值加载到表变量中(创建一个只有一列的表)。 由于他们不参与交易,您可以测试交易是否是您真正的问题。