【问题标题】:Why is the addition operator defined for DATETIME values but not for DATE?为什么为 DATETIME 值定义了加法运算符而不为 DATE 定义了加法运算符?
【发布时间】:2015-04-17 09:33:33
【问题描述】:

我知道解决方法是对这两种数据类型都使用DATEADD。我想了解为什么语言设计者选择为一种数据类型而不是另一种数据类型定义此运算符?

当您尝试直接在 DATE 上使用加号运算符时

DECLARE @tomorrow DATE = CONVERT(DATE, GETDATE()) + 1

您收到此错误消息:

消息 206,第 16 级,状态 2,第 1 行
操作数类型冲突:日期与 int 不兼容

但是,您可以将整数添加到 DATETIME,并且可以将 DATETIME 隐式转换为 DATE 而不会出现错误:

DECLARE @thisTimeTomorrow DATETIME = GETDATE() + 1
DECLARE @tomorrow DATE = GETDATE() + 1

【问题讨论】:

  • 不要使用+ 1 - 你真正添加了什么? 1小时? 1天? 1年?使用更合适的 DATEADD() 方法,它可以让您清楚地说明您要添加的内容 - 毫秒到一年.....
  • 出于兼容性原因,语言设计者可能不得不将加法运算符放在那里 - 可能是与 Oracle(或者可能是 Oracle 也决定模仿的东西 - Sybase、DB2,谁知道)。 date 没有理由这样做,因为它是相对较新的;当然,从datetime 中删除它不再是一种选择。
  • @marc_s “不要使用 + 1 - 你真正添加了什么?1 小时?1 天?1 年?”有趣的是,答案是有一天,我猜错了 1 毫秒。
  • 除非 SQL Sever 开发团队就这个问题发表了官方帖子,否则我会说它只能吸引推测性的答案。

标签: sql-server tsql datetime


【解决方案1】:

这是因为出于兼容性目的,SQL Server DATETIME 行为保持不变。由于 2008 年版本 DATETIME2 被引入,禁止整数相加的能力,同时也引入了 DATE,这也禁止了相加。

最简单的解决方案是将加法移动到 CONVERT 中:

DECLARE @tomorrow DATE = CONVERT(DATE, GETDATE()+1)

虽然我建议使用 DATEADD 而不是整数加法:

DECLARE @tomorrow DATE = CONVERT(DATE, DATEADD(DD,+1,GETDATE()))

谢谢。

【讨论】:

  • DATE 存储为 1,3 字节整数而不是 NTEXT。检查here
  • 谢谢 ughai。我们每天都学到新东西。前提还是一样,整数加法一定要移到CONVERT操作里面去。
  • 在对该问题进行一些研究后,我已经编辑了我的答案。似乎 DATETIME 出于所有密集目的“已弃用”,但保留用于遗留代码问题。 DATETIME2 是自 2008 年以来 SQL Server 中的官方日期时间对象,应该使用它,但老实说,我自己从未使用过它。感谢您的意见。
【解决方案2】:

Microsoft SQL Server 源自 Sybase 代码库,其中加法运算符可以将日期时间与数字组合并生成数据时间。根据 ANSI SQL 标准,这种表达式的结果应该产生一个区间类型(在 MSSQL 中不存在)。

Microsoft 开发的较新的 time、date、datetime2、datetimeoffset 数据类型有意不支持这种传统行为以支持 ANSI 标准。必须使用内置的 DATEADD 函数。

【讨论】:

    猜你喜欢
    • 2013-12-04
    • 1970-01-01
    • 1970-01-01
    • 2013-11-24
    • 2021-06-11
    • 1970-01-01
    • 2020-09-30
    • 2020-10-10
    相关资源
    最近更新 更多