从分裂函数返回的子字符串中拆分字符串

8

我有一个类似下面的字符串

a_b|c_d

我需要根据|进行拆分。

所以,结果将会是:

a_b
c_d

然后,我想再次使用_进行拆分,结果如下:
a
b

c
d

是否可以一次性完成此操作?就是输入相应的字符串,它会返回以下数值:

a
b
c
d

我已经创建了一个用于分割的函数:

select items from dbo.splitdetails('a_b|c_d','|')

它将产生如下结果:
a_b
c_d

但我不知道如何使用这些结果进行下一次拆分?
使用临时表,我希望可以做到这一点,但我需要在函数内部使用它。因此,我认为临时表不是一个好的选择。游标也是一种选择,但当我使用游标时,它会降低性能,因为我有成千上万条记录。
我的输入是:
a_b|c_d

所需的输出结果是:

a
b
c
d

2
你是否考虑过使用专门用于保存多个值的数据类型,例如XML或表格,而不是在一开始就为自己创造这个问题? - Damien_The_Unbeliever
6个回答

7
您可以先使用 Sql Replace 函数,然后按照以下方式使用拆分函数。
select REPLACE('a_b|c_d','|','_')

results: a_b_c_d

现在像下面这样使用您的Split函数。
select items from dbo.splitdetails('a_b_c_d','_')

编辑:

一次性全部

select items from dbo.splitdetails(REPLACE('a_b|c_d','|','_'),'_')

编辑1:

在这种情况下,使用“反向替换”选项。

select items from dbo.splitdetails(REPLACE('a_b|c_d','_','|'),'|')

好的,我会尝试一下。谢谢你的有价值的建议。 - Arunprasanth K V
谢谢你的解决方案,它有效,但不幸的是我不能使用这个解决方案,因为在我的逻辑中“_”和“|”可能有不同的含义。所以当我用“_”替换“|”时,整个逻辑将会失败。 - Arunprasanth K V
无论如何,您的答案回答了我的问题,因此需要被接受。 - Arunprasanth K V
请再次参考答案。 - Sai Kalyan Kumar Akshinthala

5
您可以像这样使用 CROSS APPLY
SELECT d.item,e.item from dbo.splitdetails('a_b|c_d','|') d
CROSS APPLY dbo.splitdetails(d.item,'_') e

抱歉,它显示一个错误消息102,级别15,状态1,第2行附近有语法错误。 - Arunprasanth K V
啊,原来是因为我从你的原问题中查看了模式名称。 - ughai

2

在SQL中有一个 CURSOR

然后使用fetch从第一个查询结果中获取每个SubString

DECLARE db_cursor CURSOR FOR  
select items 
from bdo.splitdetails('a_b|c_d','|')

OPEN db_cursor   
FETCH NEXT FROM db_cursor INTO @items

WHILE @@FETCH_STATUS = 0   
BEGIN   
   select SubString
   from bdo.splitdetails(@items,'_')

   --do something on SubString--

   FETCH NEXT FROM db_cursor INTO @items
END   

CLOSE db_cursor   
DEALLOCATE db_cursor

当我使用游标时,性能会下降。我必须根据许多条件拆分一个长字符串,并且需要使用联接查询来完成,因此可能有数千条记录。因此,当我使用游标时,对于每个记录,我都需要循环,这将降低性能。 - Arunprasanth K V

1
这有帮助吗?
With value(Item) as 
(
select items from bdo.splitdetails('a_b|c_d','|')
)
Select x.Items from value a
cross apply ( 
select items from bdo.splitdetails(a.Item,'_')
) x ;

1
你可以使用PATINDEX函数通过多个分隔符来拆分字符串。以下是完整的函数和示例输出。
CREATE FUNCTION [dbo].[splitdetails]
(
    @input VARCHAR(100),
    @delim VARCHAR(100)
)
RETURNS @table TABLE
(
    items VARCHAR(100)
)
AS
BEGIN
    DECLARE @index INT;
    SET @index = PATINDEX(@delim, @input)
    WHILE @index > 0
    BEGIN
        INSERT INTO @table SELECT LEFT(@input, @index - 1)
        SET @input = RIGHT(@input, LEN(@input) - @index)
        SET @index = PATINDEX(@delim, @input)
    END
    INSERT INTO @table SELECT @input
    RETURN
END
GO

SELECT items FROM dbo.splitdetails('a_b|c_d', '%[_|]%')
-- a
-- b
-- c
-- d

SELECT items FROM dbo.splitdetails('xxx|yyy', '%[_|]%')
-- xxx
-- yyy

SELECT items FROM dbo.splitdetails('xxxxxxx', '%[_|]%')
-- xxxxxxx

谢谢,好的解决方案。 - Arunprasanth K V

0

使用这个可能会有帮助

select items from bdo.splitdetails(REPLACE('a_b|c_d','|','_'),'_')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接