如何在SQL Server中将split函数转换为内联表值udf?

时间:2015-04-30 07:26:33

标签: sql-server sql-server-2008-r2 inline-table-function

假设我有这个查询(伪):

Select T.a,
       T.b, 
       (select top 1 element from fn_split(c,',') where element=T.element)
From largeTable T

对于每一行运行fn_split,我想使用内联表值udf,这样性能会更好。

注意:fn_split只需通过,

分割即可创建表格

enter image description here

但是看一下内联表值udf structure

create FUNCTION [dbo].[fn_...]
(
    ...
)
RETURNS table
AS
RETURN  SELECT ...(!!!)

它应该立即返回选择作为第一个语句!

但是,如果我的UDF看起来像:

CREATE FUNCTION [dbo].[FN_Split] 
(
    @InDelimitedString varchar(max),
    @InDelimiter       varchar(10) 
)
RETURNS 
    @tblArray TABLE 
    (
        ElementID  smallint IDENTITY(1,1), 
        Element    varchar(1000)
    )

AS
BEGIN

    DECLARE @StrPos smallint,
    @StrStart smallint,
    @DelimiterLength smallint

    SET @DelimiterLength = LEN(@InDelimiter)    

    WHILE LEN(@InDelimitedString) > 0
        BEGIN
         --Removed for clarity . do some CHARINDEX  manipulation ETc.
        END

    RETURN 
END

问题:

我无法立即返回select,但我仍想将fn_split更改为内联表值udf。

我该怎么办?

1 个答案:

答案 0 :(得分:4)

问题在于您的分割功能。它以RBAR方式进行拆分。您应该使用基于集合的拆分器。以下是Jeff Moden的DelimitedSplit8k,它是最快的分割器之一:

Class<? extends XXXX> toolClass = null; // Some class with assignOptions
try {
    toolClass.getMethod("assignOptions", MyOptionModule.class).invoke(null, optionModule);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
    // Exceptions, no options if NoSuchMethodException
}

注意:请务必查看有关更新功能的文章

有关更多分割功能,请阅读Aaron Bertrand爵士的这些文章: