我在存储过程中收到此错误。
EXECUTE之后的事务计数表示BEGIN和COMMIT语句的数量不匹配。先前的计数= 1,当前计数= 0。
我通读了一些答案,发现如果我没有提交就返回,我就会收到错误。我的存储过程是这样的:
BEGIN TRY
BEGIN
if @id is null
BEGIN
set @id= (SELECT last_sequence_value FROM table_name WHERE sequence_name = 'id') + 1
BEGIN
BEGIN TRANSACTION
-- update SQL statement here
IF @@ROWCOUNT = 0
BEGIN
ROLLBACK TRANSACTION
RAISERROR('There was an error getting unique id in the table.',10,1)
RETURN
END
IF (@@ERROR <> 0)
BEGIN
ROLLBACK TRANSACTION
RAISERROR('There was an error updating record to the table',10,1)
RETURN
END
COMMIT TRANSACTION
END
END
else
BEGIN
-- some sql select statements
END
END
END TRY
BEGIN CATCH
-- Raise an error with the details of the exception
RAISERROR(@ErrMsg, @ErrSeverity, 1) WITH SETERROR
END CATCH
从上面的代码中,我正在进行回滚并从存储过程返回。然而,当我在perf测试环境中运行它时,我得到了前面提到的错误。
请帮忙解决这个问题。
答案 0 :(得分:1)
我已经通过添加
修复了它IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION
在我发出错误之前,在catch块中。
感谢大家的精彩投入。
答案 1 :(得分:0)
我有一个用户在我继承的代码中报告了同样的错误,但它是由在 sproc 内部使用事务和 try/catch 以及在 VB.Net System.Transactions 内部调用 sproc 的组合引起的。 TransactionScope 块也是如此。如果 sproc 中出现错误,sproc 会正确回滚那里的所有内容,但它显然也回滚了 VB.Net 事务并造成了不匹配。我的解决方法是从 sproc 中删除事务代码和 try/catch 块,因为如果 sproc 失败或其他处理在 VB.Net 事务中完成,VB.Net 事务将回滚 sproc 内的所有插入/更新块也失败了。希望这会为其他人节省一天的挫败感。
答案 2 :(得分:-1)
这里你应该在开始交易中使用try catch blog。像这样
BEGIN
if @id is null
BEGIN
set @id= (SELECT last_sequence_value FROM table_name WHERE sequence_name = 'id') + 1
BEGIN
BEGIN TRANSACTION
BEGIN TRY
-- update SQL statement here
IF @@ROWCOUNT = 0
BEGIN
ROLLBACK TRANSACTION
RAISERROR('There was an error getting unique id in the table.',10,1)
RETURN
END
IF (@@ERROR <> 0)
BEGIN
ROLLBACK TRANSACTION
RAISERROR('There was an error updating record to the table',10,1)
RETURN
END
END TRY
BEGIN CATCH
-- Raise an error with the details of the exception
RAISERROR(@ErrMsg, @ErrSeverity, 1) WITH SETERROR
END CATCH
COMMIT TRANSACTION
END
END
else
BEGIN
-- some sql select statements
END
END
答案 3 :(得分:-1)
首先,比较
DECLARE @ErrorVar INT
RAISERROR(N'Message', 16, 1);
IF @@ROWCOUNT <> 0
PRINT 'Rows <> 0'
IF @@ERROR <> 0
PRINT N'Error = ' + CAST(@@ERROR AS NVARCHAR(8));
GO
这个
DECLARE @ErrorVar INT,
@Error INT,
@Cnt INT
RAISERROR(N'Message', 16, 1);
SELECT @ERROR = @@ERROR, @Cnt = @@ROWCOUNT
IF @Cnt <> 0
PRINT 'Rows 0'
IF @ERROR <> 0
PRINT N'Error = ' + CAST(@@ERROR AS NVARCHAR(8));
GO
https://docs.microsoft.com/en-us/sql/t-sql/functions/error-transact-sql 因为@@ ERROR在每个执行的语句中被清除并重置,所以在验证语句之后立即检查它,或者将其保存到稍后可以检查的本地变量中。 +