好吧,既然您已经看到它可能存在的问题,我希望您已经学会了永远不要将 DateTime 值存储为字符串。
您应该努力始终使用最合适的可用数据类型。
不过不用担心。这是一个常见的错误 Aaron Bertrand 写了一篇关于它的博客文章(嗯,更普遍的问题) - 称为 Bad habits to kick : choosing the wrong data type。
以下是您处理此类事情的方法:
(TL;DR;Rextester 上的现场演示)
首先,创建并填充示例表(请在您以后的问题中保存我们这一步):
CREATE TABLE MyTable (
Id int identity(1,1),
UpdatedDate nvarchar(30)
);
INSERT INTO MyTable(UpdatedDate) VALUES
('01-06-2020 12:00:00 AM'),
('6-17-2020 12:00:00 AM'),
('02-30-2020 12:00:00 AM'), -- Bad data
('1-06-2020 12:00:00 ZM'), -- Bad data
('01-06-2020 13:00:00 PM'),
('13-06-2020 13:00:00 PM'), -- Bad data
('01-06-2020 1:00:00 PM'),
('1-6-2020 1:00:00 AM'),
('Not a date at all...'); -- Bad data
请注意,我添加了一些包含无法转换为 DateTime 值的数据的行。
然后,第一步是获取转换失败的值列表。
SELECT Id, UpdatedDate
FROM dbo.MyTable
WHERE TRY_CONVERT(DateTime2, UpdatedDate, 110) IS NULL;
这将返回以下记录集(对于此示例数据):
Id UpdatedDate
3 02-30-2020 12:00:00 AM
4 1-06-2020 12:00:00 ZM
6 13-06-2020 13:00:00 PM
9 Not a date at all...
现在您有了列表,您可以决定是否要手动修复它们,删除记录,
或者干脆忽略这些值,将新的UpdatedDate 列NULL 留在这些行中。
完成后,向表中添加一个具有临时名称的新列。
我建议使用DateTime2 而不是DateTime - it's just a better data type.
ALTER TABLE dbo.MyTable
ADD UpdatedDate_New DateTime2 NULL;
接下来,您填充此列(我假设您已决定将其保留为 null,因为原始列的数据无法转换为 DateTime2):
UPDATE dbo.MyTable
SET UpdatedDate_New = TRY_CONVERT(DateTime2, UpdatedDate, 110);
现在,从表中删除旧列:
ALTER TABLE dbo.MyTable
DROP COLUMN UpdatedDate;
最后,重命名新列:
EXEC sp_Rename 'dbo.MyTable.UpdatedDate_New', 'UpdatedDate', 'COLUMN';
验证结果:
SELECT *
FROM dbo.MyTable
结果:
Id UpdatedDate
1 06.01.2020 00:00:00
2 17.06.2020 00:00:00
3 NULL
4 NULL
5 06.01.2020 13:00:00
6 NULL
7 06.01.2020 13:00:00
8 06.01.2020 01:00:00
9 NULL
最后一个问题我没有在这个答案中解决,那就是原始列的依赖关系。您应该检查什么取决于原始列,因为有时您必须根据更改的列对代码进行调整。