Ошибки SQL-запроса не возвращают значения по пятницам - PullRequest
1 голос
/ 14 июня 2011

У меня есть хранимая процедура sql, которая должна просматривать конкретную таблицу и возвращать номера заданий на основе столбца даты. Это прекрасно работает, за исключением случаев, когда он запускается в субботу утром (и должен возвращать все рабочие номера с датой пятницы, но не возвращает строк). Какие-либо предложения? Есть ли здесь какая-то логическая проблема, которую я не вижу? Как я могу отследить это?

Хранимая процедура

ALTER Procedure [dbo].[JC_GetJobsClosedYesterday]

As

SELECT [JobNumber]
  FROM [NCLGS].[dbo].[JobClosedDate]
  Where LastInvoiceDate between dbo.ufn_StartOfDay (DATEADD(d, -1, GETDATE())) AND dbo.ufn_StartOfDay (GETDATE())
  order by JobNumber desc

И функция начала дня.

ALTER function [dbo].[ufn_StartOfDay] ( @inDate datetime )

RETURNS DateTime AS 
BEGIN   
DECLARE @Now datetime   
set @Now = @inDate
DECLARE @DayStart datetime
set @DayStart = @Now

set @DayStart = DATEADD (ms, -DATEPART(ms,@Now),@DayStart)
set @DayStart = DATEADD (s, -DATEPART(s,@Now),@DayStart)
set @DayStart = DATEADD (mi, -DATEPART(mi,@Now),@DayStart)
set @DayStart = DATEADD (hh, -DATEPART(hh,@Now),@DayStart)

return @DayStart 
END

РЕДАКТИРОВАТЬ: у меня нет проблем с конвертацией даты (если она не знает, как обрабатывать пятницы). Мне нужна помощь с возвратом части без строк.

ОБРАЗЕЦ ДАННЫХ:

JobNumber   LastInvoiceDate             DayOfWeek
112117      2011-06-13 00:00:00.000     Monday
112089      2011-06-10 00:00:00.000     Friday
112090      2011-06-10 00:00:00.000     Friday
112068      2011-06-10 00:00:00.000     Friday
112082      2011-06-10 00:00:00.000     Friday

ОБНОВЛЕНИЕ: Теперь я действительно запутался. Эта вещь «никаких данных по пятницам» происходила (случилась снова в прошлую пятницу), но я все еще не могу понять это. Возможно ли, что GETDATE () не возвращает то, что, я думаю, возвращает? Потому что, когда я пытаюсь выполнить следующие модификации, основанные на предложении @ Thomas, оба метода получают данные, но в отчете, сгенерированном на основе этого последнего кода, нет данных.

DECLARE @date datetime
--SET @date = '2011-06-21 13:42:27.257'
SET @date = '2011-06-11 03:42:27.257'

--Original Code
SELECT [JobNumber]
  FROM [NCLGS].[dbo].[JobClosedDate]
  Where LastInvoiceDate between dbo.ufn_StartOfDay (DATEADD(d, -1, @date)) AND dbo.ufn_StartOfDay (@date)
  order by JobNumber desc

  --Returns 21 records

--Modified based on @Thomas suggestion
Select [JobNumber]
From [NCLGS].[dbo].[JobClosedDate]
Where LastInvoiceDate >= DateAdd( d, DateDiff( d, 0, @date ) - 1, 0 )
    And LastInvoiceDate < DateAdd( d, DateDiff( d, 0, @date ), 0 )
Order By JobNumber Desc

  --Returns 21 records

Ответы [ 3 ]

5 голосов
/ 14 июня 2011

Вместо DATEADD(d, -1, GETDATE()) вы должны использовать выражение, которое возвращает начало предыдущего дня.Для этого вы можете использовать функцию dbo.ufn_StartOfDay(), но есть более простой способ сделать то же самое:

Select @DayStart = DateAdd( d, DateDiff( d, 0, @inDate ), 0 )

, что означает: увеличить нулевую временную метку на общее количество дней между нулевой временной меткой иданный .

Я бы также предложил использовать это выражение вместо уже существующего вызова функции, поэтому ваш запрос будет:

Select [JobNumber]
From [NCLGS].[dbo].[JobClosedDate]
Where LastInvoiceDate Between DateAdd( d, DateDiff( d, 0, GetDate() ) - 1, 0 )
                          And DateAdd( d, DateDiff( d, 0, GetDate() ),     0 )
Order By JobNumber Desc

Дополнение

Вам необходимо уточнить, в чем именно проблема.Вот пример запроса, который я создал и который проверяет каждую дату с четверга, 9 июня по субботу, 18 июня. В какую дату вы ожидали получить значения, но не получили или наоборот:

With SampleData As
    (
    Select 112117 As JobNumber, '2011-06-13 00:00:00.000' As LastInvoiceDate, 'Monday' As DayOfWeek
    Union All Select 112089, '2011-06-10 00:00:00.000', 'Friday'
    Union All Select 112090, '2011-06-10 00:00:00.000', 'Friday'
    Union All Select 112068, '2011-06-10 00:00:00.000', 'Friday'
    Union All Select 112082, '2011-06-10 00:00:00.000', 'Friday'
    )
    , TestDates As
    (
    Select Cast('20110609' As datetime) As Date
    Union All
    Select DateAdd(d,1,Date)
    From TestDates
    Where Date <= '20110617'
    )
Select TD.Date, DateName(dw,TD.Date), Count(SD.JobNumber)
From TestDates As TD
    Left Join SampleData As SD
        On SD.LastInvoiceDate Between DateAdd( d, DateDiff( d, 0, TD.Date ) - 1, 0 )
                          And DateAdd( d, DateDiff( d, 0, TD.Date ),     0 )

Group By TD.Date

Обновление

При просмотре ваших комментариев и кода, я думаю, проблема в том, что вы используете Between.Col Between DateA And DateB переводится как Col >= DateA And Col <= DateB.То есть он включает обе конечные точки.Вместо этого вам нужно исключить конечную конечную точку:

Select [JobNumber]
From [NCLGS].[dbo].[JobClosedDate]
Where LastInvoiceDate >= DateAdd( d, DateDiff( d, 0, GetDate() ) - 1, 0 )
    And LastInvoiceDate < DateAdd( d, DateDiff( d, 0, GetDate() ), 0 )
Order By JobNumber Desc

Это даст вам все номера работ, которые были на предыдущую дату.То есть, если сегодня пятница, 10 июня 2011 года, он выдаст вам все значения LastInvoiceDate от 2011-06-09 midnight до 2011-06-09 23:59:59.

0 голосов
/ 22 июня 2011

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

Я добавил следующее перед оператором выбора:

if datepart(dw, GETDATE()) = 7 OR datepart(dw, GETDATE()) = 1
    BEGIN
        Exec dbo.NCL_MaintainJobClosedDateTable
        --Select 'True'
    END

, что приведет к обновлению в субботу и воскресенье утром.

0 голосов
/ 14 июня 2011

См. Пол даты в SQL-сервере

Чтобы удалить часть времени, используйте:

 SELECT CAST(FLOOR(CAST(CURRENT_TIMESTAMP AS float)) AS DATETIME)

Это должен быть самый быстрый способ.Таким образом

SELECT [JobNumber]
  FROM [NCLGS].[dbo].[JobClosedDate]
  WHERE LastInvoiceDate between 
       CAST((FLOOR(CAST(GETDATE() float))-1.0) AS DATETIME) AND
        CAST(FLOOR(CAST(GETDATE() AS float)) AS DATETIME)
  ORDER BY JobNumber DESC
...