SQL Server将日期插入为1/1/1900

6

我有一个ASP经典页面,用于向表中插入记录。 我使用表单元素来处理5个字段,即[ABC]([code]、[updatedate]、[flag]、[Mfdate])。当用户没有选择Mdate时,使用日期控件获取用户选择的日期,生成的查询如下所示:

INSERT INTO [ABC] ([code], [updatedate], [flag], [Mfdate]) 
VALUES('203 ', '6/12/2013', 'N/A', '')

当在SQL Server中运行时,它会为Mfdate插入日期1/1/1900,但用户没有选择任何值。
为什么会这样呢? Mfdate的数据类型是datetime

4
Mfdate传入的值是'',这与NULL不同。 - StingyJack
那个表上有触发器吗? - RBarryYoung
2
还有,是“1990”还是“1900”? - StingyJack
4
@StingyJack SELECT CAST('' as datetime) = 1900-01-01 00:00:00.000 - Martin Smith
真的。这肯定是错误的。 - Martin Smith
显示剩余5条评论
2个回答

15

你没有将其设为 null,而是尝试插入一个空字符串('')。你需要:

INSERT INTO [ABC] ([code],[updatedate],[flag],[Mfdate]) 
VALUES ('203', '6/12/2013','N/A', NULL) 

其实,如果您要插入日期,最好以YYYYMMDD格式插入,如下所示:

INSERT INTO [ABC] ([code],[updatedate],[flag],[Mfdate]) 
VALUES ('203', '20130612','N/A', NULL) 

为什么你说“最好”?我认为ISO格式之一会更好,因为它们不会受到文化差异的影响。 - StingyJack
3
是的,Aaron坚持认为应该使用'YYYYMMDD',因为在SQL-Server中甚至连YYYY-MM-DD也会失败的(罕见)设置:改掉的坏习惯:处理日期/范围查询不当 - ypercubeᵀᴹ
1
@Codelearner - 你真的需要编辑你的问题并附上你的代码,因为我不知道你是否在使用C#、VB.NET、Java、PHP、Perl或其他什么语言。这基本上就是检查空字符串,并将相应等效的NULL传递给参数。 - LittleBobbyTables - Au Revoir
1
@Codelearner - 我没有看到任何代码。你是如何构建SQL字符串的? - LittleBobbyTables - Au Revoir
@LittleBobbyTables,我采用了你建议的方法(基本上就是检查空字符串,并将相应的NULL等效参数传递给参数),并使代码正常工作。 - Codelearner
显示剩余4条评论

11

SQL Server日历的纪元或零点是1900年1月1日的开始时间(00:00:00.000)。

datetime的内部表示由2个32位有符号整数组成。高位整数是自纪元以来的天数计数,低位整数是从当天开始计算的毫秒数计数。任何导致datetime值的表示为零的操作都会产生此结果:

select convert(datetime,0)
select convert(datetime,'')
select convert(datetime,0x0000000000000000)

将会产生一个时代性的datetime值,其日期为1900年1月1日 00:00:00.000

然而,null则被转换为…呃…null,因为SQL标准要求涉及到null的任何表达式或测试(除了使用is [not] null进行显式的空值测试)本身必须评估为空值。

另一方面,如果您已经设置了SQL Server的选项来基本上互换处理null和nil字符串,那么您可能会得到时代日期。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接