列入“WHERE ... IN”的条款时UDF奇怪的错误(Weird error in udf wh

2019-09-22 13:58发布

我有分裂了一个字符串(末尾为清楚起见粘贴)功能。 此功能单独使用时预期。 例:

SELECT value
FROM dbo.mg_fn_Split('2#1','#')

返回

-- value --
--   2   --
--   1   --
-----------

但是,在一个“WHERE IN”子句本例中使用时,作为(更TableA上以后):

SELECT * FROM TableA WHERE TableA.id IN
(
  SELECT value
  FROM dbo.mg_fn_Split('2#1','#')
)

我得到的错误:“传递给左或子字符串函数无效长度参数”

表A在此用作一个例子。 使用不同的表(假设他们有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
    )

编辑:我已经成立了一个小提琴表现出这一点: http://sqlfiddle.com/#!3/9f9ff/3

Answer 1:

这种情况发生时,你在内部查询数据变为如下。

SELECT值FROM dbo.mg_fn_Split( '#', '#')-------------->在这里你会得到错误。

SELECT值FROM dbo.mg_fn_Split( '2#1', '#')------------->这里没有错误。

SELECT值FROM dbo.mg_fn_Split( '2', '#')-------------------->这里没有错误。

SELECT值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"

如果你改变这

    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

那么它就会迎刃而解。所有你正在做的是增加“1”,而不是'......希望这有助于。



文章来源: Weird error in udf when included in “WHERE…IN” clause