проблема с обновлением: я просто хочу обновить столбец past или future до 0 или 1 в зависимости от даты, и я не могу заставить его работать, кто-нибудь может мне помочь?

#sql #sql-server #tsql

#sql #sql-сервер #tsql

Вопрос:

     IF OBJECT_ID('dbo.DimensionDate', 'U') IS NOT NULL
          DROP TABLE dbo.DimensionDate

    /**********************************************************************************/

    CREATE TABLE    [dbo].[DimensionDate]
        (   [DateKey] INT primary key, 
            [Date] DATETIME,
            [FullDate] CHAR(10),-- Date in dd-MM-yyyy format
            [DayOfMonth] VARCHAR(2), -- Field will hold day number of Month
            [DaySuffix] VARCHAR(4), -- Apply suffix as 1st, 2nd ,3rd etc
            [DayName] VARCHAR(9), -- Contains name of the day, Sunday, Monday 
            [DayOfWeekIRE] CHAR(1),-- First Day Monday=1 and Sunday=7
            [DayOfWeekInMonth] VARCHAR(2), --1st Monday or 2nd Monday in Month
            [DayOfWeekInYear] VARCHAR(2),
            [DayOfQuarter] VARCHAR(3),
            [DayOfYear] VARCHAR(3),
            [WeekOfMonth] VARCHAR(1),-- Week Number of Month 
            [WeekOfQuarter] VARCHAR(2), --Week Number of the Quarter
            [WeekOfYear] VARCHAR(2),--Week Number of the Year
            [Month] VARCHAR(2), --Number of the Month 1 to 12
            [MonthName] VARCHAR(9),--January, February etc
            [MonthOfQuarter] VARCHAR(2),-- Month Number belongs to Quarter
            [Quarter] CHAR(1),
            [QuarterName] VARCHAR(9),--First,Second..
            [Year] CHAR(4),-- Year value of Date stored in Row
            [YearName] CHAR(7), --CY 2012,CY 2013
            [MonthYear] CHAR(10), --Jan-2013,Feb-2013
            [MMYYYY] CHAR(6),
            [FirstDayOfMonth] DATE,
            [LastDayOfMonth] DATE,
            [FirstDayOfQuarter] DATE,
            [LastDayOfQuarter] DATE,
            [FirstDayOfYear] DATE,
            [LastDayOfYear] DATE,
            [IsHolidayIRE] BIT,-- Flag 1=National Holiday, 0-No National Holiday
            [IsWeekday] BIT,-- 0=Week End ,1=Week Day
            [HolidayIRE] VARCHAR(50),--Name of Holiday in US
            [IsHolidayUK] BIT Null,-- Flag 1=National Holiday, 0-No National Holiday
            [HolidayUK] VARCHAR(50) Null, --Name of Holiday in UK
            [PastOrFuture] BIT Null -- Flag  0=Past, 1=Future


        )
    GO

    TRUNCATE Table Dbo.DimensionDate

    /********************************************************************************************/
    --Specify Start Date and End date here
    --Value of Start Date Must be Less than Your End Date 

    DECLARE @StartDate DATETIME = '04/01/2012' --Starting value of Date Range
    DECLARE @EndDate DATETIME = '04/01/2015' --End Value of Date Range

    --Temporary Variables To Hold the Values During Processing of Each Date of Year
    DECLARE
        @DayOfWeekInMonth INT,
        @DayOfWeekInYear INT,
        @DayOfQuarter INT,
        @WeekOfMonth INT,
        @CurrentYear INT,
        @CurrentMonth INT,
        @CurrentQuarter INT

    /*Table Data type to store the day of week count for the month and year*/
    DECLARE @DayOfWeek TABLE (DOW INT, MonthCount INT, QuarterCount INT, YearCount INT)

    INSERT INTO @DayOfWeek VALUES (1, 0, 0, 0)
    INSERT INTO @DayOfWeek VALUES (2, 0, 0, 0)
    INSERT INTO @DayOfWeek VALUES (3, 0, 0, 0)
    INSERT INTO @DayOfWeek VALUES (4, 0, 0, 0)
    INSERT INTO @DayOfWeek VALUES (5, 0, 0, 0)
    INSERT INTO @DayOfWeek VALUES (6, 0, 0, 0)
    INSERT INTO @DayOfWeek VALUES (7, 0, 0, 0)

    --Extract and assign various parts of Values from Current Date to Variable

    DECLARE @CurrentDate AS DATETIME = @StartDate
    SET @CurrentMonth = DATEPART(MM, @CurrentDate)
    SET @CurrentYear = DATEPART(YY, @CurrentDate)
    SET @CurrentQuarter = DATEPART(QQ, @CurrentDate)
    SET @startDate = GETDATE()

    /********************************************************************************************/
    --Proceed only if Start Date(Current date ) is less than End date you specified above

    WHILE @CurrentDate < @EndDate
    BEGIN

    /*Begin day of week logic*/

     /*Check for Change in Month of the Current date if Month changed then 
      Change variable value*/
