前言:本人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
这个是我开始写出来的一个.烂到不行.虽然是解决了我的需求.但是显而易见这种办法是不可取的.后来请教同事,跟我介绍了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>
那么,如何改变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>
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就把我的问题解决了.