ben*_*ear 2 sql t-sql string null sql-server-2008
问题:
我有一个标量值函数将数据返回为 VARCHAR(MAX) 或 NULL(下面的函数),我使用此函数来分解长文本字符串并获取单个值(多种数据类型)。
我现在尝试将此数据插入到另一个表中,但转换为正确的数据类型,但如果返回值为空,则失败。
我试图填充的字段是DATETIME NULL
这样的,如果函数返回 null 我只想选择 null,否则我想将 转换VARCHAR
为 a DATETIME
,到目前为止我有:
(SELECT CONVERT(DATETIME, dbo.UDEF_GetFromTextString('Date=', ',', RawData))) AS LineDate,
Run Code Online (Sandbox Code Playgroud)
我不能做的是既处理 null 值又转换为 a 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.
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
编辑:
在 AakashM 提供的非常有用的帮助之后,我找到了导致错误的行和值,它试图将 dd-mm-yyyy 作为 mm-dd-yyyy 传递,一直工作到当天的值超过 12。
为了解决这个问题我刚刚改变了:
(SELECT CONVERT(DATETIME, UDEF_GetFromTextString('Date=', ',', RawData))) AS CallDate
Run Code Online (Sandbox Code Playgroud)
到:
(SELECT CONVERT(DATETIME, UDEF_GetFromTextString('Date=', ',', RawData), 105)) AS CallDate
Run Code Online (Sandbox Code Playgroud)
将 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
Run Code Online (Sandbox Code Playgroud)
传递给此函数的一些值:
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
Run Code Online (Sandbox Code Playgroud)
按原样注释行,我们得到
ii s
----------- -----------------------
3 NULL
5 2012-05-16 00:00:00.000
Run Code Online (Sandbox Code Playgroud)
表明它NULL
可以作为函数的返回值。但是,取消注释该2
行,我们得到
将 varchar 数据类型转换为 datetime 数据类型导致值超出范围。
因为 1750 年早于 的可代表范围datetime
(即 1753 到 9999)。