簡體   English   中英

SQL CLR,用於將字符串拆分為二維數組

[英]SQL CLR for splitting string into two dimensional array

我是為SQL Server TVF編寫SQL CLR的新手,並嘗試創建將字符串(例如“ 1:2; 1:3; 1:4”)拆分為二維數組的程序集:

public partial class UserDefinedFunctions
{
    [Microsoft.SqlServer.Server.SqlFunction(
       FillRowMethodName = "FillRow_Multi",
       TableDefinition = "field nvarchar(4000), item nvarchar(4000)"
       )
    ]
    public static IEnumerable SplitString_Multi(
      [SqlFacet(MaxSize = -1)]
      SqlString Input,
      [SqlFacet(MaxSize = 1)]
      SqlChars Delimiter1,
      [SqlFacet(MaxSize = 1)]
      SqlChars Delimiter2
    )
    {
        return Input.Value.Split(Delimiter1[0]).Select(s => s.Split(Delimiter2[0]));
    }

    public static void FillRow_Multi(object obj, out SqlString field, out SqlString item)
    {
       *dont know*
    }

}

而且不知道如何正確實現FillRow_Multi方法。 在此先感謝您的幫助!

嘗試這個,

    ALTER FUNCTION [dbo].[fnRecursiveSplitString] (
    @input VARCHAR(255)
    ,@Delimeter1 CHAR(1)
    ,@Delimeter2 CHAR(1)
    )
RETURNS TABLE
AS
RETURN (
        WITH CTE1 AS (
                SELECT substring(@input, 0, charindex(@Delimeter1, @input)) field
                    ,substring(@input, charindex(@Delimeter1, @input) + 1, (charindex(@Delimeter2, @input) - charindex(@Delimeter1, @input)) - 1) item
                    ,CAST(STUFF(@input, 1, charindex(@Delimeter2, @input), '') AS VARCHAR(255)) INPUT
                    ,1 RN

                UNION ALL

                SELECT CASE 
                        WHEN LEN(INPUT) > 0
                            THEN CASE 
                                    WHEN charindex(@Delimeter2, INPUT) > 0
                                        THEN substring(substring(INPUT, 0, charindex(@Delimeter1, INPUT)), 0, charindex(@Delimeter2, INPUT))
                                    ELSE substring(INPUT, 0, charindex(@Delimeter1, INPUT))
                                    END
                        END
                    ,CASE 
                        WHEN LEN(INPUT) > 0
                            THEN substring(INPUT, charindex(@Delimeter1, INPUT) + 1, CASE 
                                        WHEN charindex(@Delimeter2, INPUT) > 0
                                            THEN (charindex(@Delimeter2, @input) - charindex(@Delimeter1, @input)) - 1
                                        ELSE LEN(INPUT)
                                        END)
                        END
                    ,CASE 
                        WHEN LEN(INPUT) > 0
                            THEN CAST(STUFF(INPUT, 1, CASE 
                                            WHEN charindex(@Delimeter2, INPUT) > 0
                                                THEN charindex(@Delimeter2, INPUT)
                                            ELSE LEN(INPUT)
                                            END, '') AS VARCHAR(255))
                        END
                    ,RN + 1
                FROM cte1
                WHERE len(INPUT) > 0
                )
        SELECT rn RowNum
            ,field
            ,item
        FROM CTE1
        )

用法,

SELECT * FROM [dbo].[fnRecursiveSplitString]('1:2;1:3;1:4',':',';')
SELECT * FROM [dbo].[fnRecursiveSplitString]('aaa:111' + char(10) + 'bbb:222'+ char(10) + '222:ddd' + char(10) + 'ccc:333' + char(10), ':', char(10)) 

通過使用相同的SQL CLR拆分函數 ,我可以拆分多次,希望在以下情況下滿足您的要求輸入字符串值為2維它使用行分隔符和列分隔符來區分其他行和列

declare @inputstring nvarchar(max) = '1-2;5-6;100-200'
declare @d int = 0
;with cte as (
select 
    rowno = ROW_NUMBER() over (order by @d),
    r.string
from CLRSplitStringFunction(@inputstring,';',0) r
)
select 
    rowno,
    MAX(col1) col1,
    MAX(col2) col2
from (
select 
    rowno,
    case when ROW_NUMBER() over (partition by rowno order by @d) = 1 then c.string end as col1,
    case when ROW_NUMBER() over (partition by rowno order by @d) = 2 then c.string end as col2
from cte
cross apply CLRSplitStringFunction(cte.string,'-',0) c
) t
group by rowno

這是輸出

在此處輸入圖片說明

我不確定使用兩次拆分函數還是使用單個函數以期望的最終表格格式返回所有數據的性能差異

我希望,我已經完成了:)創建您請求的SQL CLR拆分功能

在參考的教程中,我還共享了示例CLR項目源

我使用了這樣的FillRowMethod

公共共享的子FillRowMethod(ByVal行作為對象,ByRef ID作為SqlInt32,ByRef Col1作為字符串,ByRef Col2作為字符串)

並且主要的拆分函數定義如下<SqlFunction(FillRowMethodName:=“ FillRowMethod”,TableDefinition:=“ id int,column1 nvarchar(max),column2 nvarchar(max)”)>

行的第一次拆分在主拆分函數中進行。

FillRowMethod函數用於填充列。 對於上一個主要功能創建的每一行,它僅工作一次。 因此,我在此函數中拆分了輸入行字符串值。

請注意,對於行可以拆分為超出預期的列等情況,應進一步開發該功能。

我從以前的SQL CLR Split函數添加了一個控件,以防止CLR函數返回空值。 在這種情況下,我不確定它是否會按預期工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM