pkE*_*xec 5 sql user-defined-functions sql-server-2008
我有一个分割字符串的功能(为了清晰起见粘贴在最后).单独使用时,此功能可按预期工作.例:
SELECT value
FROM dbo.mg_fn_Split('2#1','#')
Run Code Online (Sandbox Code Playgroud)
返回
-- value --
-- 2 --
-- 1 --
-----------
Run Code Online (Sandbox Code Playgroud)
但是当在"WHERE IN"子句中使用时,就像在这个例子中一样(稍后在tableA上更多):
SELECT * FROM TableA WHERE TableA.id IN
(
SELECT value
FROM dbo.mg_fn_Split('2#1','#')
)
Run Code Online (Sandbox Code Playgroud)
我收到错误:"传递给LEFT或SUBSTRING函数的长度参数无效."
这里使用TableA作为示例.使用不同的表(假设它们具有id列)有时会返回正确的结果,而在其他表上我得到错误.
我假设它与执行顺序有关,但我仍然没有看到什么可能"破坏"该功能.
我正在寻找一个"正在发生什么"的解释,而不是"使用它".我知道我可以使用连接来获得结果.
功能定义:
-- Description: Returns a table containing the results of a string-split operation.
-- Params:
-- DelimitedList: The string to split
-- Delimiter: The delimiter char, defaults to ','
-- Columns:
-- Position - The char index of the item
-- Value - The actual item
-- =============================================
CREATE Function [dbo].[mg_fn_Split]
(
@DelimitedList nvarchar(max)
, @Delimiter nvarchar(2) = ','
)
RETURNS TABLE
AS
RETURN
(
With CorrectedList As
(
Select Case When Left(@DelimitedList, Len(@Delimiter)) <> @Delimiter Then @Delimiter Else '' End
+ @DelimitedList
+ Case When Right(@DelimitedList, Len(@Delimiter)) <> @Delimiter Then @Delimiter Else '' End
As List
, Len(@Delimiter) As DelimiterLen
)
, Numbers As
(
Select TOP( Coalesce(DataLength(@DelimitedList)/2,0) ) Row_Number() Over ( Order By c1.object_id ) As Value
From sys.columns As c1
Cross Join sys.columns As c2
)
Select CharIndex(@Delimiter, CL.list, N.Value) + CL.DelimiterLen As Position
, Substring (
CL.List
, CharIndex(@Delimiter, CL.list, N.Value) + CL.DelimiterLen
, CharIndex(@Delimiter, CL.list, N.Value + 1)
- ( CharIndex(@Delimiter, CL.list, N.Value) + CL.DelimiterLen )
) As Value
From CorrectedList As CL
Cross Join Numbers As N
Where N.Value <= DataLength(CL.List) / 2
And Substring(CL.List, N.Value, CL.DelimiterLen) = @Delimiter
)
Run Code Online (Sandbox Code Playgroud)
编辑:我已经设置了一个小提琴来展示这个:http: //sqlfiddle.com/#!3/9f9ff/3
当内部查询中的数据如下所示时,就会发生这种情况。
SELECT value FROM dbo.mg_fn_Split('#','#') --------------> 这里会出现错误。
SELECT value FROM dbo.mg_fn_Split('2#1','#') -------------> 这里没有错误。
SELECT value FROM dbo.mg_fn_Split('2','#') --------------------> 这里没有错误。
SELECT value FROM dbo.mg_fn_Split('','#') ----------------------> 这里没有错误。
所以基本上当您分割的数据和分隔符相同时,就会发生错误。
问题出在这些陈述上。
" Select Case When Left(@DelimitedList, Len(@Delimiter)) <> @Delimiter Then @Delimiter Else '' End
+ @DelimitedList
+ Case When Right(@DelimitedList, Len(@Delimiter)) <> @Delimiter Then @Delimiter Else '' End"
Run Code Online (Sandbox Code Playgroud)
如果你将其更改为
Select Case When Left(@DelimitedList, Len(@Delimiter)) <> @Delimiter Then @Delimiter Else '1' End
+ @DelimitedList
+ Case When Right(@DelimitedList, Len(@Delimiter)) <> @Delimiter Then @Delimiter Else '1' End
Run Code Online (Sandbox Code Playgroud)
那么它会很好地工作..您所做的就是添加“1”而不是“”...希望这有帮助。
归档时间: |
|
查看次数: |
365 次 |
最近记录: |