Скалярная функция SQL Возвращает значение NULL - PullRequest
1 голос
/ 03 апреля 2012

Проблема:

У меня есть функция со скалярным значением, возвращающая данные как VARCHAR (MAX) или 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 FUNCTION

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)+@ADJLEN, CHARINDEX(@commonsuffix,@datastring,PATINDEX('%' + @uniqueprefix + '%',@datastring))- PATINDEX('%' + @uniqueprefix + '%',@datastring)-@ADJLEN) ELSE NULL END
    )
END

Редактировать:

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

Чтобы решить его, я просто изменил:

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

На:

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

1 Ответ

4 голосов
/ 03 апреля 2012

Преобразование типа данных varchar в тип данных datetime привело к значению вне допустимого диапазона.

Это не жалуется на невозможность преобразования 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, и мы получим

Преобразование типа данных varchar в тип данных datetime привело к значению вне допустимого диапазона.

потому что 1750 год предшествует представительному диапазону datetime (то есть 1753–9999).

...