sql server中cursor的替代方法是什么

时间:2014-05-05 11:21:56

标签: sql-server-2008

我有一个已经编写的存储过程,它使用了游标。我想删除此光标,并希望使用替代方法以获得更好的查询性能。以下是程序:

ALTER PROCEDURE [dbo].[usp_AOTGetExistingAccountInfoByAcctNum]
@AcctNum VARCHAR(50),
@AcctId INT = NULL
AS
BEGIN
DECLARE @GoodStandingAcctsTotal INT = 0
DECLARE @BadStandingAcctsTotal INT  = 0
DECLARE @ExistingAcctsTotal INT     = 0

DECLARE @GoodStandingAccts INT
DECLARE @BadStandingAccts INT
DECLARE @ExistingAccts INT

-- Temporary table created to suppress the result of procedure usp_naCheckExistingAccts in resultset
DECLARE @Temp table (ExistingAccts INT, GoodStandingAccts INT, BadStandingAccts INT, ClosedAccts INT)

DECLARE ExistingAcctCursor CURSOR FOR 
    (SELECT app.TaxID FROM DMApplicant app JOIN DMAccount acc ON app.CustNum = acc.CustNum where acc.AcctNum = @AcctNum)
DECLARE @TaxId INT
OPEN ExistingAcctCursor
FETCH NEXT FROM ExistingAcctCursor INTO @TaxId
WHILE @@FETCH_STATUS = 0  
BEGIN
INSERT INTO @Temp 
    EXEC dbo.usp_naCheckExistingAccts  @TaxID, @ExistingAccts OUTPUT, @GoodStandingAccts OUTPUT, @BadStandingAccts OUTPUT

SET @GoodStandingAcctsTotal = @GoodStandingAcctsTotal + @GoodStandingAccts
SET @BadStandingAcctsTotal = @BadStandingAcctsTotal + @BadStandingAccts
SET @ExistingAcctsTotal = @ExistingAcctsTotal + @ExistingAccts

FETCH NEXT FROM ExistingAcctCursor INTO @TaxId
END
CLOSE ExistingAcctCursor
DEALLOCATE ExistingAcctCursor

DECLARE @FloatException VARCHAR(10)

SELECT @FloatException = CASE 
WHEN isRemoveHold IS NULL THEN ''
                        WHEN isRemoveHold = 1 THEN 'Yes' 
                        WHEN isRemoveHold = 0 THEN 'No' 
                    END 
                FROM Account WHERE AcctID = @AcctId

Select  
dm.AcctNum,
dm.BranchDesc,
dm.AcctTypeNum,
dm.AcctTypeDesc,
dm.Acct_stat_cde,
dm.Lst_Dp_Amt,
dm.dtLastDeposit,
dm.dtOpen,
dm.dtLastTransaction,
dm.Prev_Day_Ytd_Avg_Lgr_Bal,
dm.TME_NSF_YTD_CNT,
dm.RTN_ITM_YTD_CNT,
dm.Avail_Bal,
dm.AVG_NEG_LGR_BAL,
@FloatException AS isRemoveHold,
CASE WHEN @BadStandingAcctsTotal = 0 AND @GoodStandingAcctsTotal  > 0 THEN 'Yes' ELSE 'No' END AS isGoodStanding
From    
AccountMatchExisting ame JOIN DMAccount dm ON RIGHT(Replicate('0',16) + ame.AcctNumMatch, 16) = RIGHT(Replicate('0',16) + dm.AcctNum, 16),
AccountmatchExisting am JOIN Account acc ON am.AcctNumMatch = acc.AcctNum 
WHERE 
dm.AcctNum = @AcctNum

END

可以在上面的存储过程中使用表变量吗?

1 个答案:

答案 0 :(得分:0)

我在表变量的帮助下解决了它,并从中删除了游标的使用。以下是我使用的代码:

DECLARE @AcctNum VARCHAR(50)='00011001990'
DECLARE @AcctId INT = 58281
DECLARE @GoodStandingAcctsTotal INT = 0
DECLARE @GoodStandingAccts INT
DECLARE @BadStandingAccts INT
DECLARE @ExistingAccts INT
DECLARE @BadStandingAcctsTotal INT  = 0
DECLARE @ExistingAcctsTotal INT     = 0
DECLARE @i INT=1
DECLARE @count INT
DECLARE @TaxIDs VARCHAR(20)
DECLARE @maxCount INT 
DECLARE @TableVariable TABLE 
(
 Id INT IDENTITY(1,1),
 TaxID VARCHAR(20)
)    
DECLARE @Temp table (ExistingAccts INT, GoodStandingAccts INT, BadStandingAccts INT, ClosedAccts INT)

--Table Variable Use
INSERT INTO @TableVariable(TaxID)
   SELECT app.TaxID FROM DMApplicant app JOIN DMAccount acc ON app.CustNum = acc.CustNum where acc.AcctNum = @AcctNum
   SELECT @maxCount=COUNT(Id) FROM @TableVariable
   WHILE(@i<=@maxCount)
    BEGIN
        SELECT @TaxIDs=TaxID from @TableVariable WHERE Id=@i
        INSERT INTO @Temp 
        EXEC dbo.usp_naCheckExistingAccts  @TaxIDs, @ExistingAccts OUTPUT, @GoodStandingAccts OUTPUT, @BadStandingAccts OUTPUT

        SET @GoodStandingAcctsTotal = @GoodStandingAcctsTotal + @GoodStandingAccts
        SET @BadStandingAcctsTotal = @BadStandingAcctsTotal + @BadStandingAccts
        SET @ExistingAcctsTotal = @ExistingAcctsTotal + @ExistingAccts
        SET @i=@i+1

    END