我正在运行此查询
select * from dbo.CHARGES m
LEFT JOIN Docs z ON z.DocId=m.DocId
AND CHARGE_DATE=CAST(z.DocDate + z.DocTime AS DATETIME)
获得Conversion failed when converting date and/or time from character string
,因为DocDate, DocTime
的某些行具有空值
这里DocTime
是Varchar(5)
如何通过忽略NULL或错误的值来运行此查询?
答案 0 :(得分:4)
如果您的字符串格式为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,即使它是在convert中设置的,这是为了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);
<强> Examples on SQL Fiddle 强>
我不宽恕这种方法,并且(正如我在评论中所说)会强烈建议纠正问题(将数据存储为错误的类型),而不是通过箍来解决数据错误。
答案 1 :(得分:1)
尝试此代码,查询取决于您的需要。
使用空值
select * from dbo.CHARGES m
LEFT JOIN Docs z
ON z.DocId=m.DocId
AND (
z.DocDate IS NULL
OR z.DocTime IS NULL
OR CHARGE_DATE=CAST(z.DocDate + z.DocTime AS DATETIME)
)
没有空值
select * from dbo.CHARGES m
LEFT JOIN Docs z
ON z.DocId=m.DocId
AND (
NOT z.DocDate IS NULL
AND NOT z.DocTime IS NULL
AND CHARGE_DATE=CAST(z.DocDate + z.DocTime AS DATETIME)
)