T-SQL中的while子句永远循环
我最近负责调试电子商务应用程序中的一个奇怪问题.应用程序升级后,站点开始不时挂起,我被派去调试.检查事件日志后,我发现SQL服务器在几分钟内写了大约200 000个事件,并显示一条约束失败的消息.经过大量调试和一些追踪后,我找到了罪魁祸首.我已经删除了一些不必要的代码并清理了一下但基本上就是这样
WHILE EXISTS (SELECT * FROM ShoppingCartItem WHERE ShoppingCartItem.PurchID = @PurchID) BEGIN SELECT TOP 1 @TmpGFSID = ShoppingCartItem.GFSID,@TmpQuantity = ShoppingCartItem.Quantity,@TmpShoppingCartItemID = ShoppingCartItem.ShoppingCartItemID,FROM ShoppingCartItem INNER JOIN GoodsForSale on ShoppingCartItem.GFSID = GoodsForSale.GFSID WHERE ShoppingCartItem.PurchID = @PurchID EXEC @ErrorCode = spGoodsForSale_ReverseReservations @TmpGFSID,@TmpQuantity IF @ErrorCode <> 0 BEGIN Goto Cleanup END DELETE FROM ShoppingCartItem WHERE ShoppingCartItem.ShoppingCartItemID = @TmpShoppingCartItemID -- @@ROWCOUNT is 1 after this END 事实: >只有一个或两个记录与第一个select子句匹配 该程序已被重写,以选择应删除到临时内存表中的行,以便立即解决问题,但这确实引起了我的好奇心. 它为什么永远循环? 说明:删除不会失败(调试后删除stmt后@@ rowcount为1) 更新:检查颠覆日志后,我发现了使这个存储过程变得混乱的罪魁祸首提交.我能找到的唯一真正的区别是,以前没有SELECT TOP 1语句中的连接,即没有连接,它没有任何围绕删除的事务语句.似乎是连接的引入使SQL服务器更加挑剔. 更新澄清:brien指出不需要连接,但我们确实使用了GoodsForSale表中的一些字段,但我已将它们删除以保持代码简单,以便我们可以专注于手头的问题 解决方法您是在显式还是隐式操作 transaction mode?由于您处于显式模式,我认为您需要使用BEGIN TRANSACTION和COMMIT TRANSACTION语句包围DELETE操作. WHILE EXISTS (SELECT * FROM ShoppingCartItem WHERE ShoppingCartItem.PurchID = @PurchID) BEGIN SELECT TOP 1 @TmpGFSID = ShoppingCartItem.GFSID,FROM ShoppingCartItem INNER JOIN GoodsForSale on ShoppingCartItem.GFSID = GoodsForSale.GFSID WHERE ShoppingCartItem.PurchID = @PurchID EXEC @ErrorCode = spGoodsForSale_ReverseReservations @TmpGFSID,@TmpQuantity IF @ErrorCode <> 0 BEGIN Goto Cleanup END BEGIN TRANSACTION delete DELETE FROM ShoppingCartItem WHERE ShoppingCartItem.ShoppingCartItemID = @TmpShoppingCartItemID -- @@ROWCOUNT is 1 after this COMMIT TRANSACTION delete END 澄清:您需要使用事务的原因是,在执行COMMIT操作之前,删除实际上不会发生在数据库中.当您在原子事务中有多个写操作时,通常会使用此方法.基本上,如果所有操作都成功,您只希望更改发生在数据库中. 在您的情况下,只有一个操作,但由于您处于显式事务模式,您需要告诉SQL Server真正进行更改. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 在自动生成的数据库脚本中,tsql – CONTAINMENT被标记为不正
- uniqueidentifier转换成varchar数据类型的sql语句
- sql-server-2008 – 简单语法:Alter Table语句中的多个约束
- MSSQLServer SQL备份与还原数据库
- sql – 使用ORM进行大容量数据库更新
- 如何删除Openshift应用程序上的数据库盒?
- sql server连接不上怎么办 SQL Server2008R无法登录的解决方
- .net – 删除LINQ to SQL记录而不先加载它
- 在SQLSERVER中获得不包含时间部分的日期
- sql-server – 只安装SSIS而不是整个SQL Server系统?