将DateTime转换为NULL值

时间:2013-10-25 12:02:14

标签: sql sql-server sql-server-2008

我正在运行此查询

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

2 个答案:

答案 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)
    )