如果您的字符串采用格式,yyyy-MM-dd hh:mm
那么您的转换表达式将类似于:
SELECT CONVERT(DATETIME, ISNULL(DocDate, '1900-01-01') + ' ' + ISNULL(DocTime, '00:00'), 121)
但是,在尝试转换它之前检查它是否真的是一个日期可能是明智的:
SET DATEFORMAT YMD;
SELECT DocDate,
DocTime,
Formatted = CASE WHEN ISDATE(ISNULL(DocDate, '1900-01-01')
+ ' ' + ISNULL(DocTime, '00:00')) = 1
THEN CONVERT(DATETIME, ISNULL(DocDate, '1900-01-01')
+ ' ' + ISNULL(DocTime, '00:00'), 121)
ELSE NULL
END
FROM (VALUES
('2013-10-01', '17:30'),-- CORRECT FORMAT
('2013-10-01', NULL), -- NULL TIME
('2013-13-10', '17:30'), -- INVALID DATE
('2013-01-05', 'XX:30'), -- INVALID TIME
(NULL, '17:00') -- NULL DATE
) t (DocDate, DocTime);
注意,我已经设置了 dateformat,即使它是在转换中设置的,这是为了方便ISDATE()
,如果日期格式不是这样设置的,它可能会认为这2013-13-10
是一个有效的日期(2013 年 10 月 13 日),但会通过转换时出现错误。
如果/当您升级到 SQL-Server 2012 时,您可以简单地使用TRY_CONVERT:
SET DATEFORMAT YMD;
SELECT DocDate,
DocTime,
Formatted = TRY_CONVERT(DATETIME, ISNULL(DocDate, '1900-01-01')
+ ' ' + ISNULL(DocTime, '00:00'), 121)
FROM (VALUES
('2013-10-01', '17:30'),-- CORRECT FORMAT
('2013-10-01', NULL), -- NULL TIME
('2013-13-10', '17:30'), -- INVALID DATE
('2013-01-05', 'XX:30'), -- INVALID TIME
(NULL, '17:00') -- NULL DATE
) t (DocDate, DocTime);
SQL Fiddle 上的示例
我不容忍这种方法,并且(正如我在评论中所说)强烈建议纠正问题(将数据存储为错误的类型),而不是跳过箍来解决数据错误。