Sqlserver如何递归查询层级数据将父级字段和本级某个字段合并?如何自定义用户函数并调用?

     开门见山,首先说下遇到的问题:前期系统地区字典表中,每个省市县只存了本级名称,没存完整的字段。如:肥西县隶属安徽省合肥市,表中就存了一个肥西县。现有需求需要将完整字段显示,由于系统已在线上运营,无法做过多复杂修改,初步定的方案是在表中新追加一个字段,将字段补齐,一是方便修改,二是为了后期如果别的功能用到可以拿新字段使用,简化工作。

 好了,问题已经明确,接下来就想想怎么解决问题了。也不是什么比较难得问题,刚好闲着无聊,就打开园子写下随笔,或许能帮到有相关问题的人。

 围绕两个问题来说。  

Sqlserver如何递归查询层级数据将父级字段和本级某个字段合并?

       我们都知道oracle中递归是通过connect by prior 来实现的, 那sqlserver中如何实现呢?sqlserver中是没有此关键字辅助的。

       地区表结构如下:

           

    sqlserver递归代码贴上:

     ------查询树结构某节点的上级所有跟节点

with areadata (sID,sSuperID,sName)
as
(

---起始条件
select m.sID,m.sSuperID,m.sName
from [AdoptionRegister_Membership].[dbo].[mdb_Area] m where sID='340824'   --列出子节点查询条件

--递归条件
union all
select a.sID,a.sSuperID,a.sName
from [AdoptionRegister_Membership].[dbo].[mdb_Area] a
inner join
areadata b on a.sID=b.sSuperID  

--根据子节点父级字段查询父级信息
)

select  * from areadata

查询结果如下:

       接下来 我们现在要考虑如何将字段拼接合成,这里我们可以使用stuff来完成,代码如下:

select stuff((
select ''+sName
from areadata where sID!='000000' order by sID asc for xml path('')),1,0,'') as name ;     -----sID!='000000' 这里是过滤全国这行数据

查询效果如下:

      OK,以上已初步解决了如何递归查询层级数据将父级字段和本级某个字段合并问题!现在我们继续看待第二个问题。

       如何自定义用户函数并调用?

       其实就是创建一个自定义标量值自定义函数,将我们刚才写的递归查询封装起来,并返回合并后的值,这个地方就很简单了。代码如下:

USE [AdoptionRegister_Manage]
GO
/****** Object: UserDefinedFunction [dbo].[GET_Area_FullName] Script Date: 01/10/2018 15:50:55 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
Create FUNCTION [dbo].[GET_Area_FullName]
(
@sid nvarchar(40)

)
RETURNS nvarchar(40)

AS

BEGIN


DECLARE @str nvarchar(40)

set @str=N'未查到';

with areadata (sID,sSuperID,sName)
as
(
select m.sID,m.sSuperID,m.sName
from [AdoptionRegister_Membership].[dbo].[mdb_Area] m where sID=@sid
union all
select a.sID,a.sSuperID,a.sName
from [AdoptionRegister_Membership].[dbo].[mdb_Area] a
inner join
areadata b on a.sID=b.sSuperID
)
select @str=stuff((
select ''+sName
from areadata where sID!='000000' order by sID asc for xml path('')),1,0,'')

RETURN @str

END

        ------------------------------

       测试调用

      select  dbo.GET_Area_FullName('340824')

        -----------

        至此我们已经解决了抛出的问题,最后运用函数将表中新加字段全局更新就OK了!

       update [AdoptionRegister_Membership].[dbo].[mdb_Area] set sFullName=dbo.GET_Area_FullName(sID) 

       看下最终结果:

结束,收工!希望对你有帮助!

原文地址:https://www.cnblogs.com/zuozongyao/p/8258737.html