运行更新语句时出错。 对于一个记录,它工作正常,但对于一大块记录,它给了我一个错误。
另外,为什么它告诉我64801行受影响然后1行受影响然后0?我该如何解释?
这是剧本:
update tblQuotes
set QuoteStatusID = 11, --Not Taken Up
QuoteStatusReasonID = 9 --"Not Competitive"
where CAST(EffectiveDate as DATE) < CAST('2013-11-27' as DATE)
and CompanyLocationGuid = '32828BB4-E1FA-489F-9764-75D8AF7A78F1' -- Plaza Insurance Company
and LineGUID = '623AA353-9DFE-4463-97D7-0FD398400B6D' --Commercial Auto
我添加了BEGIN TRANSACTION
声明,但它仍然无法正常工作。
BEGIN TRANSACTION
update tblQuotes
set QuoteStatusID = 11, --Not Taken Up
QuoteStatusReasonID = 9 --"Not Competitive"
where CAST(EffectiveDate as DATE) < CAST('2017-11-27' as DATE)
AND CompanyLocationGuid = '32828BB4-E1FA-489F-9764-75D8AF7A78F1' -- Plaza Insurance Company
and LineGUID = '623AA353-9DFE-4463-97D7-0FD398400B6D' --Commercial Auto
IF @@TRANCOUNT>0
COMMIT TRANSACTION
答案 0 :(得分:2)
在我看来,这是一个“缺陷”,如果不是SQL Server中的“bug”。当您执行COMMIT事务时,TRANCOUNT减1.当您ROLLBACK任何事务时,调用堆栈中的所有事务都将回滚!这意味着任何尝试提交或回滚的调用过程都会出现此错误,并且您已经失去了调用堆栈的完整性。
在构建机制时,我在SQL Server上进行单元测试。我总是使用命名事务来解决它,如下例所示。你显然也可以查看XACT_STATE。关键在于,如果您按名称或事务ID管理事务,则可以更好地控制,而不是盲目地提交和回滚匿名事务。
对于单元测试,我将存储过程编写为调用测试过程的测试。单元测试处于可序列化或快照模式,并且仅包含回滚语句。我调用测试中的过程,验证结果,构建测试输出(通过/失败,参数等)作为XML输出,然后一切都回滚。这避免了构建“模拟数据”的需要。我可以在任何环境中使用数据,因为事务总是回滚。
--
-- get @procedure from object_name(@@procid)
-------------------------------------------------
DECLARE @procedure SYSNAME = N'a_procedure_name_is_a_synonym_so_can_be_longer_than_a_transaction_name'
, @transaction_id BIGINT;
DECLARE @transaction_name NVARCHAR(32) = RIGHT(@procedure + N'_tx', 32);
--
BEGIN TRANSACTION @transaction_name;
BEGIN
SELECT @transaction_id = [transaction_id]
FROM [sys].[dm_tran_active_transactions]
WHERE [name] = @transaction_name;
SELECT *
FROM [sys].[dm_tran_active_transactions]
WHERE [name] = @transaction_name;
-- Perform work here
END;
IF EXISTS
(SELECT *
FROM [sys].[dm_tran_active_transactions]
WHERE [name] = @transaction_name)
ROLLBACK TRANSACTION @transaction_name;
答案 1 :(得分:1)
此错误表明在SQL Server中,您已指定Commit或Commit Transaction而未指定Begin Transaction,或者提交事务的数量大于begin transaction的数量。为避免这种情况,请确保在提交之前检查当前会话中的现有事务。
因此,正常的提交交易将更新如下
IF @@TRANCOUNT>0
COMMIT TRANSACTION
答案 2 :(得分:0)
有一个触发器,可确保QuoteStatusID的完整性。因此,我的WHERE子句我必须准确指定当前状态ID策略必须具有哪些才能进行更新。