Как проверить название дня по дате. но из процедуры я получаю неправильный день в соответствии с датой, поэтому, пожалуйста, помогите мне

#sql #sql-server

#sql #sql-сервер

Вопрос:

Вот мой код SQL Server:

 CREATE PROCEDURE [dbo].[usp_GetLeaveDateBewteenStartAndEndDate]      
    (@UserEmail VARCHAR(100) = NULL,      
     @FromDate VARCHAR(10) = NULL,      
     @ToDate VARCHAR(10) = NULL)      
AS      
BEGIN      
    --SELECT       
    --GETDATE() AS [Date]      
    --,CONVERT(VARCHAR(10),GETDATE(),103) AS ShortDate      
    --,'Monday' as [DayName]      
    --,'Full Day' as [Session]      
    --, 1 as NoOfDays      
    --,'Work Day' as [Status]      
    --,'W' as StatusCode      
    
     DECLARE @Result AS TABLE    
                        (    
                            Date       DATETIME,
                            ShortDate  VARCHAR(50),
                            DayNames   VARCHAR(50),    
                            Session    VARCHAR(20),    
                            NoOfDays   INT,
                            Status     VARCHAR(50),    
                            StatusCode VARCHAR(2)    
                        )        
       
    DECLARE @dayscount INT 

    SET @dayscount =  CAST(DATEDIFF(DAY, CONVERT(DATE, @FromDate, 103), CONVERT(DATE, @ToDate, 103)) AS INT)   1

    DECLARE @daysval INT
    SET @daysval = 0

    WHILE (@daysval < @dayscount)
    BEGIN
        INSERT INTO @Result (Date, ShortDate, DayNames, Session, NoOfDays, Status, StatusCode)    
        VALUES (CONVERT(DATETIME, DATEADD(DAY, @daysval, CONVERT(DATE, @FromDate, 103)), 103), CONVERT(VARCHAR(50), DATEADD(DAY, @daysval, CONVERT(DATE, @FromDate, 103)), 103),     
                DATENAME(dw, CONVERT(VARCHAR(50), DATEADD(DAY, @daysval, '07/02/2021'), 103)), 
                'Full Session', 1, 'Work Day', 'W')    
    
        SET @daysval = @daysval   1

        DECLARE @daycheck NVARCHAR(100)

        SELECT @daycheck = DayNames 
        FROM @Result
   
        IF (@daycheck = 'sunday')
        BEGIN
            UPDATE @Result
            SET Status = '', StatusCode = ''
        END
    END
      
    SELECT * FROM @Result   
END
 

И после выполнения моего запроса я получаю этот результат:

 EXEC [dbo].[usp_GetLeaveDateBewteenStartAndEndDate] NULL, '03/02/2021', '05/02/2021'

Date    ShortDate   DayNames    Session NoOfDays    Status  StatusCode  
-----------------------------------------------------------------------
2021-02-03 00:00:00.000 03/02/2021  Sunday  Full Session    1       
2021-02-04 00:00:00.000 04/02/2021  Sunday  Full Session    1       
2021-02-05 00:00:00.000 05/02/2021  Wednesday   Full Session    1   Work Day    W
 

Для 01/02/2021 daynames должен быть понедельник, а 05/02/2021 должен быть вторник.

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

1. С какой стати вы преобразуете даты varchar только для того, чтобы передать их обратно в функции даты, сохраняя даты как даты. И вам нужно научиться использовать таблицу / функцию подсчета.

Ответ №1:

Я не могу точно сказать, почему вы видите эти результаты, поскольку у меня нет ваших входных параметров. Но в вашем коде есть ряд фундаментальных ошибок.

  1. select @daycheck = DayNames from @Result не проверяет, какую строку он запрашивает.
  2. update @Result set Status = '' , StatusCode = '' имеет ту же проблему.
  3. Вы конвертируете даты varchar влево и вправо. Сохраняйте значения в том формате, в котором они должны быть, и просто конвертируйте там, где это необходимо для отображения.
  4. Кроме того, вы должны проходить через даты от и до как date нет varchar .
  5. Для всего этого нет необходимости в while цикле или табличной переменной. Это можно сделать с помощью таблицы подсчета. Я использовал хорошо известную таблицу Ицика Бен-Гана ниже.
 WITH
    L0 AS ( SELECT 1 AS c 
            FROM (VALUES(1),(1),(1),(1),(1),(1),(1),(1),
                        (1),(1),(1),(1),(1),(1),(1),(1)) AS D(c) ),
    L1 AS ( SELECT 1 AS c FROM L0 AS A CROSS JOIN L0 AS B ),
    L2 AS ( SELECT 1 AS c FROM L1 AS A CROSS JOIN L1 AS B ),
    L3 AS ( SELECT 1 AS c FROM L2 AS A CROSS JOIN L2 AS B ),
    Nums AS ( SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS rownum
              FROM L3 ),
    Dates AS (
        SELECT TOP( DATEDIFF(day, @FromDate, @ToDate)   1 )
            DATEADD(day, rownum - 1, @FromDate) AS dateVal
        FROM Nums
    )

SELECT
    dateVal AS Date,
    CONVERT(Varchar(50), dateVal, 103) AS ShortDate,
    v.DayNames,
    'Full Session' AS Session,
    1 AS NoOfDays,
    CASE WHEN v.DayNames = 'Sunday' THEN '' ELSE 'Work Day' END AS Status,
    CASE WHEN v.DayNames = 'Sunday' THEN '' ELSE 'W' END AS StatusCode
FROM Dates
CROSS APPLY (VALUES (DATENAME(dw, dateVal) ) ) AS v(DayNames)
 

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

1. вывод в порядке, но проблема в том, что даты 03/02/2021 и 04/02/2021 оба являются dayname показывает среду, но 04.02.2021 будет четверг. названия дней не могут быть изменены, это моя проблема, обновление работает. пожалуйста, помогите мне для dayname, которые не заполнены правильными данными

2. Извините, я понимаю 04/02/2021 | Thursday , вы меняете мой код в любом случае, кроме параметров?

3. ваш вывод кода в порядке, но когда я передаю параметр ’10/02/2021′ ДД / ММ / ГГГГ с даты в вашем коде, который принимается как ’02/10/2021′, мне нужен тот же формат

4. Это связано с настройками вашего сервера, которые, вероятно, указаны в настройках США. Всегда записывайте литералы даты в однозначном формате 'YYYY-MM-DD HH:MM:SS , чтобы избежать путаницы. Объявите ваши параметры как @FromDate date нет varchar