2012-04-03 2 views
1

Проблема:SQL Скалярная функция Вернуться Null

У меня есть скалярные значения Функция возвращает данные как VARCHAR (MAX) или NULL (функция ниже), я использую эту функцию, чтобы взорвать длинную текстовую строку и захватить одиночные значения (из нескольких типов данных).

Теперь я пытаюсь вставить эти данные в другую таблицу, но преобразуется в соответствующие типы данных, но не работает, если возвращаемое значение равно null.

поле я пытаюсь заполнить это DATETIME NULL так, если функция возвращает нулевое значение, я хочу, чтобы просто выбрать нуль, в противном случае я хочу, чтобы преобразовать VARCHAR в DATETIME, до сих пор у меня есть:

(SELECT CONVERT(DATETIME, dbo.UDEF_GetFromTextString('Date=', ',', RawData))) AS LineDate, 

То, что я не могу сделать, - это обработать нулевое значение и преобразовать в DATETIME, может ли кто-нибудь дать мне функцию линии, чтобы сделать это (если возможно, не вызывая функцию дважды)?

Ошибка:

Msg 242, Level 16, State 3, Procedure UDEF_DC_TRANSLATE_CALL_DATA, Line 11 
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value. 
The statement has been terminated. 

UDEF_GetFromTextString ФУНКЦИЯ

CREATE FUNCTION [dbo].[UDEF_GetFromTextString] 
-- Input start and end and return value. 
    (@uniqueprefix VARCHAR(100), 
    @commonsuffix VARCHAR(100), 
    @datastring VARCHAR(MAX)) 
RETURNS VARCHAR(MAX) -- Picked Value. 
AS 
BEGIN 

    DECLARE @ADJLEN INT = LEN(@uniqueprefix) 

    SET @datastring = @datastring + @commonsuffix 


    RETURN ( 
    CASE WHEN (CHARINDEX(@uniqueprefix,@datastring) > 0) 
     AND (CHARINDEX(@uniqueprefix + @commonsuffix,@datastring) = 0) 
    THEN SUBSTRING(@datastring, PATINDEX('%' + @uniqueprefix + '%',@datastring)[email protected], CHARINDEX(@commonsuffix,@datastring,PATINDEX('%' + @uniqueprefix + '%',@datastring))- PATINDEX('%' + @uniqueprefix + '%',@datastring)[email protected]) ELSE NULL END 
    ) 
END 

Edit:

После очень полезной помощь AakashM, я расположена линия и значение вызывает ошибка, это было пытается передать дд-мм-гггг, как дд-мм-гггг, работает до тех пор значение в течение дня было более 12

Чтобы устранить это, я просто изменил:

(SELECT CONVERT(DATETIME, UDEF_GetFromTextString('Date=', ',', RawData))) AS CallDate 

To:

(SELECT CONVERT(DATETIME, UDEF_GetFromTextString('Date=', ',', RawData), 105)) AS CallDate 
+1

«он не работает, если возвращаемое значение равно нулю» - что сообщение об ошибке? – AakashM

+0

Добавлена ​​ошибка. – bendataclear

ответ

4

The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.

Это не жалуется, не будучи в состоянии преобразовать NULL из varchar в datetime. Это жалуется на конвертацию и завершение с датой вне диапазона datetime. Доказательство:

Функция образец, который возвращает либо даты, как строка или NULL:

create function Fexample (@i int) RETURNS varchar(max) 
as 
begin 
return case 
when @i = 5 then '2012-05-16' 
when @i = 2 then '1750-01-01' 
else null end 
end 
go 

Некоторые значения передать в эту функцию:

declare @a table (ii int, s datetime null) 

--insert @a values (2, null) 
insert @a values (3, null) 
insert @a values (5, null) 

update @a 
set s =convert(datetime, dbo.Fexample(ii)) 

select * from @a 

С комментировал линии как есть , мы получаем

ii   s 
----------- ----------------------- 
3   NULL 
5   2012-05-16 00:00:00.000 

NULL показывая, что прекрасно в качестве возвращаемого значения из функция. Тем не менее, раскомментируйте 2 линию, и мы получаем

The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.

потому, что 1750 год до представимого диапазона datetime (который 1753 до 9999).

+0

Это определенно проблема, хорошо заметили! Следующая проблема, которую я имею, - найти оскорбительное значение. Я проверил различные значения для дат и времени, даты все в 2012 году, а время между 00:00:00 и 02:00:00. Есть ли проблема в преобразовании '00:00:00 => DATETIME'? – bendataclear

+0

Если у вас есть доступ к текущим данным, я не знаю лучшего способа, чем писать какой-то диагностический код, который курсор через данные, пытаясь преобразовать в каждую строку по очереди ... – AakashM

+0

У меня есть доступ, поэтому я буду запускать через это сейчас (* googles TSQL CURSOR) :) – bendataclear

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