如何摆脱T-SQL中的重复(高效)

时间:2016-03-31 12:12:10

标签: sql sql-server recursion

我有一个遗留代码,用于将大量数据从文本文件导入SQL Server。以前,导入是由遗留的VB6代码完成的,该代码基于一些复杂的逻辑执行对DB的更新/插入。我正在重写它 现在我所做的是将文件中的数据批量复制到临时表中,然后在SQL Server端执行相同的逻辑。第一个问题是逻辑是递归的,但我将其改为迭代代码,然后在SQL Server端实现,从而产生下面的代码。但是生成的SQL使用的是游标和成千上万的查询,这使得它效率极低。我没有大脑重写它以使其高效。也许你们可以帮助我。 以下是有问题的代码:

DECLARE Entgelte86Cursor CURSOR 
 LOCAL FORWARD_ONLY FAST_FORWARD
FOR SELECT 
    ID, IK, ZAHLBETRAG, GUELTIG_AB, GUELTIG_BIS, ABTEILUNG
FROM #ZahlBetragDivided WHERE STELLE_1_4 = '86XX'

OPEN Entgelte86Cursor
    FETCH NEXT FROM Entgelte86Cursor INTO @ID, @IK, @Betrag, @GueltigAb, @GueltigBis, @Drg
    WHILE @@FETCH_STATUS = 0
    BEGIN
        SET @BasisRate = NULL;
        SET @BasisRateAb = NULL;
        SET @BasisRateBis = NULL;

SELECT TOP 1 @BasisRate = EUROBasisrate, @BasisRateAb = GueltigVon, @BasisRateBis = GueltigBis
FROM [KHDRGBetraege] WHERE IKZ = @IK AND @GueltigAb BETWEEN GueltigVon and GueltigBis

WHILE 1=1
BEGIN
    SET @UpdateIKZ = NULL;
    SET @UpdateGueltigAb = NULL;
    SET @UpdateDrg = NULL;

    SELECT TOP 1 @UpdateIKZ = IKZ, @UpdateDrg = DRG, @UpdateGueltigAb = gueltigVon
    FROM [KHSonstEntgBetraege] WHERE IKZ = @IK AND DRG = @Drg AND gueltigVon = @GueltigAb


    IF @UpdateIKZ IS NOT NULL AND @UpdateDrg IS NOT NULL AND @UpdateGueltigAb IS NOT NULL
        IF @BasisRateBis IS NULL OR @GueltigBis <= @BasisRateBis
            BEGIN
            UPDATE [KHSonstEntgBetraege] SET
                EUROBetrag = @Betrag,
                gueltigBis = @GueltigBis,
                CWHaupt = CASE WHEN @BasisRate IS NOT NULL THEN @Betrag / @BasisRate END,
                Aenderungsdat = @UpdateDate,
                Eingabeart = 'E'
            WHERE IKZ = @UpdateIKZ AND DRG = @UpdateDrg AND gueltigVon = @UpdateGueltigAb AND  
            (
                (Eingabeart IS NULL OR Eingabeart = 'E') OR
                (
                    @OverwriteManualDate IS NOT NULL AND Eingabeart = 'M' AND gueltigVon < @OverwriteManualDate
                )
            )
            AND Aenderungsdat <= @UpdateDate

            INSERT INTO @ImportedRecords VALUES('UPDATE', 'DRG-Kennzeichen und Basisrate', 'KHSonstEntgBetraege', @@rowcount)
            END
        ELSE
            BEGIN
            UPDATE [KHSonstEntgBetraege] SET
                EUROBetrag = @Betrag,
                gueltigBis = @BasisRateBis,
                CWHaupt = CASE WHEN @BasisRate IS NOT NULL THEN @Betrag / @BasisRate END,
                Aenderungsdat = @UpdateDate,
                Eingabeart = 'E'
            WHERE IKZ = @UpdateIKZ AND DRG = @UpdateDrg AND gueltigVon = @UpdateGueltigAb
            AND  
            (
                (Eingabeart IS NULL OR Eingabeart = 'E') OR
                (
                    @OverwriteManualDate IS NOT NULL AND Eingabeart = 'M' AND gueltigVon < @OverwriteManualDate
                )
            )
            AND Aenderungsdat <= @UpdateDate

            INSERT INTO @ImportedRecords VALUES('UPDATE', 'DRG-Kennzeichen und Basisrate', 'KHSonstEntgBetraege', @@ROWCOUNT)

            SET @GueltigAb = DATEADD(DAY, 1, @BasisRateBis)

            SELECT TOP 1 @BasisRate = EUROBasisrate, @BasisRateAb = GueltigVon, @BasisRateBis = GueltigBis
                FROM [KHDRGBetraege] WHERE IKZ = @IK AND @GueltigAb BETWEEN GueltigVon and GueltigBis

            CONTINUE
            END
    ELSE
        BEGIN
        INSERT INTO [KHSonstEntgBetraege](IKZ, Drg, GueltigVon, GueltigBis, EUROBetrag, CWHaupt, Aenderungsdat, Eingabeart)
        VALUES (@IK,
                @Drg, 
                @GueltigAb, 
                @GueltigBis, 
                @Betrag, 
                CASE WHEN @BasisRate IS NOT NULL THEN @Betrag / @BasisRate END, 
                @UpdateDate,
                'E'
                )
        INSERT INTO @ImportedRecords VALUES('INSERT', 'DRG-Kennzeichen und Basisrate', 'KHSonstEntgBetraege', @@ROWCOUNT)
        END
    BREAK
END

FETCH NEXT FROM Entgelte86Cursor INTO @ID, @IK, @Betrag, @GueltigAb, @GueltigBis, @Drg
END

CLOSE Entgelte86Cursor
DEALLOCATE Entgelte86Cursor

特别有问题的是我更改@GueltigAb变量(保存日期)然后使用变量的新值继续下一次迭代时的部分。 非常感谢任何建议。

0 个答案:

没有答案