示例:检索雇员信息
此示例检索每个雇员的雇员 ID 和雇员姓名。在 AdventureWorks 数据库中,可从 Employee 表中获得 EmployeeID。可从 Contact 表中获得雇员姓名。可使用 ContactID 列来联接表。
假定要让 FOR XML EXPLICIT 转换生成 XML,如下所示:
<Employee EmpID="1" >
<Name FName="Guy" LName="Gilbert" />
</Employee>
...
因为层次结构中有两个级别,所以应编写两个 SELECT 查询并应用 UNION ALL。下面是检索 <Employee> 元素及其属性的值的第一个查询。该查询将值 1 赋给 <Employee> 元素的 Tag,将 NULL 赋给 Parent,因为它是一个顶级元素。
SELECT 1 as Tag,
NULL as Parent,
EmployeeID as [Employee!1!EmpID],
NULL as [Name!2!FName],
NULL as [Name!2!LName]
FROM HumanResources.Employee E, Person.Contact C
WHERE E.ContactID = C.ContactID
下面是第二个查询。它检索 <Name> 元素的值。它将值 2 赋给 <Name> 元素的 Tag,将值 1 赋给 Parent 标记,从而将 <Employee> 标识为父元素。
SELECT 2 as Tag,
1 as Parent,
EmployeeID,
FirstName,
LastName
FROM HumanResources.Employee E, Person.Contact C
WHERE E.ContactID = C.ContactID
可以使用 UNION ALL 组合这些查询,应用 FOR XML EXPLICIT,并指定所需的 ORDER BY 子句。您必须先按 EmployeeID、再按姓名对行集进行排序,以便先显示姓名中的 NULL 值。通过执行下面这个不带 FOR XML 子句的查询,可以看到生成的通用表。
下面是最终查询:
SELECT 1 as Tag,
NULL as Parent,
EmployeeID as [Employee!1!EmpID],
NULL as [Name!2!FName],
NULL as [Name!2!LName]
FROM HumanResources.Employee E, Person.Contact C
WHERE E.ContactID = C.ContactID
UNION ALL
SELECT 2 as Tag,
1 as Parent,
EmployeeID,
FirstName,
LastName
FROM HumanResources.Employee E, Person.Contact C
WHERE E.ContactID = C.ContactID
ORDER BY [Employee!1!EmpID],[Name!2!FName]
FOR XML EXPLICIT
下面是部分结果:
<Employee EmpID="1">
<Name FName="Guy" LName="Gilbert" />
</Employee>
<Employee EmpID="2">
<Name FName="Kevin" LName="Brown" />
</Employee>
...
第一个 SELECT 指定所得到的行集中的列名。这些名称形成两个列组。列名中 Tag 值为 1 的组将 Employee 标识为元素,将 EmpID 标识为属性。另一个列组的列中的 Tag 值为 2,它将 <Name> 标识为元素,将 FName 和 LName 标识为属性。
下表显示了查询生成的部分行集:
Tag Parent Employee!1!EmpID Name!2!FName Name!2!LName
----------- ----------- ---------------- -------------------
1 NULL 1 NULL NULL
2 1 1 Guy Gilbert
1 NULL 2 NULL NULL
2 1 2 Kevin Brown
1 NULL 3 NULL NULL
2 1 3 Roberto Tamburello
...
下面说明了如何处理通用表中的行以生成所得到的 XML 树:
第一行将 Tag 值标识为 1。因此,将标识列名 (Employee!1!EmpID) 中 Tag 值为 1 的列组。此列将 Employee 标识为元素名称。然后,将创建一个带有 EmpID 属性的 <Employee> 元素。将为这些属性分配相应的列值。
第二行的 Tag 值为 2。因此,将标识列名(Name!2!FName 和 Name!2!LName)中 Tag 值为 2 的列组。这些列名将 Name 标识为元素名称。将创建一个带有 FName 和 LName 属性的 <Name> 元素。然后,将为这些属性分配相应的列值。此行将 Parent 标识为 1。此子元素将添加到上一个 <Employee> 元素。
对于行集中的其余行,重复此过程。请注意,对通用表中的行进行排序很重要,因为这使得 FOR XML EXPLICIT 可以按顺序处理行集并生成所需的 XML。