我想删除一个包含标题、子标题和行项目详细信息的订单,然后再用替换子标题、行项目详细信息现在可能是什么来写出相同的订单。当我尝试用更改写回较新版本时,出现 pk 违规错误。经过分析,我发现即使我的 DELETE 语句似乎有效,但在发出它们(例如 x 行受影响)之后——目标表保持不变。因此,这将解释 pk vio 问题。我错过了什么?
这是其中的一种说法:
-- detail level (drop products)
DELETE dprods FROM [SQLsever].[WIP].[order].DropProducts as dprods
INNER JOIN #dropprods t on t.OrderId = dprods.OrderId
AND t.OrderDropId = dprods.OrderDropId
AND t.DropProdId = dprods.DropProdId;
发出语句后,我仍然在目标表中有所有 200 多行,并且我在 #dropprods 临时表中有 200 多个 ID。为什么?
** 编辑以更好地定义问题** * ** * ** * ** * * DELETE 语句不是问题。该问题与一组嵌套/命名事务有关。DELETE 语句在一个之下,INSERT 语句在另一个之下。这就是我所拥有的。这显然是错误的。我要做的是确保在我知道我会有一个很好的替代 INSERT 之前我不会提交 DELETE。这是我所做的: *EDITED T-SQL WITH SAVE TRANSACTION FIX * ** 这个 TSQL 现在可以工作了。
-- CHANGED
BEGIN TRANSACTION
SAVE TRANSACTION process_orders
BEGIN TRY
-- detail level
DELETE lprods FROM [SQLServer].[WIP].[order].LiftProducts as lprods
INNER JOIN #liftprods t on t.OrderId = lprods.OrderId
AND t.OrderLiftId = lprods.OrderLiftId
AND t.LiftProdId = lprods.LiftProdId;
-- the rest of the deletes
--NOTE: No commit transaction here; saving it to the end
END TRY
BEGIN CATCH
SELECT
ERROR_NUMBER() AS ErrorNumber,
ERROR_SEVERITY() AS ErrorSeverity,
ERROR_MESSAGE() AS ErrorMessage;
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION process_orders;
END CATCH
BEGIN TRANSACTION
-- CHANGED
SAVE TRANSACTION process_orders
BEGIN TRY
-- CHANGED
COMMIT TRANSACTION process_orders;
END TRY
BEGIN CATCH
SELECT
ERROR_NUMBER() AS ErrorNumber,
ERROR_SEVERITY() AS ErrorSeverity,
ERROR_MESSAGE() AS ErrorMessage;
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION process_orders ;
END CATCH