SQL标量值函数返回空值

时间:2012-04-03 09:37:32

标签: sql string sql-server-2008 tsql null

问题:

我有一个标量值函数返回数据为VARCHAR(MAX)或NULL(下面的函数),我使用此函数来分解长文本字符串并获取单个值(多种数据类型)。

我现在正在尝试将此数据插入到另一个表中但转换为正确的数据类型但如果返回的值为null则失败。

我正在尝试填充的字段是DATETIME NULL所以如果函数返回null我想只选择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)+@ADJLEN, CHARINDEX(@commonsuffix,@datastring,PATINDEX('%' + @uniqueprefix + '%',@datastring))- PATINDEX('%' + @uniqueprefix + '%',@datastring)-@ADJLEN) ELSE NULL END
    )
END

修改

在AakashM非常有用的帮助之后,我找到导致错误的线和值,它试图将dd-mm-yyyy传递为mm-dd-yyyy,直到当天的值超过12。

为了解决这个问题,我刚刚改变了:

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

要:

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

1 个答案:

答案 0 :(得分:4)

  

将varchar数据类型转换为日期时间数据类型会导致超出范围的值。

这并不是抱怨无法将NULLvarchar转换为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数据类型转换为日期时间数据类型   在超出范围的价值。

因为1750年在datetime(1753至9999)的可表示范围之前。