sql-server - 为什么 ISDATE(YEAR(GETDATE())) 返回 1?
问题描述
为什么ISDATE(YEAR(GETDATE()))
orISDATE(2020)
或ISDATE(<any four digit number>)
or会ISDATE(<any expression that returns a four digit number>)
返回 1?
所有这些都返回 1,我们真的可以依靠 ISDATE()来知道表达式是否是日期表达式吗?
这就是我担心的原因:
SELECT ISDATE(4000-2000)
返回 1 尽管它不是日期表达式。
解决方案
因为ISDATE
(like ISNUEMRIC
) 不是一个很好的功能。ISDATE
设计时考虑了较旧的日期和时间数据类型 ( datetime
and smalldatetime
),这意味着 aint
可以隐式转换为日期和时间。这不适用于新的 Date 和 Time 数据类型(例如datetime2
and date
)。
对于较旧的数据类型,一个int
值表示1900-01-01
. 如此0
,将来也会1900-01-01
如此。因此将是。2
1900-01-03
2020
1905-07-14
如果您确实想查看某个值是否是有效的日期和时间值,对于您使用的数据类型,请使用TRY_CONVERT
. 例如TRY_CONVERT(date,2020)
将返回NULL
,因为2020
无法转换。另一方面TRY_CONVERT(datetime,2020)
将返回1905-07-14
,因为它可以转换;即使该值不是您所期望的。
附加说明:4 位字符串也可以隐式转换。一个 4 位字符串将仅表示日期的年份,因此'2000'
将表示2000-01-01
. 对于较旧的日期和时间数据类型以及新的数据类型都是如此。两者都TRY_CONVERT(date,'2020')
将TRY_CONVERT(datetime,'2020')
返回2020-01-01
。
正如 Martin Smith 所提到的,上面的注释实际上与这里发生的事情更相关。根据ISDATE (Transact-SQL)的参数为ISDATE
:
是可以转换为字符串的字符串或表达式。表达式必须少于 4,000 个字符。日期和时间数据类型,除了 datetime 和 smalldatetime,不允许作为 ISDATE 的参数。
这意味着表达式ISDATE(2020)
和ISDATE('2020')
是同义词。这实际上非常糟糕,因为2020
不能(隐式或显式)转换为 a date
,但可以转换为datetime
. 这进一步(在我看来)巩固了ISDATE
应该避免的情况。考虑到它TRY_CONVERT
在所有受支持的 SQL Server 版本(包括扩展支持的版本)中都可用,这是迄今为止更安全的选择。
推荐阅读
- c# - 如何从循环中保存 datagridview 行中的单元格值并将其传递给每一行的另一个循环?
- python - python字符串替换字母的出现次数
- java - 处理日期选择器中日期格式的解析异常
- machine-learning - 训练空白 spacy 模型后无法获得任何实体
- javascript - 动态添加和删除标记
- javascript - 检测单元格上的有效字段编辑
- ssh - Performance Testing of SFTP server using jMeter
- shell - 没有在 jenkinsfile 中获取变量值
- vue.js - VueJS 渲染函数 - 如何添加对另一个组件的引用?
- react-native - 如何将参数从其他 Stack React Native 传递给 Stack?