BEGIN ... SET ... END的语法问题

时间:2012-12-21 16:18:22

标签: sql-server-2008 tsql

我编写了以下存储过程,该过程使用Date Dimension表来计算给定开始日期和频率的下一个日期。

每当我有一个IF BEGIN SET IF SET END序列时,我会收到一些奇怪的语法错误。

为了帮助调试,我回过头来在一行IF语句周围添加了不需要的BEGIN和END语句。

我在这里错过了某种类型的BEGIN - END或IF - ELSE匹配规则吗? (我已经用注释标记了解析器抱怨的行。)

CREATE PROCEDURE dbo.GetNextScheduledBusinessDayOccurance
(
  @BeginDate DATE,
  @Frequency CHAR(1)
)
AS
BEGIN
    DECLARE @Date DATETIME,
    @currentDate DATE,
    @weekOfYear INT,
    @dayOfWeek varchar(9),
    @weekOfMonth tinyint,
    @month varchar(2),
    @dayOfQuarter tinyint,
    @currentDayOfQuarter tinyint,
    @quarterOfNextOccurance tinyint,
    @yearOfNextOccurance int;

    SET @currentDate = CONVERT(Date, GETDATE())
    IF (@BeginDate > @currentDate)-- If it hasn't started yet
    BEGIN
        SET @Date = (SELECT TOP(1) [DATE] FROM dbo.dim_Date WHERE [DATE] >= @BeginDate AND [Date] > @currentDate AND (IsBusinessDay = 1) ORDER BY [DATE])
    END
    ELSE
        BEGIN
            IF @Frequency = 'A' --Annually
            BEGIN
                SET @Date = (SELECT TOP(1) [DATE] FROM dbo.dim_Date WHERE ([DATE] > @currentDate AND [Month] >= DATEPART(MONTH, @BeginDate) AND [Day] >= DATEPART(DAY, @BeginDate) AND IsBusinessDay = 1) ORDER BY [Date])
            END
            ELSE IF @Frequency = 'B' --Biweekly
                BEGIN
                    SET @weekOfYear = (SELECT WeekOfYear FROM dbo.dim_Date WHERE [Date] = @BeginDate)
                    SET @dayOfWeek = (SELECT [DayOfWeek] FROM Dbo.dim_Date WHERE [Date] >= @BeginDate AND IsBusinessDay = 1)
                    SET @Date = ((SELECT TOP(1) [Date] FROM dbo.dim_Date WHERE ([DATE] > @currentDate AND [WeekOfYear]%2 = @weekOfYear%2 AND [DayOfWeek] = @dayOfWeek AND IsBusinessDay = 1) ORDER BY [Date]))
                END
            ELSE IF @Frequency = 'D' --Daily
                BEGIN
                    SET @Date = ((SELECT TOP(1) [Date] FROM dbo.dim_Date WHERE ([DATE] > @currentDate AND IsBusinessDay = 1) ORDER BY [Date]))
                END
            ELSE IF @Frequency = 'E' -- Semi-Monthly (twice each month) (assume the 15th and last day of month)
                BEGIN
                    -- GET the next 15th or last day of month.
                    SET @Date = (SELECT TOP(1) [Date] FROM dim_Date WHERE [Date] > @currentDate AND (Day = '15' OR (DateAdd(day, -1, DateAdd( month, DateDiff(month , 0,[Date])+1 , 0)) = [Date])) ORDER BY [Date])
                    IF ((SELECT IsBusinessDay FROM dim_Date WHERE [Date] = @Date) = 0)
                    BEGIN
                        SET @Date = ((SELECT TOP(1) [Date] FROM dbo.dim_Date WHERE (([DATE] > @Date) AND IsBusinessDay = 1) ORDER BY [Date])
                    END --Parser ERROR: Incorrect syntax near the keyword 'END'.
                END
            ELSE IF @Frequency = 'I' --Bimonthly (Every other month)
                BEGIN
                    SET @Month = (SELECT Month FROM dbo.dim_Date WHERE [Date] = @BeginDate)
                    SET @Date = (SELECT TOP(1) [Date] FROM dbo.dim_Date WHERE ([Date] > @currentDate AND [Month]%2 = @Month%2 AND [Day] = DATEPART(day, @BeginDate)) ORDER BY [Date])
                    IF ((SELECT IsBusinessDay FROM dim_Date WHERE [Date] = @Date) = 0)
                    BEGIN
                        SET @Date = ((SELECT TOP(1) [Date] FROM dbo.dim_Date WHERE (([DATE] > @Date) AND IsBusinessDay = 1) ORDER BY [Date])
                    END --Parser ERROR: Incorrect syntax near the keyword 'END'.
                END
            ELSE IF @Frequency = 'L' --Last Business Day of the Month
                BEGIN
                    SET @Date = (SELECT TOP(1) [Date] FROM dim_Date WHERE [Date] > '2013-03-20 00:00:00.000' AND  (DateAdd(day, -1, DateAdd( month, DateDiff(month , 0,[Date])+1 , 0)) = [Date]) ORDER BY [Date])
                    IF ((SELECT IsBusinessDay FROM dim_Date WHERE [Date] = @Date) = 0)
                    BEGIN
                        SET @Date = ((SELECT TOP(1) [Date] FROM dbo.dim_Date WHERE (([DATE] < @Date) AND IsBusinessDay = 1) ORDER BY [Date] DESC))
                    END
                END     
            ELSE IF @Frequency = 'M'  -- Monthly
                BEGIN
                    SET @Date = (SELECT TOP(1) [Date] FROM dim_Date WHERE [Date] > @currentDate AND (Day > DATEPART(day, @BeginDate)) ORDER BY [Date])
                    IF ((SELECT IsBusinessDay FROM dim_Date WHERE [Date] = @Date) = 0)
                    BEGIN
                        SET @Date = ((SELECT TOP(1) [Date] FROM dbo.dim_Date WHERE (([DATE] > @Date) AND IsBusinessDay = 1) ORDER BY [Date])
                    END--Parser ERROR: Incorrect syntax near the keyword 'END'.
                END
            ELSE
            IF @Frequency = 'Q' --Quarterly
                BEGIN
                    SET @dayOfQuarter = (Select DayOfQuarter FROM dim_Date WHERE [DATE] = @BeginDate)
                    SET @currentDayOfQuarter = (Select DayOfQuarter FROM dim_Date WHERE [DATE] = @currentDate)
                    SET @quarterOfNextOccurance = (SELECT [Quarter] FROM dbo.dim_Date WHERE [Date] = @currentDate)
                    SET @yearOfNextOccurance = (SELECT [Year] FROM dbo.dim_Date WHERE [Date] = @currentDate)
                    --SELECT @dayOfQuarter DOQ, @currentDayOfQuarter curDOQ, @quarterOfNextOccurance QofNext, @yearOfNextOccurance YofNext
                    IF (@currentDayOfQuarter >= @dayOfQuarter)
                        SET @quarterOfNextOccurance = @quarterOfNextOccurance + 1
                    SET @Date = '1900-01-01'
                    WHILE (@Date < @currentDate) --Loop through this just in case we're close to the end of the Quarter, and there's no more business days left
                        BEGIN
                            IF (@quarterOfNextOccurance > 4)
                                BEGIN
                                    SET @quarterOfNextOccurance = @quarterOfNextOccurance%4
                                    SET @yearOfNextOccurance = @yearOfNextOccurance + 1         
                                END
                            --SELECT @quarterOfNextOccurance QofNext, @yearOfNextOccurance YofNext
                            --CREATE a temp table with all of the business dates from the target quarter in decending order.
                            SELECT * INTO ##temp FROM (SELECT TOP(92) [Date], MAX(DayOfQuarter) as DOQ FROM dim_Date WHERE (YEAR = @yearOfNextOccurance AND Quarter = @quarterOfNextOccurance AND IsBusinessDay = 1) Group By Date ORDER BY Date DESC) as foo
                            SET @Date = (SELECT TOP(1) DATE from ##temp WHERE DOQ <= @dayOfQuarter)
                            SET @quarterOfNextOccurance = @quarterOfNextOccurance + 1 -- Go ahead and incriment this just in case we start the WHILE over.
                            --SELECT * FROM ##temp
                            BEGIN TRY DROP TABLE ##temp END TRY BEGIN CATCH END CATCH
                        END
                END
            ELSE
            IF @Frequency = 'S' --Semi-annually
                BEGIN
                    SET @Date = @BeginDate
                    WHILE (@Date < @currentDate)
                    BEGIN
                        SET @Date = (SELECT [Date] FROM dbo.dim_Date WHERE [Date] = DATEADD(MONTH, 6, @Date))
                    END
                    IF ((SELECT IsBusinessDay FROM dim_Date WHERE [Date] = @Date) = 0)
                    BEGIN
                        SET @Date = ((SELECT TOP(1) [Date] FROM dbo.dim_Date WHERE (([DATE] > @Date) AND IsBusinessDay = 1) ORDER BY [Date])
                    END--Parser ERROR: Incorrect syntax near the keyword 'END'.
                END
            ELSE
            IF @Frequency = 'W' --Weekly
                BEGIN
                    SET @dayOfWeek = (SELECT [DayOfWeek] FROM dbo.dim_Date WHERE [Date] = @BeginDate)
                    SET @Date = (SELECT TOP(1) [Date] FROM Dbo.dim_Date WHERE DayOfWeek = @dayOfWeek AND [DATE] < @currentDate ORDER BY [DATE] DESC)
                    --SELECT @Date DATE, @BeginDate BeginDate
                    WHILE ((@Date < @currentDate) OR (@Date < @BeginDate))
                    BEGIN
                        SET @Date = (SELECT [Date] FROM dbo.dim_Date WHERE [Date] = DATEADD(Week, 1, @Date))
                        --SELECT @Date DateInWHile
                    END
                    IF ((SELECT IsBusinessDay FROM dim_Date WHERE [Date] = @Date) = 0)
                        SET @Date = (SELECT TOP(1) [Date] FROM dbo.dim_Date WHERE (([DATE] > @Date) AND IsBusinessDay = 1) ORDER BY [Date])
                    --SELECT @Date
                END
            ELSE
                SET @Date = NULL
        END
        RETURN @Date
END

GO

1 个答案:

答案 0 :(得分:2)

您错过了结束)

BEGIN
  SET @Date = ((
    SELECT TOP(1) [Date] 
    FROM dbo.dim_Date 
    WHERE (([DATE] > @Date) AND IsBusinessDay = 1) 
    ORDER BY [Date]) ) -- Paren added here...
END --Parser ERROR: Incorrect syntax near the keyword 'END'.