我有一个这样的选项卡:
日期 |
---|
2020年1月 |
2022-01-01 |
一般建议是确保您的架构使用Date-Typed列来存储信息,而不是基于字符的列。这样,您的应用程序将被迫以正确的格式输入数据。
日期和时间数据类型和函数(Transact-SQL(
如果数据以标准格式存储,那么即使数据没有索引,对该数据的查询也会更高效,而不是在每次读取时操纵数据。
- 关于日期和时间值的细节很重要,但不在本文的范围内。不过,在写入操作期间处理和清除数据输入一次(而不是每次读取(是有意义的,使用适当的数据类型是设计高效SQL数据模式的第一步
但如果必须这样做,您可以使用CAST
,过滤掉会导致强制转换引发异常的值可能很重要:
WITH StringDates as (
SELECT '1/1/2020' as [Date]
UNION
SELECT '2022-01-01'
UNION
SELECT 'Not valid'
)
SELECT [Date], ISDATE([Date]) as IsDate, Cast([Date] as Date) as TypedDate
FROM StringDates
WHERE ISDate([Date]) = 1
DateString | IsDate | TypedDate
---|---|
2020年1月1日 | 12020-01-01 |
2022-01-01 | 1 | <2022-01-01>
一种可能的方法是使用具有适当日期和时间样式的TRY_CONVERT
函数。请注意,此转换的结果通常不明确(例如,05/06/2020
的日期(,因此需要定义样式优先级。
样本数据:
SELECT *
INTO Data
FROM (VALUES
('1/1/2020'),
('2022-01-01'),
('13/13/2020'),
('5/6/2020')
) v ([Date])
声明:
SELECT
DateAsText = d.Date,
DateAsDate = (
SELECT TOP 1 TRY_CONVERT(date, d.Date, v.Style)
FROM (VALUES (1, 103), (2, 23)) v (Precedence, Style)
WHERE TRY_CONVERT(date, d.Date, v.Style) IS NOT NULL
ORDER BY v.Precedence
)
FROM Data d
结果:
DateAsText | DateAsDate |
---|---|
2020年1月1日 | 2020-01-01 |
2022-01-01 | 2022-01-01 |
2020年13月13日 | 空 |
2020年5月6日 | 2020-06-05 |