将varchar转换为DateTime不在表上工作,但适用于单个值

时间:2016-02-25 20:58:43

标签: sql-server

我有一个数据类型为ImportDate的列varchar(100)的表。

我想将其值从varchar转换为Datetime,为此我使用了此查询:

select 
    convert(datetime, ImportDate) 
from ImportHistory

但它会抛出一条消息

的异常
  

Msg 241,Level 16,State 1,Line 1
  从字符串转换日期和/或时间时转换失败。

但是,当我单独选择每个值并运行语句时,它可以正常工作。例如,下面的查询工作正常,表中的所有值

也是如此
select convert(Datetime, '1826-07-04 18:20:00')

该表中没有空值,下面是值:

1826-07-04 18:20:00
1826-07-04 18:20:00
1917-11-08 11:11:00
2003-07-16 16:02:00
1984-06-08 00:00:00
2004-06-05 00:00:00
1826-07-04 18:20:00
1826-07-04 18:20:00
1917-11-08 11:11:00
2003-07-16 16:02:00
1984-06-08 00:00:00
2004-06-05 00:00:00

2 个答案:

答案 0 :(得分:2)

如果您使用的是SQL Server 2012+,请在此类情况下使用TRY_PARSETRY_CONVERT

DECLARE @ImportHistory TABLE (ImportDate VARCHAR(100))

INSERT @ImportHistory
VALUES
('1826-07-04 18:20:00'),
('1826-07-04 18:20:00'),
('1917-11-08 11:11:00'),
('2003-07-16 16:02:00'),
('1984-06-08 00:00:00'),
('2004-06-05 00:00:00'),
('1826-07-04 18:20:00'),
('1826-07-04 18:20:00'),
('1917-11-08 11:11:00'),
('Invalid!'),
('2003-07-16 16:02:00'),
('1984-06-08 00:00:00'),
('2004-06-05 00:00:00')

SELECT
    ImportDate, TRY_CONVERT(datetime, ImportDate) as dt
FROM @ImportHistory
WHERE TRY_CONVERT(datetime, ImportDate) IS NULL
-- output: Invalid!, NULL

找到无效值。如果您希望将无效值转换为NULL,则可以删除WHERE子句,并使用TRY_PARSE代替CONVERT

您列出的日期都是有效的,但实际表格中您很可能至少有一个无效日期 - 或者至少没有一个可以按原样分析的日期(额外空间,月/日存储在不同的日期)文化形式等。)。

如果由于某种未知原因必须将列保留为VARCHAR,并且您希望确保应用程序不会在其中插入不可解析的日期,则可以添加约束

ALTER TABLE ImportHistory 
   ADD CONSTRAINT CK_ImportDate 
   CHECK(TRY_CONVERT(datetime, ImportDate) IS NOT NULL)

如果您没有SQL Server 2012+,可以尝试制作游标以查找无效数据:

DECLARE @dt VARCHAR(100); 
DECLARE @dt2 DATETIME;

BEGIN TRY
    DECLARE test_cursor1 CURSOR FOR
    SELECT Importdate FROM @ImportHistory

    OPEN test_cursor1

    WHILE @@FETCH_STATUS = 0
    BEGIN
        FETCH NEXT FROM test_cursor1 INTO @dt
        SET @dt2 = CONVERT(datetime, @dt)
    END
END TRY
BEGIN CATCH
    SELECT @dt
END CATCH
-- output: Invalid!

答案 1 :(得分:1)

这解决了这个问题。

选择转换(日期时间,LTRIM(RTRIM(REPLACE(REPLACE(REPLACE(ImportDate,CHAR(10),''),CHAR(13),''),CHAR(9),'')))) ImportHistory

谢谢大家!!