IF @CurrentMonth != DATEPART(MM, @CurrentDate) 
BEGIN
    UPDATE @DayOfWeek
    SET MonthCount = 0
    SET @CurrentMonth = DATEPART(MM, @CurrentDate)
END

    /* Check for Change in Quarter of the Current date if Quarter changed then change 
     Variable value*/

IF @CurrentQuarter != DATEPART(QQ, @CurrentDate)
BEGIN
    UPDATE @DayOfWeek
    SET QuarterCount = 0
    SET @CurrentQuarter = DATEPART(QQ, @CurrentDate)
END

    /* Check for Change in Year of the Current date if Year changed then change 
     Variable value*/


IF @CurrentYear != DATEPART(YY, @CurrentDate)
BEGIN
    UPDATE @DayOfWeek
    SET YearCount = 0
    SET @CurrentYear = DATEPART(YY, @CurrentDate)
END

    -- Set values in table data type created above from variables 

UPDATE @DayOfWeek
SET 
    MonthCount = MonthCount   1,
    QuarterCount = QuarterCount   1,
    YearCount = YearCount   1
WHERE DOW = DATEPART(DW, @CurrentDate)

SELECT
    @DayOfWeekInMonth = MonthCount,
    @DayOfQuarter = QuarterCount,
    @DayOfWeekInYear = YearCount
FROM @DayOfWeek
WHERE DOW = DATEPART(DW, @CurrentDate)
 

/ Логика конечного дня недели/

/ * Заполните таблицу измерений значениями*/

 INSERT INTO [dbo].[DimensionDate]
SELECT

    CONVERT (char(8),@CurrentDate,112) as DateKey,
    @CurrentDate AS Date,

    CONVERT (char(10),@CurrentDate,103) as FullDate,
    DATEPART(DD, @CurrentDate) AS DayOfMonth,
    --Apply Suffix values like 1st, 2nd 3rd etc..
    CASE 
        WHEN DATEPART(DD,@CurrentDate) IN (11,12,13) 
        THEN CAST(DATEPART(DD,@CurrentDate) AS VARCHAR)   'th'
        WHEN RIGHT(DATEPART(DD,@CurrentDate),1) = 1 
        THEN CAST(DATEPART(DD,@CurrentDate) AS VARCHAR)   'st'
        WHEN RIGHT(DATEPART(DD,@CurrentDate),1) = 2 
        THEN CAST(DATEPART(DD,@CurrentDate) AS VARCHAR)   'nd'
        WHEN RIGHT(DATEPART(DD,@CurrentDate),1) = 3 
        THEN CAST(DATEPART(DD,@CurrentDate) AS VARCHAR)   'rd'
        ELSE CAST(DATEPART(DD,@CurrentDate) AS VARCHAR)   'th' 
        END AS DaySuffix,

    DATENAME(DW, @CurrentDate) AS DayName,


    -- check for day of week as Per US and change it as per UK format 

        CASE DATEPART(DW, @CurrentDate)
        WHEN 1 THEN 7
        WHEN 2 THEN 1
        WHEN 3 THEN 2
        WHEN 4 THEN 3
        WHEN 5 THEN 4
        WHEN 6 THEN 5
        WHEN 7 THEN 6
        END 
        AS DayOfWeekIRE,

    @DayOfWeekInMonth AS DayOfWeekInMonth,
    @DayOfWeekInYear AS DayOfWeekInYear,
    @DayOfQuarter AS DayOfQuarter,
    DATEPART(DY, @CurrentDate) AS DayOfYear,
    DATEPART(WW, @CurrentDate)   1 - DATEPART(WW, CONVERT(VARCHAR, 
    DATEPART(MM, @CurrentDate))   '/1/'   CONVERT(VARCHAR, 
    DATEPART(YY, @CurrentDate))) AS WeekOfMonth,
    (DATEDIFF(DD, DATEADD(QQ, DATEDIFF(QQ, 0, @CurrentDate), 0), 
    @CurrentDate) / 7)   1 AS WeekOfQuarter,
    DATEPART(WW, @CurrentDate) AS WeekOfYear,
    DATEPART(MM, @CurrentDate) AS Month,
    DATENAME(MM, @CurrentDate) AS MonthName,
    CASE
        WHEN DATEPART(MM, @CurrentDate) IN (1, 4, 7, 10) THEN 1
        WHEN DATEPART(MM, @CurrentDate) IN (2, 5, 8, 11) THEN 2
        WHEN DATEPART(MM, @CurrentDate) IN (3, 6, 9, 12) THEN 3
        END AS MonthOfQuarter,
    DATEPART(QQ, @CurrentDate) AS Quarter,
    CASE DATEPART(QQ, @CurrentDate)
        WHEN 1 THEN 'First'
        WHEN 2 THEN 'Second'
        WHEN 3 THEN 'Third'
        WHEN 4 THEN 'Fourth'
        END AS QuarterName,
    DATEPART(YEAR, @CurrentDate) AS Year,
    'CY '   CONVERT(VARCHAR, DATEPART(YEAR, @CurrentDate)) AS YearName,
    LEFT(DATENAME(MM, @CurrentDate), 3)   '-'   CONVERT(VARCHAR, 
    DATEPART(YY, @CurrentDate)) AS MonthYear,
    RIGHT('0'   CONVERT(VARCHAR, DATEPART(MM, @CurrentDate)),2)   
    CONVERT(VARCHAR, DATEPART(YY, @CurrentDate)) AS MMYYYY,
    CONVERT(DATETIME, CONVERT(DATE, DATEADD(DD, - (DATEPART(DD, 
    @CurrentDate) - 1), @CurrentDate))) AS FirstDayOfMonth,
    CONVERT(DATETIME, CONVERT(DATE, DATEADD(DD, - (DATEPART(DD, 
    (DATEADD(MM, 1, @CurrentDate)))), DATEADD(MM, 1, 
    @CurrentDate)))) AS LastDayOfMonth,
    DATEADD(QQ, DATEDIFF(QQ, 0, @CurrentDate), 0) AS FirstDayOfQuarter,
    DATEADD(QQ, DATEDIFF(QQ, -1, @CurrentDate), -1) AS LastDayOfQuarter,
    CONVERT(DATETIME, '01/01/'   CONVERT(VARCHAR, DATEPART(YY, 
    @CurrentDate))) AS FirstDayOfYear,
    CONVERT(DATETIME, '12/31/'   CONVERT(VARCHAR, DATEPART(YY, 
    @CurrentDate))) AS LastDayOfYear,
    NULL AS IsHolidayIRE,
    CASE DATEPART(DW, @CurrentDate)
        WHEN 1 THEN 0
        WHEN 2 THEN 1
        WHEN 3 THEN 1
        WHEN 4 THEN 1
        WHEN 5 THEN 1
        WHEN 6 THEN 1
        WHEN 7 THEN 0
        END AS IsWeekday,
    NULL AS HolidayIRE, Null, Null


    UPDATE 
        DimensionDate
    SET  [PastOrFuture] =
         CASE
            WHEN @StartDate <= [DATE] THEN 0
            ELSE 1
          END
 

