我可以从SQL Server存储过程中检索分层数据结构吗?
问题描述:
我有一个Web服务,它的方法之一返回的项目列表,每个拥有项目的另一个列表:我可以从SQL Server存储过程中检索分层数据结构吗?
<TopLevelItems>
<TopLevelItem field1="a" field2="b" ...>
<LowLevelItem fieldA="1" fieldB="2" .../>
<LowLevelItem fieldA="3" fieldB="4" .../>
</TopLevelItem>
</TopLevelItems>
这些列表是从SQL Server数据库使用简单的查询(包括TopLevelItem
和LowLevelItem
检索对应于数据库中的相关表格)。直到现在,为了检索所有这些数据,我需要两个查询:一个用于检索顶层项目,它被执行一次;另一个检索低级项目,每个顶级项目执行一次。
但是,这似乎是非常低效的。我想定义一个存储过程来执行所有必要的查询,并将结果作为分层数据结构进行检索。可能吗?如果是这样,怎么样?
答
分层数据可以使用FOR XML来获得。在这种情况下,你只需要编写一个查询来连接表,然后父子关系将表现为嵌套的XML元素:
DECLARE @sites TABLE (ID INT, Name VARCHAR(50))
INSERT INTO @sites
VALUES (1, 'abc'),
(2, 'def')
DECLARE @siteEnergy TABLE
(
SiteFK INT,
Month INT,
Energy INT
)
INSERT INTO @siteEnergy
VALUES (1, 1, 50),
(1, 2, 49),
(1, 3, 50),
(2, 1, 33),
(2, 2, 34),
(2, 3, 50)
SELECT *
FROM @sites site
JOIN @siteEnergy siteEnergy ON site.id = siteEnergy.sitefk
FOR XML AUTO, ROOT('SiteInformation')
结果:
<SiteInformation>
<site ID="1" Name="abc">
<siteEnergy SiteFK="1" Month="1" Energy="50" />
<siteEnergy SiteFK="1" Month="2" Energy="49" />
<siteEnergy SiteFK="1" Month="3" Energy="50" />
</site>
<site ID="2" Name="def">
<siteEnergy SiteFK="2" Month="1" Energy="33" />
<siteEnergy SiteFK="2" Month="2" Energy="34" />
<siteEnergy SiteFK="2" Month="3" Energy="50" />
</site>
</SiteInformation>
答
使用可以在SP直接
创建XML例
declare @TopLevelItem table (TopID int, field1 varchar(50), field2 varchar(50))
declare @LowLevelItem table (TopID int, fieldA int, fieldB int)
insert into @TopLevelItem values (1, 'a', 'b')
insert into @LowLevelItem values (1, 1, 2)
insert into @LowLevelItem values (1, 3, 4)
select
T.field1 as '@field1',
T.field2 as '@field2',
((select
L.fieldA as '@fieldA',
L.fieldB as '@fieldB'
from @LowLevelItem as L
where T.TopID = L.TopID
for xml path('LowLevelItem'), type))
from @TopLevelItem as T
for xml path('TopLevelItem'), root('TopLevelItems')
结果在SQL服务器
<TopLevelItems>
<TopLevelItem field1="a" field2="b">
<LowLevelItem fieldA="1" fieldB="2" />
<LowLevelItem fieldA="3" fieldB="4" />
</TopLevelItem>
</TopLevelItems>