Почему мое сравнение дат sql возвращает 0 результатов - PullRequest
1 голос
/ 05 января 2011

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

В моей базе данных SQL Server 2008 есть следующая таблица:

CREATE TABLE [VSPRRecalc](
    [VSPRDate] [datetimeoffset](7) NOT NULL,
    [CalcType] [int] NOT NULL,
CONSTRAINT [PK_VSPRRecalc] PRIMARY KEY CLUSTERED ([VSPRDate] ASC)

В нем есть несколько строк, которые выглядят так:

INSERT [vsprrecalc](VSPRDate,CalcType) VALUES('2010-12-15 10:17:49.5780000 -05:00','3')
INSERT [vsprrecalc](VSPRDate,CalcType) VALUES('2010-12-16 07:44:03.3750000 -05:00','1')
INSERT [vsprrecalc](VSPRDate,CalcType) VALUES('2010-12-17 07:40:40.1090000 -05:00','1')
INSERT [vsprrecalc](VSPRDate,CalcType) VALUES('2010-12-18 16:29:02.2203744 -05:00','2')
INSERT [vsprrecalc](VSPRDate,CalcType) VALUES('2010-12-20 09:58:50.1250000 -05:00','1')
INSERT [vsprrecalc](VSPRDate,CalcType) VALUES('2010-12-29 19:21:26.8120000 -05:00','1')

Я использую linq, чтобы проверить и посмотреть, существует ли заданная дата в этой таблице:

var recalc = (from re in VSPRRecalcs
              where re.VSPRDate.Date == oDate.Value.Date
              select re).SingleOrDefault();

В настоящее время recalc возвращает ноль, когда дата находится в пределах 5 часов от полуночи (как в случае 12-29 в операторах вставки выше). Я проверил, и следующий sql выполняется:

exec sp_executesql N'SELECT [t0].[VSPRDate], [t0].[CalcType]
                     FROM [dbo].[VSPRRecalc] AS [t0]
                     WHERE 
                     CONVERT(DATE, [t0].[VSPRDate]) = @p0',N'@p0 datetime',@p0='2010-12-29'

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

declare @t as date
set @t =  '2010-12-29'

select *, 
case  when  CONVERT(DATE, [VSPRDate]) = @t then 'true' else 'false' end  
from VSPRRecalc where 
CONVERT(DATE, [VSPRDate]) = @t 

Этот запрос работает для любой другой даты в таблице, но не для любой даты, которая находится в пределах 5 часов после полуночи (снова см. 12-29 выше). Если я выполняю приведенный выше запрос без предложения where, в строке 12-29 действительно отображается «true», поэтому ясно, что логическое значение оценивает то, что я ожидаю в операторе select, но не в предложении where. Почему это происходит?

1 Ответ

1 голос
/ 05 января 2011

Я бы сказал, что это ошибка на SQL Server, связанная с преобразованием времени DATETIMEOFFSET в более «стандартные» типы DATETIME и DATE ...

Вот что я узнал:

Это работает:

EXEC sp_executesql N'SELECT [t0].[VSPRDate], [t0].[CalcType]
                     FROM [dbo].[VSPRRecalc] AS [t0]
                     WHERE [t0].[VSPRDate] = @p0',

                     N'@p0 DATETIMEOFFSET(7)',
                     @p0 = '2010-12-29 19:21:26.8120000 -05:00'

Что означает, что когда мы продолжаем использовать DATETIMEOFFSET, проблем вообще не возникает ... Тем не менее, вам, похоже, нужно найти все записи за определенный день, а не искать точный DATETIMEOFFSET, верно?

Так что, возможно, немного более полезно, это также работает:

EXEC sp_executesql N'SELECT [t0].[VSPRDate], [t0].[CalcType]
                 FROM [dbo].[VSPRRecalc] AS [t0]
                 WHERE [t0].[VSPRDate] BETWEEN @p0 AND @p1',

                 N'@p0 DATETIMEOFFSET, @p1 DATETIMEOFFSET',
                 @p0 = '2010-12-29 00:00:00.0000000 -05:00',
                 @p1 = '2010-12-30 00:00:00.0000000 -05:00'

Полагаю, секрет в том, чтобы продолжать использовать тип данных DATETIMEOFFSET (и это эквивалент CLR, System.DateTimeOffset ). Таким образом, вы не попадете в проблему конверсии ...

(И, кстати, вы все равно должны использовать BETWEEN для поиска записей по дате в любом случае. Это позволяет СУБД использовать индекс по этому столбцу, что невозможно при выполнении предложения WHERE вызов функции или жестко запрограммированное преобразование).

Редактировать Я забыл, что для Linq для SQL нет оператора BETWEEN, но это легко исправить, просто используйте что-то вроде WHERE [t0].[VSPRDate] >= @p0 AND [t0].[VSPRDate] <= @p1' ... Кроме того, this Так что вопрос в том, чтобы объявить метод расширения для его реализации, но я не знаю, работает ли он ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...