sql - 帮助用更好的代码替换这个 SQL 游标

标签 sql sql-server-2000 cursors

谁能帮助我提高 SQL 2000 中游标逻辑的性能。它在 SQl2005 和 SQL2008 中运行良好,但在 SQL 2000 中运行至少需要 20 分钟。顺便说一句,我永远不会选择使用游标,我没有编写这段代码,只是想让它运行得更快。短期内无法将此客户端升级到 2005/2008。

-------------------------------------------------------------------------------
------- Rollup totals in the chart of accounts hierarchy
-------------------------------------------------------------------------------
DECLARE @B_SubTotalAccountID int, @B_Debits money, @B_Credits money, @B_YTDDebits money, @B_YTDCredits money

DECLARE Bal CURSOR FAST_FORWARD FOR 
 SELECT SubTotalAccountID, Debits, Credits, YTDDebits, YTDCredits FROM xxx 
  WHERE AccountType = 0 AND SubTotalAccountID Is Not Null and (abs(credits)+abs(debits)+abs(ytdcredits)+abs(ytddebits)<>0)
OPEN Bal

FETCH NEXT FROM Bal INTO @B_SubTotalAccountID, @B_Debits, @B_Credits, @B_YTDDebits, @B_YTDCredits

--For Each Active Account
WHILE @@FETCH_STATUS = 0
 BEGIN

 --Loop Until end of subtotal chain is reached
 WHILE @B_SubTotalAccountID Is Not Null
  BEGIN

  UPDATE xxx2
  SET Debits = Debits + @B_Debits,
   Credits = Credits + @B_Credits,
   YTDDebits = YTDDebits + @B_YTDDebits,
   YTDCredits = YTDCredits + @B_YTDCredits
  WHERE GLAccountID = @B_SubTotalAccountID

  SET @B_SubTotalAccountID = (SELECT SubTotalAccountID FROM xxx2 WHERE GLAccountID = @B_SubTotalAccountID)

  END

 FETCH NEXT FROM Bal INTO @B_SubTotalAccountID, @B_Debits, @B_Credits, @B_YTDDebits, @B_YTDCredits

 END

CLOSE Bal
DEALLOCATE Bal

最佳答案

Update xx2
Set Credits = Credits + X1.CreditTotal
    , Debits = Debits + X1.DebitTotal
    , YtdDebits = YtdDebits + X1.YtdDebitTotal
    , YtdCredits = YtdCredits + X1.YtdDebitTotal
From xx2 As X2
    Join    (
            Select SubTotalAccountID, Sum(Debits) As DebitTotal, Sum(Credits) As CreditTotal
                , Sum(YtdDebits) As YtdDebitTotal, Sum(YtdCredits) As YtdCreditTotal
            From xxx
            Where AccountType = 0 
                And SubTotalAccountID Is Not Null 
                And (
                    Credits <> 0
                    Or Debits <> 0
                    Or YtdCredits <> 0
                    Or YtdDebits <> 0
                    )
            Group By SubTotalAccountID
            ) As X1
        On X1.SubTotalAccountID = X2.GLAccountID

如果没有架构,我无法判断 xxx 表是否会为给定的 SubTotalAccountId 返回多行。我假设它可以按此列对值进行分组,以便每个 SubTotalAccountId 获得一行。

我还用简单的零检查替换了 WHERE 子句中对 ABS 的使用。这应该会快得多。

此 UPDATE 语句应该完全替代您的游标。

关于sql - 帮助用更好的代码替换这个 SQL 游标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2653720/

相关文章:

sql - 这条sql语句的推荐写法是什么?

sql-server-2000 - 如何在 SQL Server 中禁用字符串截断错误?

sql - 保持 SQL 游标打开的 "reasonable"时间长度是多少?

SQL 查询间歇性返回无结果

php - 如何一次获取所有选定的 ID? PHP/MySQL 问题

MYSQL - 加入三个表

sql-server - SQL 服务器 : how to determine what will break when downgrading a database?

sql - 伪造 SQL Server

sql - 巨大表的 MSSQL 游标无法分配空间