2013-10-25 3 views
0

Я бег этого запросаПреобразовать DateTime со значением NULL

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

И вопрос ...? –

+2

", так как некоторые строки DocDate, DocTime имеют нулевое значение" Нет, это не так. Это связано с тем, что данные, которые у вас есть в столбцах, создают строку, которая не преобразуется хорошо в datetime. –

+0

В каком формате находится дата 'DocDate'? Возможно, вам придется использовать SQL-сервер [CONVERT] (http://msdn.microsoft.com/en-us/library/ms187928.aspx), а не 'CAST', чтобы вы могли указать стиль и преобразовать каждую часть по отдельности. например 'CONVERT (DATETIME, z.DocDate, 103) + CONVERT (TIME, z.DocTime)' – GarethD

ответ

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) 
    ) 
+2

Я действительно не понимаю этого ответа. –

+0

В этом решении фильтр даты используется только тогда, когда оба поля не равны нулю. –

4

Если ваши строки в формате yyyy-MM-dd hh:mm тогда ваше выражение новообращенный будет что-то вроде:

SELECT CONVERT(DATETIME, ISNULL(DocDate, '1900-01-01') + ' ' + ISNULL(DocTime, '00:00'), 121) 

Однако, вероятно, можно согласиться проверить, что на самом деле это дата, прежде чем пытаться сотрудничать nvert его:

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 является действительная дата (13 октября 2013 года), но через ошибку, когда дело доходит до конвертации.

Если/При обновлении до 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

Я не одобряю такой подход, и (как я в комментарий) настоятельно рекомендовал бы исправить проблему (которая хранит данные как неправильный тип), а не перепрыгивать через обручи для устранения ошибок данных.

Смежные вопросы