示例:检索雇员信息

此示例检索每个员工的员工 ID 和员工名称。 在 AdventureWorks2012 数据库中,可以从 Employee 表中的 BusinessEntityID 列获取 employeeID。 员工姓名可以从 Person 表获取。 BusinessEntityID 列可用于连接这些表。

假设你希望 FOR XML EXPLICIT 转换生成 XML,如下所示:

<Employee EmpID="1" >  
  <Name FName="Ken" LName="S??nchez" />  
</Employee>  
...  

由于层次结构中有两个级别,因此需要编写两个 SELECT 查询并应用 UNION ALL。 这是检索元素及其属性的值 <Employee> 的第一个查询。 查询将1分配为Tag值为<Employee>元素,并将NULL作为Parent,因为它是顶级元素。

SELECT 1    as Tag,  
       NULL as Parent,  
       E.BusinessEntityID AS [Employee!1!EmpID],  
       NULL       as [Name!2!FName],  
       NULL       as [Name!2!LName]  
FROM   HumanResources.Employee AS E  
INNER JOIN Person.Person AS P  
ON  E.BusinessEntityID = P.BusinessEntityID;  

这是第二个查询。 它检索元素的值 <Name> 。 它将2作为Tag值分配给<Name>元素,并将1作为标记值分配给Parent以标识<Employee>作为父级。

SELECT 2 as Tag,  
       1 as Parent,  
       E.BusinessEntityID,  
       FirstName,   
       LastName   
FROM   HumanResources.Employee AS E  
INNER JOIN Person.Person AS P  
ON  E.BusinessEntityID = P.BusinessEntityID;  

您将这些查询与 UNION ALL 合并,应用 FOR XML EXPLICIT,并指定所需的 ORDER BY 子句。 必须先按 BusinessEntityID 对行集进行排序,然后按名称排序,以便名称中包含 NULL 值的项目先显示。 通过在不使用 FOR XML 子句的情况下执行以下查询,可以看到生成的通用表。

这是最终查询:

SELECT 1    as Tag,  
       NULL as Parent,  
       E.BusinessEntityID as [Employee!1!EmpID],  
       NULL       as [Name!2!FName],  
       NULL       as [Name!2!LName]  
FROM   HumanResources.Employee AS E  
INNER JOIN Person.Person AS P  
ON  E.BusinessEntityID = P.BusinessEntityID  
UNION ALL  
SELECT 2 as Tag,  
       1 as Parent,  
       E.BusinessEntityID,  
       FirstName,   
       LastName   
FROM   HumanResources.Employee AS E  
INNER JOIN Person.Person AS P  
ON  E.BusinessEntityID = P.BusinessEntityID  
ORDER BY [Employee!1!EmpID],[Name!2!FName]  
FOR XML EXPLICIT;  

下面是部分结果:

<Employee EmpID="1">

<Name FName="Ken" LName="S??nchez" />

</Employee>

<Employee EmpID="2">

<Name FName="Terri" LName="Duffy" />

</Employee>

...

第一个 SELECT 指定生成的行集中列的名称。 这些名称构成两个列组。 列名称中具有 Tag 值的 1 组标识 Employee 为元素和 EmpID 属性。 其他列组在列中具有Tag2,并标识<Name>为元素,FNameLName为属性。

下表显示了查询生成的部分行集:

Tag Parent Employee!1!EmpID Name!2!FName Name!2!LName

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

1 NULL 1 NULL NULL

2 1 1 Ken S??nchez

1 NULL 2 NULL NULL

2 1 2 Terri Duffy

1 NULL 3 NULL NULL

2 1 3 Roberto Tamburello

...

这就是处理通用表中的行以生成生成的 XML 树的方式:

第一行标识 Tag1。 因此,标识的是具有Tag值的1列组,Employee!1!EmpID。 此列标识 Employee 为元素名称。 然后创建一个 <Employee> 具有 EmpID 属性的元素。 相应的列值分配给这些属性。

第二行具有 Tag2。 因此,识别出名称中具有Tag值的列是2Name!2!FName, Name!2!LName列组。 这些列名称标识 Name 为元素名称。 < > Name创建具有FName属性和LName属性的元素。 然后将相应的列值分配给这些属性。 此行标识 1Parent. 此子元素被添加到之前的<Employee>元素中。

对于行集中的其余行重复此过程。 请注意对通用表中的行进行排序的重要性,以便 FOR XML EXPLICIT 可以按顺序处理行集并生成所需的 XML。

另请参阅

将 EXPLICIT 模式与 FOR XML 配合使用