SQL Server的,您可以检索数据为XML支持的FOR XML子句,其中可包括在您的查询。您可以使用的FOR XML子句中的主要(外)查询以及子查询。该条款支持众多的选项,让您定义格式的XML数据。
当您包含的FOR XML子句在查询中,您必须指定一个四个支持模式,原料,汽车,明确,或路径。可以作出的选择每个模式不同,因此该模式;然而,许多选项都分担模式。在本文中,我解释如何使用这些模式,每一个检索数据为XML ,并提供范例,证明他们是如何使用的各种选择。
原始的模式生成一个单一的XML元素的每一行的结果集返回的查询。
要使用的FOR XML子句在原始模式下,只需附加条款和RAW关键字到您的SELECT语句,如以下示例所示:
SELECT e.EmployeeID, c.FirstName, c.MiddleName, c.LastName
FROM HumanResources.Employee e INNER JOIN Person.Contact c
ON c.ContactID = e.ContactID
WHERE c.FirstName = 'Rob'
FOR XML RAW;
请注意, SELECT语句本身是一个非常基本的查询。 (声明中调用数据的AdventureWorks样本数据库。 )如果没有的FOR XML子句,该声明将返回以下结果:
EmployeeID FirstName MiddleName LastName
---------- --------- ---------- --------
4 Rob NULL Walters
168 Rob T Caron
<row EmployeeID="4" FirstName="Rob" LastName="Walters" />
<row EmployeeID="168" FirstName="Rob" MiddleName="T" LastName="Caron" />
Note: You can include a FOR XML clause only in SELECT statements, if those statements define the outer, or top-level, query. However, you can also include the clause in INSERT, UPDATE, and DELETE statements that are part of a subquery.
SELECT e.EmployeeID, c.FirstName, c.MiddleName, c.LastName
FROM HumanResources.Employee e INNER JOIN Person.Contact c
ON c.ContactID = e.ContactID
WHERE c.FirstName = 'Rob'
FOR XML RAW ('Employee');
现在相关的内容每一行返回的查询将被命名为<Employee> ,而不是默认的<row> :
<Employee EmployeeID="4" FirstName="Rob" LastName="Walters" />
<Employee EmployeeID="168" FirstName="Rob" MiddleName="T" LastName="Caron" />
除了能够提供的名称列的内容,您也可以指定一个根元素创建包的所有其他要素。要创建一个根元素,增加根系的关键字,您的FOR XML子句:
SELECT e.EmployeeID, c.FirstName, c.MiddleName, c.LastName
FROM HumanResources.Employee e INNER JOIN Person.Contact c
ON c.ContactID = e.ContactID
WHERE c.FirstName = 'Rob'
FOR XML RAW ('Employee'), ROOT;
请注意,您必须包括一个逗号当添加一个选项,如根,以独立的要素。至于下面的结果表明,一个<根目录>元素现在包含在XML :
<root>
<Employee EmployeeID="4" FirstName="Rob" LastName="Walters" />
<Employee EmployeeID="168" FirstName="Rob" MiddleName="T" LastName="Caron" />
</root>
至于该行的内容,您也可以提供一个特定名称的根元素:
SELECT e.EmployeeID, c.FirstName, c.MiddleName, c.LastName
FROM HumanResources.Employee e INNER JOIN Person.Contact c
ON c.ContactID = e.ContactID
WHERE c.FirstName = 'Rob'
FOR XML RAW ('Employee'), ROOT ('Employees');
在这种情况下,我已经命名根元素<Employees>所示,结果如下:
<Employees>
<Employee EmployeeID="4" FirstName="Rob" LastName="Walters" />
<Employee EmployeeID="168" FirstName="Rob" MiddleName="T" LastName="Caron" />
</Employees>
此时,我的例子表明您添加列的值作为属性,每一行内容。这是默认行为的原始模式。不过,您可以代替指定列的值添加子元素的行元素的要素列入的选项中的FOR XML子句:
SELECT e.EmployeeID, c.FirstName, c.MiddleName, c.LastName
FROM HumanResources.Employee e INNER JOIN Person.Contact c
ON c.ContactID = e.ContactID
WHERE c.FirstName = 'Rob'
FOR XML RAW ('Employee'), ROOT ('Employees'), ELEMENTS;
再说一遍,我也加入了逗号分隔的选项。正如你所看到的结果如下,每个<Employee>元素现在包含了一套儿童要素相对应的列返回的查询:
<Employees>
<Employee>
<EmployeeID>4</EmployeeID>
<FirstName>Rob</FirstName>
<LastName>Walters</LastName>
</Employee>
<Employee>
<EmployeeID>168</EmployeeID>
<FirstName>Rob</FirstName>
<MiddleName>T</MiddleName>
<LastName>Caron</LastName>
</Employee>
</Employees>
现在<Employee>内容不再包括任何属性和提供的所有数据是通过个别儿童的内容。
如果你看回的XML返回前面的示例中,您会发现该数据为员工4 (罗布沃尔特斯)不包括中间名。这是因为MiddleName值为空的源数据,并根据预设,没有内容是创建一个列的值为空。不过,您可以覆写这个行为,增加XSINIL关键字的内容选择:
SELECT e.EmployeeID, c.FirstName, c.MiddleName, c.LastName
FROM HumanResources.Employee e INNER JOIN Person.Contact c
ON c.ContactID = e.ContactID
WHERE c.FirstName = 'Rob'
FOR XML RAW ('Employee'), ROOT ('Employees'), ELEMENTS XSINIL;
现在的结果将包括一个因素MiddleName栏,将包括将xsi :无属性,价值真正当一个值为空,显示在下面的XML :
<Employees xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Employee>
<EmployeeID>4</EmployeeID>
<FirstName>Rob</FirstName>
<MiddleName xsi:nil="true" />
<LastName>Walters</LastName>
</Employee>
<Employee>
<EmployeeID>168</EmployeeID>
<FirstName>Rob</FirstName>
<MiddleName>T</MiddleName>
<LastName>Caron</LastName>
</Employee>
</Employees>
请注意, xmlns : XSI的属性也已添加到根节点和提供的名称默认架构实例。
另一个重要的选择,是支持的RAW节点XMLSCHEMA ,其中规定,一个内联W3C XML架构(结构描述)是包含在XML数据。您添加了XMLSCHEMA选择以相同的方式添加其他选项:
SELECT e.EmployeeID, c.FirstName, c.MiddleName, c.LastName
FROM HumanResources.Employee e INNER JOIN Person.Contact c
ON c.ContactID = e.ContactID
WHERE c.FirstName = 'Rob'
FOR XML RAW ('Employee'), ROOT ('Employees'), ELEMENTS XSINIL, XMLSCHEMA;
正如你所看到的结果如下,架构完全界定,并纳入了XML结果:
<Employees xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsd:schema targetNamespace="urn:schemas-microsoft-com:sql:SqlRowSet1" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sqltypes="http://schemas.microsoft.com/sqlserver/2004/sqltypes" elementFormDefault="qualified">
<xsd:import namespace="http://schemas.microsoft.com/sqlserver/2004/sqltypes" schemaLocation="http://schemas.microsoft.com/sqlserver/2004/sqltypes/sqltypes.xsd" />
<xsd:element name="Employee">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="EmployeeID" type="sqltypes:int" nillable="1" />
<xsd:element name="FirstName" nillable="1">
<xsd:simpleType sqltypes:sqlTypeAlias="[AdventureWorks].[dbo].[Name]">
<xsd:restriction base="sqltypes:nvarchar" sqltypes:localeId="1033" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth" sqltypes:sqlSortId="52">
<xsd:maxLength value="50" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="MiddleName" nillable="1">
<xsd:simpleType sqltypes:sqlTypeAlias="[AdventureWorks].[dbo].[Name]">
<xsd:restriction base="sqltypes:nvarchar" sqltypes:localeId="1033" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth" sqltypes:sqlSortId="52">
<xsd:maxLength value="50" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="LastName" nillable="1">
<xsd:simpleType sqltypes:sqlTypeAlias="[AdventureWorks].[dbo].[Name]">
<xsd:restriction base="sqltypes:nvarchar" sqltypes:localeId="1033" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth" sqltypes:sqlSortId="52">
<xsd:maxLength value="50" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<Employee xmlns="urn:schemas-microsoft-com:sql:SqlRowSet1">
<EmployeeID>4</EmployeeID>
<FirstName>Rob</FirstName>
<MiddleName xsi:nil="true" />
<LastName>Walters</LastName>
</Employee>
<Employee xmlns="urn:schemas-microsoft-com:sql:SqlRowSet1">
<EmployeeID>168</EmployeeID>
<FirstName>Rob</FirstName>
<MiddleName>T</MiddleName>
<LastName>Caron</LastName>
</Employee>
</Employees>
当您指定的模式建立,您也可以指定名称的目标命名空间。例如,下面的FOR XML子句包括XMLSCHEMA选择,其次是名称的目标名字空间(urn:schema_example.com):
SELECT e.EmployeeID, c.FirstName, c.MiddleName, c.LastName
FROM HumanResources.Employee e INNER JOIN Person.Contact c
ON c.ContactID = e.ContactID
WHERE c.FirstName = 'Rob'
FOR XML RAW ('Employee'), ROOT ('Employees'), ELEMENTS XSINIL,
XMLSCHEMA ('urn:schema_example.com');
该声明将返回相同的结果与前一个范例,但在XML ,现在将包括新名称的目标命名空间。
在SELECT语句中显示前面的例子取自数据来自非的XML列(在这种情况下,整数和字符串栏) 。不过,您也可以查询检索数据从XML列。在这种情况下,对XML的条款将纳入数据取自到一个XML列的XML结果集。
例如,下面的SELECT语句使用XML query ( )方法来检索与教育有关的数据恢复列在JobCandidate表:
SELECT e.EmployeeID, c.FirstName, c.LastName,
jc.Resume.query('declare namespace ns=
"http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/Resume";
/ns:Resume/ns:Education')
FROM HumanResources.Employee e INNER JOIN Person.Contact c
ON c.ContactID = e.ContactID
INNER JOIN HumanResources.JobCandidate jc
ON e.EmployeeID = jc.EmployeeID
WHERE e.EmployeeID = 268
FOR XML RAW ('Employee'), ELEMENTS;
query ( )方法本身撷取以下数据恢复栏:
<ns:Education xmlns:ns="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/Resume">
<ns:Edu.Level>Bachelor</ns:Edu.Level>
<ns:Edu.StartDate>1986-09-15Z</ns:Edu.StartDate>
<ns:Edu.EndDate>1990-05-20Z</ns:Edu.EndDate>
<ns:Edu.Degree>Bachelor of Arts and Science</ns:Edu.Degree>
<ns:Edu.Major>Business</ns:Edu.Major>
<ns:Edu.Minor />
<ns:Edu.GPA>3.3</ns:Edu.GPA>
<ns:Edu.GPAScale>4</ns:Edu.GPAScale>
<ns:Edu.School>Louisiana Business College of New Orleans</ns:Edu.School>
<ns:Edu.Location>
<ns:Location>
<ns:Loc.CountryRegion>US </ns:Loc.CountryRegion>
<ns:Loc.State>LA</ns:Loc.State>
<ns:Loc.City>New Orleans</ns:Loc.City>
</ns:Location>
</ns:Edu.Location>
</ns:Education>
此数据纳入其余结果集当您使用的FOR XML子句,所显示的结果如下:
<Employee>
<EmployeeID>268</EmployeeID>
<FirstName>Stephen</FirstName>
<LastName>Jiang</LastName>
<ns:Education xmlns:ns="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/Resume">
<ns:Edu.Level>Bachelor</ns:Edu.Level>
<ns:Edu.StartDate>1986-09-15Z</ns:Edu.StartDate>
<ns:Edu.EndDate>1990-05-20Z</ns:Edu.EndDate>
<ns:Edu.Degree>Bachelor of Arts and Science</ns:Edu.Degree>
<ns:Edu.Major>Business</ns:Edu.Major>
<ns:Edu.Minor />
<ns:Edu.GPA>3.3</ns:Edu.GPA>
<ns:Edu.GPAScale>4</ns:Edu.GPAScale>
<ns:Edu.School>Louisiana Business College of New Orleans</ns:Edu.School>
<ns:Edu.Location>
<ns:Location>
<ns:Loc.CountryRegion>US </ns:Loc.CountryRegion>
<ns:Loc.State>LA</ns:Loc.State>
<ns:Loc.City>New Orleans</ns:Loc.City>
</ns:Location>
</ns:Edu.Location>
</ns:Education>
</Employee>
正如你所看到的, <ns:Education>元素及其子元素中增加了XML数据。上定义的命名空间中的数据源的XML列也包括在内。