2012-12-21 25 views
3

我写了使用日期维度表来计算给定开始日期和频率的日期的下一个出现以下存储过程。语法问题与BEGIN ... SET ... END

我越来越似乎每当我有一个IF BEGIN SET如果设置END顺序发生一些奇怪的语法错误。

为了帮助调试,我已经回到和增加不必要的BEGIN和周围的一行IF语句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 

回答

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'. 
+0

谢谢您的括号福! – NathanC

+1

@NathanC不客气......扔代码到一个不同的IDE,突出匹配的括号会很有帮助。在这种情况下,我只是把它变成记事本++ ... –

+0

SSMS 2012确实在括号匹配了很好的工作,所以这是一个选项太(尤其是现在,它是完全免费)。您仍然可以管理旧版本,并且可以节省编辑器之间的交换代码。 –