Почему SQL Server не преобразует DATE в DATETIME автоматически для сравнения?
Мне нравится новый тип данных DATE в SQL Server 2008, но когда я сравниваю поле DATE с полем DATETIME на связанном сервере (в данном случае SQL 2005), например:
DECLARE @MyDate DATE
SET @MyDate = CONVERT(DATE, GETDATE())
SELECT *
FROM MySQL2005LinkedServer.SomeDB.dbo.SomeTable
WHERE SomeDatetimeField < @MyDate
Я получаю эту ошибку:
OLE DB provider "SQLNCLI10" returned message "Unspecified error".
OLE DB provider "SQLNCLI10" returned message "The scale is invalid.".
Очевидно, что "масштаб недействителен", потому что собственный клиент передает тип данных DATE обратно на связанный сервер, и, поскольку это SQL 2005, он не знает, что с ним делать. Выполнение этого же запроса на сервере 2008 прекрасно работает - SQL Server может без проблем сравнивать типы данных DATE и DATETIME.
Вот мой вопрос - есть ли причина, по которой собственный клиент автоматически не конвертирует значение DATE "2009-11-09" в DATETIME "2009-11-09 00:00:00.000", чтобы предыдущая версия SQL Server не захлебнется?
3 ответа
Внутренняя структура для datetime (2005) и date / time / datetime2 datetimeoffset (2008) очень отличается друг от друга, и, как и в случае других сравнений, данные должны быть помещены в один тип при сравнении. Таким образом, нативный клиент будет вынужден сделать такое преобразование.
Собственный клиент может быть щедрым и выполнять неявное преобразование для вас, но в равной степени "элемент наименьшего удивления", над которым склонны работать продукты, должен предполагать, что использование типа в SQL 2005, который он изначально не понимает, должен быть отклонен. Есть ряд тонких ошибок, которые могут просочиться от этой ошибки наверняка.
То же самое должно быть справедливо и для броска datetime2(7) в SQL 2005, ожидаем ли мы, что он округлит точность 100 нс до 3,33 мс или бросок и ошибка - я бы предпочел ошибку и сделать / принять явное приведение.
Я могу только догадываться, что это потому, что 2009-11-09 00:00:00.000
не зависит от часового пояса и может стать причиной более тонких ошибок. Пожалуйста, поправьте меня, если я ошибаюсь.
Вы можете добиться этого с помощью команды ALTER SESSION SET NLS_DATE_FORMAT = 'MM/DD/YYYY HH:MI:SS AM'; Это временное решение. Если вы работаете в UNIX, эти настройки могут быть выполнены в.profile навсегда.