Правильный способ обработки дат в SQL Server, когда доступно только время и дата - PullRequest
0 голосов
/ 09 апреля 2019

Мы используем программное обеспечение PLM под названием «Aras Innovator», и нам нужно сохранить дату как свойство пользовательского элемента. Программное обеспечение использует Microsoft SQL Server для хранения своих данных, а доступ к свойствам на уровне базы данных официально поддерживается.

Однако наша проблема в том, что программное обеспечение поддерживает только дату, а не дату. И даты хранятся в UTC - поэтому, когда мы храним «2020-01-01» от клиента в Центральной Европе, он становится «2019-12-31 23:00» или около того в базе данных (за 1 час до полуночи дня до). И запросы, проверяющие «> = 2020-01-01», не могут найти эти строки.

Производитель программного обеспечения говорит:

Нет стандартной функции для хранения только месяца и дня; быстрый вариант может быть сохранить его в виде строки и сделать программная проверка введенной строки, если требуется.

Что касается прямых запросов SQL, все даты хранятся в UTC для совместимость с несколькими часовыми поясами. Они автоматически конвертируется при доступе через стандартный API. При доступе прямой с SQL вы можете использовать функцию ConvertToLocal, описанную в Aras Innovator 11.0 - Руководство по настройке интернационализации на компакт-диске Изображение, раздел 5.3:

SELECT item_number, innovator.ConvertToLocal (созданный_он, 'восточный Стандартное время ») КАК СОЗДАН НА ИЗДЕЛИИ. Документ

ConvertFromLocal может использоваться для указания дат, которые вы хотите запросить вместо того, чтобы требовать, чтобы эти даты были отправлены в UTC.

Я не уверен, что работа со строкой была бы хорошим решением. Но не уверен, что их функции "ConvertTo / FromLocal" также будут хорошим решением. Наверняка должен быть какой-то другой способ справиться с этим непосредственно в SQL Server?

1 Ответ

0 голосов
/ 10 апреля 2019

SQL Server 2016 представил оператор AT TIME ZONE .

Обратите внимание:

SELECT CONVERT(date, TheDateTime AT TIME ZONE 'UTC'
                                 AT TIME ZONE 'Central Europe Standard Time')

Приведенное выше сначала преобразует поле TheDateTime из datetimeили (datetime2) для типа datetimeoffset со смещением нуля (UTC).Затем он преобразует его в зону Central Europe Standard Time и, наконец, преобразует его в тип date, удаляя любую информацию о времени.

Что касается вашего утверждения:

...> = 2020-01-01 ", следовательно, не удается найти эти строки.

Вместо этого следует рассмотреть возможность преобразования противоположного направления, чтобы выполнить запрос по времени UTC - что будет sargable . Например:

SELECT ...
WHERE TheDateTime >= CONVERT(datetime,
                     '2020-01-01' AT TIME ZONE 'Central Europe Standard Time'
                     AT TIME ZONE 'UTC')

Конечно, вы можете сделать всю правую часть выражения раньше времени и использовать вместо него локальную переменную. Аналогично, если вы вызываете этот запросиз приложения вы можете конвертировать в код приложения UTC в коде приложения и вообще не беспокоиться об этом в SQL Server.

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