【叶子函数分享九】根据字符分割字符串的三种写法

本文介绍了三种不同的SQL函数实现方式,用于将输入的字符串按指定分隔符进行拆分,并返回拆分后的结果集。这些函数可以有效处理大量数据的字符串拆分任务,提高数据处理效率。

go

--创建函数(第一版)

create function [dbo].[m_split](@c varchar(2000),@split varchar(2))  

    returns @t table(col varchar(200))  

as  

begin  

      while(charindex(@split,@c)<>0)  

        begin  

          insert @t(col) values (substring(@c,1,charindex(@split,@c)-1))  

          set @c = stuff(@c,1,charindex(@split,@c),'')  

        end  

      insert @t(col) values (@c)  

      return  

end

 

--下面两种是在论坛看到高手们发的

go

--创建函数(第二版)(fredrickhu(F))

create function [dbo].[f_split](@s varchar(8000), @split varchar(10) )

returns table

as

 return

 (select substring(@s,number,charindex(@split,@s+@split,number)-number)as col

  from master..spt_values

  where type='p' and number<=len(@s+'a')

  and charindex(@split,@split+@s,number)=number)

 

go

--创建函数(第三版)(dawugui(爱新觉罗.毓华))

create function [dbo].[d_split] (@inputstr varchar(8000),@seprator varchar(10))

returns @temp table (a varchar(200))

as

begin

  declare @i int

  set @inputstr = rtrim(ltrim(@inputstr))

  set @i = charindex(@seprator, @inputstr)

  while @i >= 1

  begin

    insert @temp values(left(@inputstr, @i - 1))

    set @inputstr = substring(@inputstr, @i + 1, len(@inputstr) - @i)

    set @i = charindex(@seprator, @inputstr)

  end

  if @inputstr <> '/'

  insert @temp values(@inputstr)

  return

end

 

--测试示例

declare @sql varchar(20)

set @sql='A,B,C,D,E'

 

select * from dbo.m_split(@sql,',')

select * from dbo.f_split(@sql,',')

select * from dbo.d_split(@sql,',')

 

--运行结果(结果是相同的)

/*

col

---------

A

B

C

D

E

*/

<think>好的,用户的问题是在Oracle中使用WITH RECURSIVE进行递归查询,并将结果用逗号分隔。首先,我需要确认Oracle是否支持WITH RECURSIVE语法。根据之前的知识,Oracle的递归查询通常使用CONNECT BY和START WITH子句,而WITH子句在Oracle中被称为通用表表达式(CTE),但递归CTE的语法可能有所不同。 查阅引用资料,引用[4]提到Oracle使用CONNECT BY进行递归查询,而MySQL 8.0以上使用WITH RECURSIVE。不过引用[3]指出Oracle的WITH子句可以优化性能,但可能不直接支持递归。因此,用户可能混淆了语法,需要明确Oracle的正确递归写法。 接下来,用户希望将结果以逗号分隔。Oracle中可以使用LISTAGG函数来实现这一点。所以,正确的步骤应该是使用CONNECT BY进行递归查询,然后使用LISTAGG聚合结果。 现在需要编写示例SQL。假设有一个表EMPLOYEE,包含ID和MANAGER_ID字段。递归查询所有下属,然后用逗号分隔。首先,使用CONNECT BY获取层级关系,然后使用SYS_CONNECT_BY_PATH生成路径,最后用LISTAGG聚合。 检查语法是否正确,确保CONNECT BY和START WITH的正确使用,以及LISTAGG的参数是否正确。可能需要子查询先获取递归结果,再聚合。同时,注意处理循环和层级限制,比如NOCYCLE和LEVEL <= 10。 最后,验证示例是否符合用户需求,并确保回答结构清晰,分步骤说明,并附上相关问题。</think>在 Oracle 数据库中,递归查询建议使用 `CONNECT BY` 语法而非 `WITH RECURSIVE`。但若需要实现类似功能并格式化结果,可通过以下步骤实现: ### 1. 递归查询实现 使用 `CONNECT BY` 实现层级查询,结合 `SYS_CONNECT_BY_PATH` 函数生成路径: ```sql SELECT ID, SYS_CONNECT_BY_PATH(name, ',') AS path FROM employee WHERE CONNECT_BY_ISLEAF = 1 -- 仅保留叶子节点路径 START WITH manager_id IS NULL CONNECT BY NOCYCLE PRIOR id = manager_id ``` ### 2. 结果合并与分隔 使用 `LISTAGG` 函数将多行结果合并为逗号分隔字符串: ```sql SELECT LISTAGG(name, ',') WITHIN GROUP (ORDER BY id) AS concat_names FROM ( SELECT name, id FROM employee START WITH manager_id IS NULL CONNECT BY PRIOR id = manager_id ) ``` ### 组合示例 若需递归查询某节点的所有子节点并合并: ```sql WITH hierarchy_cte AS ( SELECT name FROM employee START WITH id = 1 -- 指定根节点 CONNECT BY PRIOR id = manager_id ) SELECT LISTAGG(name, ',') AS all_children FROM hierarchy_cte ``` ### 注意事项 1. `NOCYCLE` 参数可防止循环引用报错 2. `LEVEL` 伪列可控制递归深度(如 `WHERE LEVEL <= 5`) 3. 性能优化建议对 `manager_id` 字段建立索引[^3]
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值