Функция SQL Server для возврата минимальной даты (1 января 1753 г.)

93

Я ищу функцию SQL Server, которая бы возвращала минимальное значение для datetime, а именно 1 января 1753 г. Я бы предпочел не закодировать это значение даты в моем скрипте.

Что-нибудь подобное существует? (Для сравнения, на C # я мог бы просто сделать DateTime.MinValue) Или мне пришлось бы написать это самому?

Я использую Microsoft SQL Server 2008 Express.

Джереми
источник
2
Просто любопытно: почему вы вообще планируете использовать эту дату, а не позволять столбцу иметь значение NULL?
Джо Стефанелли,
1
Вы можете использовать CONVERT(smalldatetime, 0)для smalldatetime.
Гейб
5
CONVERT (smalldatetime, 0) или CONVERT (datetime, 0) или cast (0 as datetime) не является минимальным значением datetime
Геннадий Ванин Геннадий Ванин
2
@Joe: столбец не допускает значений NULL, и я не хочу его изменять, поскольку я не создаю эту таблицу.
Джереми

Ответы:

94

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

select cast(-53690 as datetime)

Затем используйте эту функцию в своих сценариях, и если вам когда-нибудь понадобится ее изменить, есть только одно место для этого.

В качестве альтернативы вы можете использовать этот запрос, если вы предпочитаете его для лучшей читаемости:

select cast('1753-1-1' as datetime)

Пример функции

create function dbo.DateTimeMinValue()
returns datetime as
begin
    return (select cast(-53690 as datetime))
end

Применение

select dbo.DateTimeMinValue() as DateTimeMinValue

DateTimeMinValue
-----------------------
1753-01-01 00:00:00.000
RedFilter
источник
56
Если вы собираетесь иметь произвольную константу, '1753-1-1'это намного лучше, чем-53690
Гейб
6
Имя функции сделало бы очевидным значение значения.
RedFilter
3
Даже в SQL Server 2012 нет функции для получения минимальной даты, аналогичной getdate (), поэтому приведенное выше является единственно возможным решением. Это для всех, кто ищет лучшее решение в решении, связанном с sql server 2012.
Ram
1
Просто используйте DateTime2 (7). Он точно соответствует типу .NET DateTime. Использование sql 'datetime' плохо, как использование 'varchar' вместо 'nvarchar'. nvarchar соответствует типу .NET String. Та же идея. Тогда вы можете просто использовать DateTime.MinValue везде.
Трийнко
2
Как упоминается ниже Фрэнком Гиллихом, cast('17530101' as datetime)он также избегает региональных проблем и немного более читабелен, чем -53690.
Джим
29

Вы видели объект SqlDateTime ? используйте, SqlDateTime.MinValueчтобы получить минимальную дату (1 января 1753 г.).

Наим Сарфраз
источник
33
Это должна быть функция SQL, а не функция .NET.
Джереми
5
Хотя SqlDateTime.MinValue полезен, иметь это в качестве ответа обманчиво. @Jeremy запрашивает встроенную функцию sql, а не что-то из библиотеки классов .NET
Эван
6
плюс один для этого помог с аналогичным вопросом, но в контексте .Net, а не SQL; как и в случае с этим вопросом ..
t_plusplus
Возможно, вы действительно сможете добиться этого с помощью нового U-SQL
Капе
14

Поскольку я не могу прокомментировать принятый ответ из-за недостаточной репутации, мой комментарий является ответом.

использование select cast('1753-1-1' as datetime)означает сбой, если запускается в базе данных с региональными настройками, не принимающими строку даты в формате ГГГГ-ММ-ДД.

Вместо этого используйте select cast(-53690 as datetime)или Convertс указанным форматом даты и времени.

Руна Андерсен
источник
6

Введите дату как собственное значение, 'yyyymmdd'чтобы избежать региональных проблем:

select cast('17530101' as datetime)

Да, было бы здорово, если бы был TSQL MinDate() = '00010101', но не тут-то было .

Фрэнк Гиллих
источник
4

Вот быстрый и легко читаемый способ получить минимальное значение даты

Примечание: это детерминированная функция , поэтому для дальнейшего повышения производительности мы могли бы также применить WITH SCHEMABINDING к возвращаемому значению.

Создать функцию

CREATE FUNCTION MinDate()
RETURNS DATETIME WITH SCHEMABINDING
AS
BEGIN
    RETURN CONVERT(DATETIME, -53690)

END

Вызов функции

dbo.MinDate()

Пример 1

PRINT dbo.MinDate()

Пример 2

PRINT 'The minimimum date allowed in an SQL database is ' + CONVERT(VARCHAR(MAX), dbo.MinDate())

Пример 3

SELECT * FROM Table WHERE DateValue > dbo.MinDate()

Пример 4

SELECT dbo.MinDate() AS MinDate

Пример 5

DECLARE @MinDate AS DATETIME = dbo.MinDate()

SELECT @MinDate AS MinDate
WonderWorker
источник
3

Это не 1 января 1753 года, но выберите cast ('' as datetime), который показывает: 1900-01-01 00: 00: 00.000 дает значение по умолчанию для SQL-сервера. (В любом случае, для меня это выглядит более неинициализированным)

Томаш Гессе
источник
2
Это не так. Базовое datetime - 1 января 1900 00: 00: 00.000 (что вы получаете SELECT CONVERT(DATETIME, 0)), но фактическое минимальное значение, которое datetime может содержать в SQL Server, на самом деле находится в 1753 году, что написал OP. Именно тогда Америка также перешла на григорианский календарь, и SQL Server не должен иметь дело с пропущенными днями и т. Д. SELECT CONVERT(DATETIME, -53690)Выдает 1753-01-01 00:00:00.000и SELECT CONVERT(DATETIME, -53691)выдает ошибку о переполнении.
bugybunny
0

Это то, что я использую для получения минимальной даты в SQL Server. Обратите внимание, что это подходит для глобализации:

CREATE FUNCTION [dbo].[DateTimeMinValue]()
RETURNS datetime
AS
BEGIN
  RETURN (SELECT
    CAST('17530101' AS datetime))
END

Звоните, используя:

SELECT [dbo].[DateTimeMinValue]()
CarneyCode
источник
-1

Диапазон для datetimeне изменится, так как это нарушит обратную совместимость. Так что вы можете жестко это закодировать.

Андомар
источник
2
Это правда, но все равно было бы неплохо вызывать GetMinDate () или что-то в этом роде вместо CONVERT (datetime, '1753-1-1') везде, где мне нужно его использовать.
Джереми
@ Джереми: Я знаю, что convertделает, но GetMinDate()мне пришлось бы углубиться в определение функции. Так что, если бы мне пришлось поддерживать ваш код, я бы предпочел convertвариант.
Andomar
1
Вы можете знать, что convertделает, но не обязательно знать значение 1753-1-1.
jwg