0

我正在运行此查询

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 或错误值来运行此查询?

4

2 回答 2

6

如果您的字符串采用格式,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 上的示例

我不容忍这种方法,并且(正如我在评论中所说)强烈建议纠正问题(将数据存储为错误的类型),而不是跳过箍来解决数据错误。

于 2013-10-25T13:39:12.697 回答
2

试试这个代码,查询取决于你的需要。

使用空值

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)
    )
于 2013-10-25T12:08:28.837 回答