当前位置:  开发笔记 > 编程语言 > 正文

T-SQL中的while子句永远循环

如何解决《T-SQL中的while子句永远循环》经验,为你挑选了0个好方法。

我最近负责调试电子商务应用程序中的一个奇怪问题.应用程序升级后,站点开始不时挂起,我被派去调试.检查事件日志后,我发现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子句

    DELETE语句中的RowCount表示它已被删除

    WHILE子句将永远循环

该程序已被重写,以选择应删除到临时内存表中的行,以便解决当前问题,但这确实引起了我的好奇心.

它为什么永远循环?

澄清:删除不会失败(调试后删除stmt后@@ rowcount为1)说明 2:SELECT TOP ...子句是否由任何特定字段排序,因为记录与返回的id将被删除,因此在下一个循环中它应该得到另一条记录.

更新:检查了subversion日志后,我发现了使这个存储过程变得混乱的罪魁祸首提交.我能找到的唯一真正的区别是,之前没有SELECT TOP 1语句中的连接,即没有连接它没有任何围绕删除的事务语句.它似乎是引入了使SQL服务器更加挑剔的连接.

更新澄清: brien指出不需要连接,但我们实际上使用了GoodsForSale表中的一些字段,但我已将它们删除以保持代码简单,以便我们可以专注于手头的问题

推荐阅读
手机用户2402852307
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有