Проблема с использованием TOP 1 в запросе - PullRequest
4 голосов
/ 03 сентября 2010

Я написал следующий запрос, чтобы получить дату, удалить часть времени и добавить желаемое время.Если я запускаю этот запрос без предложения TOP, он работает хорошо.Но когда я добавляю его, он возвращает следующее исключение: «Ошибка преобразования при преобразовании даты и / или времени из символьной строки».

Вот запрос:

SELECT TOP 1 
CONVERT(DateTime, (CONVERT(varchar(50),CONVERT(Date, VRSAS.EventOn)) 
+ ' ' + 
CONVERT(varchar(50), CONVERT(Time, '23:30')))) E 
FROM ViewRangeSheetActualStatus VRSAS 
Where VRSAS.EventOn <= '2010-07-31' 
AND VRSAS.[Status] = 1
 order by VRSAS.RangeSheet

Поле EventOnимеет тип DateTime.

Что может происходить?

Ответы [ 3 ]

2 голосов
/ 03 сентября 2010

Я довольно легко воспроизвел этот конец. Я нашел с помощью DATEADD решено

DATEADD(MINUTE, 23*60 + 30, CONVERT(DATETIME,CONVERT(DATE, VRSAS.EventOn)))

Но я на самом деле не уверен почему. Шаги для воспроизведения ниже.

CREATE TABLE ViewRangeSheetActualStatus
(EventOn DATETIME,
[Status] BIT,
RangeSheet INT
)

INSERT INTO [dbo].[ViewRangeSheetActualStatus]([EventOn], [Status], [RangeSheet])
SELECT '20100903 11:02:39.517', 1, 1 UNION ALL
SELECT '20100731 11:03:23.577', 1, 1 UNION ALL
SELECT '20100731 00:00:00.000', 1, 1

/*Selects ALL records - No error*/
SELECT 
CONVERT(DateTime, (CONVERT(varchar(50),CONVERT(Date, VRSAS.EventOn)) 
+ ' ' + 
CONVERT(varchar(50), CONVERT(Time, '23:30')))) E 
FROM ViewRangeSheetActualStatus VRSAS 

/*Selects top (1) record - Error!*/   
SELECT top (1)
CONVERT(DateTime, (CONVERT(varchar(50),CONVERT(Date, VRSAS.EventOn)) 
+ ' ' + 
CONVERT(varchar(50), CONVERT(Time, '23:30')))) E 
FROM ViewRangeSheetActualStatus VRSAS 

Глядя на свойства ComputeScalar в плане выполнения, они различаются.

Все

(CONVERT(datetime,(CONVERT(varchar(50),CONVERT(date,[ViewRangeSheetActualStatus].
 [EventOn] as [VRSAS].[EventOn],0),0)+[@1])+CONVERT(varchar(50),CONVERT(time(7), 
 [@2],0),0),0))

Топ 1

(CONVERT(datetime,(CONVERT(varchar(50),CONVERT(date,[ViewRangeSheetActualStatus].
 [EventOn] as [VRSAS].[EventOn],0),121)+' ')+'23:30:00.0000000',0))

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

------------------------------
Sep  3 2010 11:30PM
Jul 31 2010 11:30PM
Jul 31 2010 11:30PM

Вторая версия производит варчар, содержащий

------------------------------
2010-09-03 23:30:00.0000000

Именно .0000000 вызывает проблему при возвращении к datetime. Я понятия не имею, почему добавление TOP к запросу вызовет это совершенно несвязанное изменение в поведении.

2 голосов
/ 07 сентября 2010

Кажется, что за несогласованность виновата автопараметризация.

Books Online документы , которые DATE, TIME, DATETIME2 и DATETIMEOFFSET используют стиль 121 CONVERT по умолчанию, тогда как стиль 0 используется для DATETIME и SMALLDATETIME. Кто-то забыл обновить правила автопараметризации для новых типов:)

Если запрос может быть автоматически параметризован, стиль 0 ошибочно применяется к новым типам ДАТА / ВРЕМЯ, если имеет место неявное преобразование или явное преобразование с указанным стилем. Запрос без TOP автоматически параметризуется (вместо литерала TIME появляется параметр [@ 1]). TOP - это одна из (многих) функций запросов, которая предотвращает автоматическую параметризацию.

Очевидный обходной путь - всегда указывать нужный стиль при использовании CONVERT.

1 голос
/ 03 сентября 2010

Странно, вы убедились, что он действительно работает без ограничения "top one"? Иногда «верхний» делает ошибку более заметной. Если у вас много, много строк и вы удалили ограничение «top one», запрос может создать впечатление, что он работает, но в фоновом режиме он все еще спулирует результаты и не попадает в строку, вызывающую проблему.

Является ли EventOn ненулевым, это может быть основной причиной. Если это так, сначала поставьте ненулевую проверку.

Кроме того, что такое тип "RangeSheet", какой это тип данных и может ли он содержать нули?

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