将 URL 字符串拆分为列

-2 sql-server sql-server-2008-r2

给定字符串:

URL:'ID=1!&user=xxx&depart=21&companyId=43&workOrder=67'
Run Code Online (Sandbox Code Playgroud)

我需要得到结果:

Sno ID user  depart companyId  workOrder
1   1! XXX   21      43         67 
Run Code Online (Sandbox Code Playgroud)

注意:该列可能会增加。

我正在使用 SQL Server 2008 R2。

Han*_*non 5

Aaron Bertrand在SQLPerformance.com上有一组关于如何拆分字符串的优秀文章,其中包括针对您可以使用的各种机制的一组非常全面的性能测试。

由于您使用的是 SQL Server 2008 R2,因此无法利用STRING_SPLIT()SQL Server 2016 中的功能;然而,你可以使用下面的代码,它可能会表现得非常糟糕,并给很多人,尤其是亚伦,带来噩梦:

CREATE FUNCTION dbo.SplitStrings_XML
(
   @List       varchar(8000),
   @Delimiter  char(1)
)
RETURNS TABLE WITH SCHEMABINDING
AS
   RETURN (SELECT [value] = y.i.value('(./text())[1]', 'varchar(8000)')
      FROM (SELECT x = CONVERT(XML, '<i>' 
          + REPLACE(@List, @Delimiter, '</i><i>') 
          + '</i>').query('.')
      ) AS a CROSS APPLY x.nodes('i') AS y(i));
GO
CREATE PROCEDURE dbo.GetColsFromString
(
    @Input VARCHAR(4000)
    , @Delimiter CHAR(1)
)
AS
BEGIN
    DECLARE @PvtList NVARCHAR(4000);
    DECLARE @cmd NVARCHAR(4000);

    IF OBJECT_ID('tempdb..#SourceRows') IS NOT NULL DROP TABLE #SourceRows;
    SELECT ss.*
    INTO #SourceRows
    FROM dbo.SplitStrings_XML(@Input, @Delimiter) ss

    SET @PvtList = STUFF((
    SELECT ',[' +  SUBSTRING(sr.value, 1, CHARINDEX('=', sr.value) -1) + ']'
    FROM #SourceRows sr
    FOR XML PATH ('')
    ), 1, 1, '');

    SET @cmd = '
    SELECT ' + @PvtList + '
    FROM (
        SELECT ColumnName = SUBSTRING(sr.value, 1, CHARINDEX(''='', sr.value) -1)
            , ColumnValue = SUBSTRING(sr.value, CHARINDEX(''='', sr.value) + 1, LEN(sr.value))
        FROM #SourceRows sr
        ) src
    PIVOT (
        MAX(ColumnValue)
        FOR ColumnName IN (
            ' + @PvtList + '
        )
    ) pvt;';
    PRINT @cmd;
    EXEC sp_executesql @cmd;
END
GO
EXEC dbo.GetColsFromString 'ID=1!&user=xxx&depart=21&companyId=43&workOrder=67','&';
Run Code Online (Sandbox Code Playgroud)

运行上述代码的输出:

在此输入图像描述

上面的代码基于 Aaron 的dbo.SplitStrings_XML函数,使用 PIVOT 语句将单个分隔字符串转换为结果集。此代码应该适用于传入的任何字符串,其格式类似于x=ywherex是所需的列名、y是所需的输出、=是分隔符。

如果您想将该结果集插入到表中,您可以使用该INSERT INTO ... EXEC ...方法,也许像:

INSERT INTO dbo.SomeTable (ID, user, depart, companyId, workOrder)
EXEC dbo.GetColsFromString 'ID=1!&user=xxx&depart=21&companyId=43&workOrder=67','&';
Run Code Online (Sandbox Code Playgroud)