拆分多个分隔符

时间:2017-08-23 14:03:05

标签: sql sql-server delimiter

我希望在MS SQL Server中拆分这些类型的字符串值。组中的字符数可以有所不同,但总会有一段时间"。"各组之间:

SELECT 'XXX xxxxxxxxxxxx.xxxx.xxx.xxx.xxxx.xxx-xxx.xxxx.xxxxxxx.xxxx.xxxx.xxxx' AS StringValue
UNION ALL
SELECT 'xxx xxxx.xxxx.xxx.xxxx.xxxx.xxx-xxx_xxxxxxx.xxxx.xxxxxxx.xxxx.xxx.xxxx'
UNION ALL
SELECT '123 INTERSTITIAL.1234.123.ABC.1234.123-ABC.1234.ABCDE01.1234.ABC‌​.1234'

所有角色之间总会有11组。我让前三组爆发,但是对于4-10组有问题。

4 个答案:

答案 0 :(得分:0)

在MS SQL Server中,您可以获得以下内容:

stringNumber stringValue
------------ ----------------
1            XXX xxxxxxxxxxxx
2            xxxx
3            xxx
4            xxx
5            xxxx
6            xxx-xxx
7            xxxx
8            xxxxxxx
9            xxxx
10           xxxx
11           xxxx
1            xxx xxxx
2            xxxx
3            xxx
4            xxxx
5            xxxx
6            xxx-xxx_xxxxxxx
7            xxxx
8            xxxxxxx
9            xxxx
10           xxx
11           xxxx
1            123 INTERSTITIAL
2            1234
3            123
4            ABC
5            1234
6            123-ABC
7            1234
8            ABCDE01
9            1234
10           ABC??
11           1234

运行以下命令:

IF OBJECT_ID(N'dbo.fn_SplitString') IS NOT NULL
    DROP FUNCTION [dbo].[fn_SplitString];
GO

CREATE FUNCTION [dbo].[fn_SplitString] (
    @string AS VARCHAR(8000)
    ,@stringSeperator AS CHAR(1)
    )
RETURNS TABLE
AS
RETURN

SELECT (number - 1) - LEN(REPLACE(LEFT(@string, number - 1), @stringSeperator, '')) + 1 AS stringNumber
    ,LTRIM(RTRIM(SUBSTRING(@string, number, CHARINDEX(@stringSeperator, @string + @stringSeperator, number) - number))) AS stringValue
FROM (
    SELECT number
    --SELECT *
    FROM master..spt_values
    WHERE type = 'p'
    ) AS numbers
WHERE number <= LEN(@string) + 1
    AND SUBSTRING(@stringSeperator + @string, number, 1) = @stringSeperator;
GO

SELECT stringNumber, stringValue
FROM (
    SELECT 'XXX xxxxxxxxxxxx.xxxx.xxx.xxx.xxxx.xxx-xxx.xxxx.xxxxxxx.xxxx.xxxx.xxxx' AS Input
    UNION ALL
    SELECT 'xxx xxxx.xxxx.xxx.xxxx.xxxx.xxx-xxx_xxxxxxx.xxxx.xxxxxxx.xxxx.xxx.xxxx'
    UNION ALL
    SELECT '123 INTERSTITIAL.1234.123.ABC.1234.123-ABC.1234.ABCDE01.1234.ABC‌​.1234'
    )OPdata
CROSS APPLY [dbo].[fn_SplitString](Input,'.');
GO

IF OBJECT_ID(N'dbo.fn_SplitString') IS NOT NULL
    DROP FUNCTION [dbo].[fn_SplitString];

答案 1 :(得分:0)

试试这个

Declare @temp TABLE (id INT IDENTITY,String nvarchar(max))
INSERT INTO @temp
SELECT 'XXX xxxxxxxxxxxx.xxxx.xxx.xxx.xxxx.xxx-xxx.xxxx.xxxxxxx.xxxx.xxxx.xxxx' UNION
SELECT 'xxx xxxx.xxxx.xxx.xxxx.xxxx.xxx-xxx_xxxxxxx.xxxx.xxxxxxx.xxxx.xxx.xxxx'

 SELECT ROW_NUMBER ()OVER(PARTITION BY id Order by id)AS stringNumber    ,
        Split.a.value('.', 'VARCHAR(1000)') AS stringValue
    FROM (
        SELECT id,CAST('<S>' + REPLACE(String, '.', '</S><S>') + '</S>' AS XML) AS String
        FROM @temp
        ) AS A
    CROSS APPLY String.nodes('/S') AS Split(a)

答案 2 :(得分:0)

如果它只是分割变量,那么你可以使用XML技巧。

例:

declare @S nvarchar(max) = N'123 INTERSTITIAL.1234.123.ABC.1234.123-ABC.1234.ABCDE01.1234.ABC‌​.1234';

declare @X XML = cast('<x>'+replace(@S,'.','</x><x>')+'</x>' as XML);

declare @T table (id int identity(1,1), XXX nvarchar(30));

insert into @T (XXX)
select T.x.value('.','nvarchar(30)') as XXX
from @X.nodes('x') as T(x);

select * from @T;

答案 3 :(得分:0)

不使用DECLAREFUNCTION,您可以执行以下操作:

SELECT Input
    ,ItemNumber = ROW_NUMBER() OVER (PARTITION BY Input ORDER BY N)
    ,Item       = SUBSTRING(Input, N, CHARINDEX('.', Input + '.', N) - N)
FROM (
    SELECT 'XXX xxxxxxxxxxxx.xxxx.xxx.xxx.xxxx.xxx-xxx.xxxx.xxxxxxx.xxxx.xxxx.xxxx' AS Input
    UNION ALL
    SELECT 'xxx xxxx.xxxx.xxx.xxxx.xxxx.xxx-xxx_xxxxxxx.xxxx.xxxxxxx.xxxx.xxx.xxxx'
    UNION ALL
    SELECT '123 INTERSTITIAL.1234.123.ABC.1234.123-ABC.1234.ABCDE01.1234.ABC‌​.1234'
    ) OPdata
JOIN (
    SELECT TOP (8000)
        n = ROW_NUMBER()OVER(ORDER BY (SELECT NULL))
    FROM sys.columns a, sys.columns b
    ) n ON SUBSTRING('.' + Input, n, 1) = '.'
ORDER BY 1,2,3