String 在SQL Server中将多个日期格式转换为日期时间值
我正在编写一个SQL脚本,用于将数据从旧表迁移到新表,并在此过程中,通过使用适当的数据类型对数据进行严格处理 旧表中有一个varchar字段,它以各种格式保存日期。到目前为止,我在该字段中发现了至少6种日期格式:String 在SQL Server中将多个日期格式转换为日期时间值,string,sql-server-2008,datetime,String,Sql Server 2008,Datetime,我正在编写一个SQL脚本,用于将数据从旧表迁移到新表,并在此过程中,通过使用适当的数据类型对数据进行严格处理 旧表中有一个varchar字段,它以各种格式保存日期。到目前为止,我在该字段中发现了至少6种日期格式: dd/mm/yyyy dd/mm/yy dd.mm.yy dd-mm-yyyy ddxx mmmm yyyy dd.m.yy 我想将所有这些日期转换为正确的日期时间值 关于转换函数的帖子非常有用 但是,我想知道如何检测上面的哪种格式适用于正在处理的每一行 一个选项是对TRY/CATC
dd/mm/yyyy
dd/mm/yy
dd.mm.yy
dd-mm-yyyy
ddxx mmmm yyyy
dd.m.yy
我想将所有这些日期转换为正确的日期时间值
关于转换函数的帖子非常有用
但是,我想知道如何检测上面的哪种格式适用于正在处理的每一行
一个选项是对TRY/CATCH块中的每种可能的格式执行转换,并只使用未失败的格式
唯一的另一种选择可能是通过字符串操作来检测格式,但这对我自己来说可能非常困难。如果这是唯一的选择,我可能会放弃SQL,并将迁移作为C#应用程序编写(只有这样,运行的时间才会比原生SQL脚本长得多)
有人知道在SQL Server中有更简单的方法吗?到目前为止,我解决这个问题的方法是使用嵌套的try/catch块尝试对每个可能的日期格式进行转换 如果做不到这一点,对于“2011年8月12日”等不寻常的日期格式,我求助于手动字符串解析(结果比我预期的要容易) 这是我正在使用的代码,但对于其他人的特殊需要,它必须相应地进行调整。(假设表变量'@datetable'的[DOB]字段已从数据库填充。) 再说一次,如果有人知道更好的解决方案或某种内置SQL Server功能可以更优雅地处理此问题,我洗耳恭听
DECLARE @dateTable TABLE
(
[DOB] varchar(max),
[DOBReal] datetime,
[DOBFilled] bit
)
DECLARE @id INT
WHILE (SELECT COUNT(*) FROM @dateTable Where [DOBFilled] = 0) > 0
BEGIN
SELECT TOP 1 @Id = ID From @dateTable Where [DOBFilled] = 0
DECLARE @sourceString VARCHAR(100) =
(SELECT TOP 1 [DOB]
FROM @dateTable
WHERE ID = @Id)
DECLARE @result DATETIME = NULL
BEGIN TRY
SET @result = CONVERT(DATETIME, @sourceString, 3)
END TRY
BEGIN CATCH
BEGIN TRY
SET @result = CONVERT(DATETIME, @sourceString, 103)
END TRY
BEGIN CATCH
BEGIN TRY
SET @result = CONVERT(DATETIME, @sourceString, 4)
END TRY
BEGIN CATCH
BEGIN TRY
SET @result = CONVERT(DATETIME, @sourceString, 104)
END TRY
BEGIN CATCH
BEGIN TRY
SET @result = CONVERT(DATETIME, @sourceString, 5)
END TRY
BEGIN CATCH
BEGIN TRY
SET @result = CONVERT(DATETIME, @sourceString, 105)
END TRY
BEGIN CATCH
BEGIN TRY
SET @result = CONVERT(DATETIME, @sourceString, 6)
END TRY
BEGIN CATCH
BEGIN TRY
SET @result = CONVERT(DATETIME, @sourceString, 106)
END TRY
BEGIN CATCH
IF (SUBSTRING(@sourceString, 3, 1) = ' '
AND SUBSTRING(@sourceString, 6, 1) = ' ')
BEGIN
IF (LEN(@sourceString) = 8)
BEGIN
SET @result =
CONVERT(
DATETIME,
(SUBSTRING(@sourceString, 1, 2) + '/' +
SUBSTRING(@sourceString, 4, 2) + '/' +
SUBSTRING(@sourceString, 7, 2)),
3)
END
ELSE
IF (LEN(@sourceString) = 10)
BEGIN
SET @result =
CONVERT(
DATETIME,
(SUBSTRING(@sourceString, 1, 2) + '/' +
SUBSTRING(@sourceString, 4, 2) + '/' +
SUBSTRING(@sourceString, 7, 4)),
103)
END
END
ELSE
IF (LEN(@sourceString) >= 11
AND ISNUMERIC(SUBSTRING(@sourceString, 1, 1)) = 1)
BEGIN
DECLARE @date VARCHAR(100) = SUBSTRING(@sourceString, 1, 1)
IF (ISNUMERIC(SUBSTRING(@sourceString, 2, 1)) = 1)
BEGIN
SET @date = SUBSTRING(@sourceString, 1, 2)
END
SET @date =
@date + '/' +
CASE
WHEN CHARINDEX('January', @sourceString) > 0 THEN '01'
WHEN CHARINDEX('February', @sourceString) > 0 THEN '02'
WHEN CHARINDEX('March', @sourceString) > 0 THEN '03'
WHEN CHARINDEX('April', @sourceString) > 0 THEN '04'
WHEN CHARINDEX('May', @sourceString) > 0 THEN '05'
WHEN CHARINDEX('June', @sourceString) > 0 THEN '06'
WHEN CHARINDEX('July', @sourceString) > 0 THEN '07'
WHEN CHARINDEX('August', @sourceString) > 0 THEN '08'
WHEN CHARINDEX('September', @sourceString) > 0 THEN '09'
WHEN CHARINDEX('October', @sourceString) > 0 THEN '10'
WHEN CHARINDEX('November', @sourceString) > 0 THEN '11'
WHEN CHARINDEX('December', @sourceString) > 0 THEN '12'
END
IF (ISNUMERIC(RIGHT(@sourceString, 4)) = 1)
BEGIN
SET @date = @date + '/' + RIGHT(@sourceString, 4)
END
BEGIN TRY
SET @result = CONVERT(DATETIME, @date, 103)
END TRY
BEGIN CATCH
END CATCH
END
END CATCH
END CATCH
END CATCH
END CATCH
END CATCH
END CATCH
END CATCH
END CATCH
UPDATE @dateTable
SET [DOBReal] = @result, [DOBFilled] = 1
WHERE [ID] = @Id
END
SELECT * FROM @dateTable