УСТАНОВИТЕ @currentDate = DATEADD(DD, 1, @currentDate)

КОНЕЧНЫЙ ВЫБОР * ИЗ DimensionDate

Сообщение 213, уровень 16, состояние 1, строка 99 Имя столбца или количество предоставленных значений не соответствует определению таблицы.

Я просто хочу исправить обновление в нижней части этого кода, не позволяя мне обновлять столбец PastOrFuture до 0 или 1 в зависимости от даты

Он работает идеально, если я удаляю свое обновление и возвращаю значение null.

Комментарии:

1. Как это не работает? Ошибка, неожиданные результаты, что-то еще?

2. Сообщение 213, уровень 16, состояние 1, строка 99 Имя столбца или количество предоставленных значений не соответствует определению таблицы. Он работает идеально, если я удаляю свое обновление и возвращаю значение null.

3. Вам нужно упростить этот код. Можете ли вы опубликовать общее представление о том, с чем вам нужна помощь? Можете ли вы попробовать удалить части кода, которые, как вы знаете, не являются проблемой? Нам нужно больше общего представления о том, что происходит, а что не происходит.

4. У вас insert короткий столбец 1… у вас есть 3 столбца после HolidayIRE , но ваша вставка имеет только 2 нуля после случая для HolidayIRE .

5. Кроме того, попробуйте лучше отформатировать свой кодер. Это поможет вам найти ошибки такого рода.

Ответ №1:

Попробуйте удалить свой оператор update и заменить следующий код на и проверить?

 ....    NULL AS HolidayIRE, Null, Null,
        CASE
                WHEN @StartDate <= [DATE] THEN 0
                ELSE 1
              END
    FROM DimensionDate
 

Я думаю, вы пытаетесь обновить insert. Вы можете вычислить прошлое будущего в самом операторе select

Ответ №2:

Ваш INSERT into DimensionDate короткий столбец.

У вас есть 3 столбца после HolidayIRE , но у insert вас есть только 2 NULLS после случая для HolidayIRE

Либо добавьте список столбцов в insert , либо добавьте еще NULL один в конец insert .

Если на то пошло, не нужно UPDATE просто указывать свой случай в конце INSERT и делать случай последним столбцом и вставлять PastOrFuture на лету…

 CASE
  WHEN @StartDate <= [DATE] THEN 0
  ELSE 1
END
 

Ответ №3:

Вы не указали pastorfuture, посчитайте свои поля по сравнению с таблицей. у вас есть HolidayIRE, null, null, а в таблице указано HolidayIRE, IsHolidayUK, HolidayUK, PastOrFuture