zoukankan      html  css  js  c++  java
  • SQL-学习使用FOR XML PATH

    前言:本人SQL技术很烂,然后工作时间也不久,许多东西都还在学习中,说的不好的地方尽请谅解.

    首先跟大家说一下我今天遇到的问题吧.

    查出的数据有三列,第一列存放的是32位的GUID,Res_Name存放的是一个物资类型.Res_Data存放的是部门的GUID.我现在需要得到的数据是这样的.

    首先大家可以看到.第一张图的Res_Data中有多个部门的GUID,中间用逗号隔开的.

    我当时想到的愚蠢的办法就是

     1 @MaterialTypeName nvarchar(200),
     2 @CentralizedName nvarchar(200),
     3 @start int,
     4 @limit int,
     5 @totalCount int output 
     6 AS
     7 BEGIN
     8     SET NOCOUNT ON;
     9     select 
    10         ROW_NUMBER() over (order by res_id asc) as RowNumber,
    11         * 
    12     into #List 
    13     from 
    14         UBIPlatform..T_RESOURCE 
    15     WHERE Res_Parent_Code='741cdd2bef2e479f8c5dd35cf6e8bf2a'
    16      
    17         
    18     declare @i int,@count int;
    19     declare @Centralized nvarchar(200);
    20     declare @List1 table(id int, ResId nvarchar(50),ResName nvarchar(50),ResData nvarchar(50));
    21     select @count=COUNT(*) from UBIPlatform..T_RESOURCE WHERE Res_Parent_Code='741cdd2bef2e479f8c5dd35cf6e8bf2a' 
    22     set @i=1
    23     while @i<=@count
    24     begin
    25         if @i in (select RowNumber from #List)
    26         begin
    27             set @Centralized='';
    28             select 
    29                 @Centralized=@Centralized+','+LTRIM(Res_Name) 
    30             from UBIPlatform.dbo.FN_GETMultiValTable(
    31                 (select 
    32                     Res_Data 
    33                 from 
    34                     UBIPlatform..T_RESOURCE 
    35                 where 
    36                     Res_Id=(select Res_Id from #List where RowNumber=@i))) ge
    37             inner join UBIPlatform..T_RESOURCE r on r.Res_Id=ge.nvalue
    38             
    39             if @Centralized!=''
    40             begin
    41                 insert into 
    42                     @List1 
    43                 select 
    44                     @i,
    45                     Res_Id,
    46                     Res_Name,
    47                     (RIGHT(@Centralized,LEN(@Centralized)-1)) 
    48                 from 
    49                     UBIPlatform..T_RESOURCE 
    50                 where Res_Id=(select Res_Id from #List where RowNumber=@i)
    51             end
    52             else
    53             begin
    54                 insert into 
    55                     @List1 
    56                 select 
    57                     @i,
    58                     Res_Id,
    59                     Res_Name,
    60                     @Centralized
    61                 from 
    62                     UBIPlatform..T_RESOURCE 
    63                 where Res_Id=(select Res_Id from #List where RowNumber=@i)
    64             end    
    65         end
    66         set @i=@i+1
    67     end
    68     
    69     select ROW_NUMBER() over (order by id asc) as RowNumber,* into #List2 from @List1 where 
    70     (@MaterialTypeName is null or @MaterialTypeName = '' or ResName  like '%'+@MaterialTypeName+'%')
    71     and (@CentralizedName is null or @CentralizedName = '' or ResData  like '%'+@CentralizedName+'%')
    72     
    73     select top(@limit) * from #List2 where RowNumber > @start order by RowNumber asc
    74     select @totalCount =COUNT(1) from @List1
    75 END
    View Code

    这个是我开始写出来的一个.烂到不行.虽然是解决了我的需求.但是显而易见这种办法是不可取的.后来请教同事,跟我介绍了FOR XML PATH,我查阅了一下就是将查询结果集以XML形式展现.

    select Res_Id,Res_Name,Res_Data from UBIPlatform..T_RESOURCE where Res_Parent_Code='741cdd2bef2e479f8c5dd35cf6e8bf2a' FOR XML PATH

    结果:

     1 <row>
     2   <Res_Id>239dbe35bd8446afb262f62712d8eb1b</Res_Id>
     3   <Res_Name>修理费-设备备件</Res_Name>
     4   <Res_Data>4BD2D7C9D91546B09BA4438EE583F682</Res_Data>
     5 </row>
     6 <row>
     7   <Res_Id>4d35c89868854d649963410a126b4c30</Res_Id>
     8   <Res_Name>低值易耗-计量器具</Res_Name>
     9   <Res_Data>4ADEEC453DE04910B0136593CBB4187C</Res_Data>
    10 </row>
    11 <row>
    12   <Res_Id>4e74469a37894ea8a7ddd5e356433119</Res_Id>
    13   <Res_Name>物料消耗-计算机耗材</Res_Name>
    14   <Res_Data>4BD2D7C9D91546B09BA4438EE583F682,9C87FFAFD8D24B5BBEA3BF1221DD507B</Res_Data>
    15 </row>
    16 <row>
    17   <Res_Id>608f30860c16430aa8b13f98df0ca9f3</Res_Id>
    18   <Res_Name>物料消耗-水票</Res_Name>
    19   <Res_Data></Res_Data>
    20 </row>
    21 <row>
    22   <Res_Id>87a4cefa112241c1b648454e7b3682d9</Res_Id>
    23   <Res_Name>低值易耗-工具及其他</Res_Name>
    24   <Res_Data></Res_Data>
    25 </row>
    26 <row>
    27   <Res_Id>c2908fe510dd476aa878622dd9d07c83</Res_Id>
    28   <Res_Name>物料消耗-杂品</Res_Name>
    29   <Res_Data></Res_Data>
    30 </row>
    31 <row>
    32   <Res_Id>c9014727c9804c6e9df4cc1bc1487a84</Res_Id>
    33   <Res_Name>劳动保护费-劳保用品</Res_Name>
    34   <Res_Data>D5566FDCDBB448FAB4A48D20A2492626</Res_Data>
    35 </row>
    36 <row>
    37   <Res_Id>d3397fdcb454440f88c9c4f9432b3f40</Res_Id>
    38   <Res_Name>低值易耗-办公设施</Res_Name>
    39   <Res_Data>9C87FFAFD8D24B5BBEA3BF1221DD507B</Res_Data>
    40 </row>
    41 <row>
    42   <Res_Id>d8222bcaeaba460db945324cb0a93a23</Res_Id>
    43   <Res_Name>修理费-计算机备件</Res_Name>
    44   <Res_Data>4BD2D7C9D91546B09BA4438EE583F682</Res_Data>
    45 </row>
    View Code

      那么,如何改变XML行节点的名称呢?代码如下:     

    select Res_Id,Res_Name,Res_Data from UBIPlatform..T_RESOURCE where Res_Parent_Code='741cdd2bef2e479f8c5dd35cf6e8bf2a' FOR XML PATH('RESOURCE')

    原来的行节点<row> 变成了我们在PATH后面括号()中,自定义的名称<RESOURCE>,结果如下:

    <RESOURCE>
      <Res_Id>239dbe35bd8446afb262f62712d8eb1b</Res_Id>
      <Res_Name>修理费-设备备件</Res_Name>
      <Res_Data>4BD2D7C9D91546B09BA4438EE583F682</Res_Data>
    </RESOURCE>
    <RESOURCE>
      <Res_Id>4d35c89868854d649963410a126b4c30</Res_Id>
      <Res_Name>低值易耗-计量器具</Res_Name>
      <Res_Data>4ADEEC453DE04910B0136593CBB4187C</Res_Data>
    </RESOURCE>
    <RESOURCE>
      <Res_Id>4e74469a37894ea8a7ddd5e356433119</Res_Id>
      <Res_Name>物料消耗-计算机耗材</Res_Name>
      <Res_Data>4BD2D7C9D91546B09BA4438EE583F682,9C87FFAFD8D24B5BBEA3BF1221DD507B</Res_Data>
    </RESOURCE>
    <RESOURCE>
      <Res_Id>608f30860c16430aa8b13f98df0ca9f3</Res_Id>
      <Res_Name>物料消耗-水票</Res_Name>
      <Res_Data></Res_Data>
    </RESOURCE>
    <RESOURCE>
      <Res_Id>87a4cefa112241c1b648454e7b3682d9</Res_Id>
      <Res_Name>低值易耗-工具及其他</Res_Name>
      <Res_Data></Res_Data>
    </RESOURCE>
    <RESOURCE>
      <Res_Id>c2908fe510dd476aa878622dd9d07c83</Res_Id>
      <Res_Name>物料消耗-杂品</Res_Name>
      <Res_Data></Res_Data>
    </RESOURCE>
    <RESOURCE>
      <Res_Id>c9014727c9804c6e9df4cc1bc1487a84</Res_Id>
      <Res_Name>劳动保护费-劳保用品</Res_Name>
      <Res_Data>D5566FDCDBB448FAB4A48D20A2492626</Res_Data>
    </RESOURCE>
    <RESOURCE>
      <Res_Id>d3397fdcb454440f88c9c4f9432b3f40</Res_Id>
      <Res_Name>低值易耗-办公设施</Res_Name>
      <Res_Data>9C87FFAFD8D24B5BBEA3BF1221DD507B</Res_Data>
    </RESOURCE>
    <RESOURCE>
      <Res_Id>d8222bcaeaba460db945324cb0a93a23</Res_Id>
      <Res_Name>修理费-计算机备件</Res_Name>
      <Res_Data>4BD2D7C9D91546B09BA4438EE583F682</Res_Data>
    </RESOURCE>
    View Code

    OK,接下来我就用这个FOR XML PATH用在我的问题上,

    @MaterialTypeName nvarchar(200),
    @CentralizedName nvarchar(200),
    @start int,
    @limit int,
    @totalCount int output 
    AS
    BEGIN
        SET NOCOUNT ON;    
        select 
            t_r.Res_Id as ResId,
            t_r.Res_Name as ResName,
            STUFF((select ','+t_r1.Res_Name               
        from UBIPlatform.dbo.T_RESOURCE t_r1 where t_r1.Res_Id in 
            (select nvalue from UBIPlatform.dbo.FN_GETMultiValTable(t_r.Res_Data))            
            for xml path('')),1,1,'') as ResData 
        into 
            #List1  
        from 
            UBIPlatform..T_RESOURCE t_r 
        where Res_Parent_Code='741cdd2bef2e479f8c5dd35cf6e8bf2a'
        
        select 
            ROW_NUMBER() over (order by ResId asc) as RowNumber,
            * into #List2 from #List1
        where (@MaterialTypeName is null or @MaterialTypeName = '' or ResName  like '%'+@MaterialTypeName+'%')
        and (@CentralizedName is null or @CentralizedName = '' or ResData  like '%'+@CentralizedName+'%')
        
        select top(@limit) * from #List2 where RowNumber > @start order by RowNumber asc
        select @totalCount =COUNT(1) from #List2
    END

    就这样,才几行的SQL就把我的问题解决了.

  • 相关阅读:
    使用 Redis 实现分布式锁(转载)
    使用Redis SETNX 命令实现分布式锁(转载)
    linux目录(转载)
    sleep函数作用(转)
    大数据量高并发的数据库优化(转)
    java获取request的url方法区别
    java获取request的头信息
    打分排序系统漫谈2
    打分排序系统漫谈1
    Tree
  • 原文地址:https://www.cnblogs.com/xran/p/3944196.html
Copyright © 2011-2022 走看看