TSQL默认最小日期时间

TSQL默认最小日期时间,tsql,Tsql,使用Transact-SQL是否有办法在列(在create table语句中)上指定默认日期时间,以便datetime是datetime值的最小可能值 create table atable ( atableID int IDENTITY(1, 1) PRIMARY KEY CLUSTERED, Modified datetime DEFAULT XXXXX?????? ) 创建表atable ( atableID int IDENTITY(1,1)主键群集, 修改日期时间默认值XXXX

使用Transact-SQL是否有办法在列(在create table语句中)上指定默认日期时间,以便datetime是datetime值的最小可能值

create table atable ( atableID int IDENTITY(1, 1) PRIMARY KEY CLUSTERED, Modified datetime DEFAULT XXXXX?????? ) 创建表atable ( atableID int IDENTITY(1,1)主键群集, 修改日期时间默认值XXXXX?????? )
也许我应该让它为空。

“也许我应该让它为空”

不要使用幻数-这是一种糟糕的做法-如果没有值,请将其保留为空


否则,如果你真的想要一个默认日期-使用发布的其他技术之一来设置默认日期

我认为这会起作用

create table atable
(
  atableID int IDENTITY(1, 1) PRIMARY KEY CLUSTERED,
  Modified datetime DEFAULT ((0))
)

编辑:这是错误的…最小SQL日期时间值为1/1/1753。我的解决方案提供了datetime=1/1/1900 00:00:00。其他答案有正确的最短日期…

据我所知,不存在返回此值的函数,您必须硬设置它

尝试从0等值强制转换以获得最小日期将默认为01-01-1900

正如前面建议的,最好将其设置为NULL(如果需要,在读取时使用ISNULL),或者如果您担心设置是否正确,您甚至可以在表上设置触发器来设置编辑时的修改日期

如果你一心想得到尽可能短的日期,那么:

create table atable ( atableID int IDENTITY(1, 1) PRIMARY KEY CLUSTERED, Modified datetime DEFAULT '1753-01-01' ) 创建表atable ( atableID int IDENTITY(1,1)主键群集, 修改日期时间默认值“1753-01-01” )
我认为你唯一的选择是一个常数。有了这句话-不要使用它-坚持使用空值,而不是伪造日期

create table atable
(
  atableID int IDENTITY(1, 1) PRIMARY KEY CLUSTERED,
  Modified datetime DEFAULT '1/1/1753'
)

除非你正在做一个数据库来追踪一个多世纪前的历史时代,使用

Modified datetime DEFAULT ((0)) 
完全安全可靠,允许比“1753-01-01”更优雅的查询,并且比
NULL
更高效的查询

但是,由于第一次修改的日期时间是插入记录的时间,因此可以使用:

Modified datetime NOT NULL DEFAULT (GETUTCDATE())
这就避免了整个问题,并使插入更容易、更安全—就像您根本不插入它,而SQL做家务一样:-)


有了它,您仍然可以通过使用0作为实际最小值来进行优雅而快速的查询,因为它保证始终低于生成的任何插入
GETUTCDATE()

我同意“不要使用魔法值”中的观点。但我想指出的是,有时诉诸此类解决方案是合法的

将列设置为null是有代价的:null是不可索引的。类似于“获取自2010年初以来未修改的所有记录”的查询包括从未修改过的记录。如果我们使用一个可为NULL的列,那么我们就不得不使用[modified]<@cutoffDate或[modified]IS NULL,这反过来又迫使数据库引擎执行表扫描,因为空值没有索引。最后一个可能是个问题

在实践中,如果不引入实际的、真实的性能惩罚,那么应该使用NULL。但这可能很难知道,除非您对当前和所谓可预见的未来的实际数据量有一些了解。您还需要知道是否会有很大比例的记录具有特殊价值-如果是这样,那么无论如何,为其编制索引是没有意义的


简言之,根据deafult/经验法则,应该选择NULL。但是,如果有大量的记录,数据经常被查询,并且只有一小部分记录具有空/特殊值,那么根据这些信息定位记录(当然要创建索引!)可能会有显著的性能提升,而且有时这可以证明使用“魔法”值是合理的

有时,您继承的脆弱代码在很多地方都已经期待着神奇的值。每个人都是正确的,如果可能,您应该使用NULL。但是,作为确保每个对该值的引用都相同的快捷方式,我喜欢将SQL中的“常量”(因为没有更好的名称)放在scaler函数中,然后在需要该值时调用该函数。这样,如果我想将它们全部更新为其他内容,我可以很容易地做到。或者,如果我想继续更改默认值,我只有一个地方可以更新它

下面的代码创建函数和一个表,将其用作默认的DateTime值。然后插入并从表中选择,而不指定“修改”的值。然后自己清理。我希望这有帮助

-- CREATE FUNCTION
CREATE FUNCTION dbo.DateTime_MinValue ( )
RETURNS DATETIME
AS 
    BEGIN
        DECLARE @dateTime_min DATETIME ;
        SET @dateTime_min = '1/1/1753 12:00:00 AM'
        RETURN @dateTime_min ;
    END ;
GO


-- CREATE TABLE USING FUNCTION FOR DEFAULT
CREATE TABLE TestTable
(
  TestTableId INT IDENTITY(1, 1)
                  PRIMARY KEY CLUSTERED ,
  Value VARCHAR(50) ,
  Modified DATETIME DEFAULT dbo.DateTime_MinValue()
) ;


-- INSERT VALUE INTO TABLE
INSERT  INTO TestTable
        ( Value )
VALUES  ( 'Value' ) ;


-- SELECT FROM TABLE
SELECT  TestTableId ,
        VALUE ,
        Modified
FROM    TestTable ;


-- CLEANUP YOUR DB
DROP TABLE TestTable ;
DROP FUNCTION dbo.DateTime_MinValue ;

我倾向于同意。顺便说一句,你有这个问题的答案吗?我讨厌用户尝试重定向用户而不是回答,然后尝试重定向。“也许我应该让它为空。”-我在回答那个部分问:它被修改了吗?答:不,您正在插入值。我在数据上保留CreatedDate和ModifiedDate。插入时ModifiedDate始终为空。它由更新时的触发器设置。+1。在修改为0的位置执行操作是可搜索的,而在修改为NULL的位置执行操作是不可搜索的。这不起作用-0是“1/1/1900”-53690会给你“1/1/1753”的值。也许我不明白,但什么是“1753年1月1日”?为什么“1/1/1900”不起作用呢?1/1/1900会起作用,但它不是OP所追求的最低值。1753年1月1日是日历开始运行之前的最后一天(采用不同的日历)。有存储日期的方法,但不使用DateTime。我认为SQL08引入了一种新类型(DateTime2?)来处理it@Tomalak:1/1/1753是datetime类型的最小值。对于指示上次修改时间的列,NULL是表示“从不”的逻辑选择。但是,如果一个人真的求助于“魔法值”(即使用一些值来表示相同值的正常含义以外的东西,这里说“1/1/1753意味着永远”),最小值在这里是一个合乎逻辑的选择。我知道这是一个古老的问题/答案,但我对此感到非常强烈,我觉得不得不插话。空是一件美妙的事情。然而,正如Dag所指出的,糟糕的表现是明智的