FOR XML 查询中的 TYPE 指令

在 SQL Server 2000 中,FOR XML 查询的结果始终直接以文本格式返回到客户端。由于 SQL Server 2005 支持 xml 数据类型,因此还可以通过指定 TYPE 指令,请求将 FOR XML 查询的结果返回为 xml 数据类型。这样您便可以在服务器上处理 FOR XML 查询的结果。例如,可以对其指定 XQuery,将结果分配给 xml 类型变量,或编写嵌套 FOR XML 查询

ms190025.note(zh-cn,SQL.90).gif注意:
SQL Server 将 XML 数据类型实例数据以不同的服务器构造结果(如使用 TYPE 指令的 FOR XML 查询)返回到客户端,或者返回到 xml 数据类型用来返回 SQL 表列和输出参数中的 XML 实例数据值的客户端。在客户端应用程序代码中,ADO.NET 提供程序请求从服务器以二进制编码发送此 XML 数据类型信息。但是,如果使用的是不带 TYPE 指令的 FOR XML,则 XML 数据将以字符串类型返回。在任何情况下,客户端访问接口都始终能够处理其中任一种形式的 XML 内容。

示例

下列示例说明了 FOR XML 查询的用途。

A. 检索类型为 XML 的 FOR XML 查询结果

下面的查询检索 Contacts 表中的客户联系信息。由于在 FOR XML 中指定了 TYPE 指令,因此返回的结果的类型为 xml

SELECT ContactID, FirstName, LastName, Phone
FROM Person.Contact
ORDER BY ContactID
FOR XML AUTO, TYPE

下面是部分结果:

<Contact ContactID="1" FirstName="Syed" LastName="Abbas" 
         Phone="398-555-0132"/>
<Contact ContactID="2" FirstName="Catherine" LastName="Abel" 
         Phone="747-555-0171"/>
...

B. 将 FOR XML 查询结果分配给 xml 类型变量

下面的示例中,FOR XML 结果被分配给 xml 类型变量 @x。查询检索 xml 类型的 AdditionalContactInfo 列中的联系信息,如 ContactID、名字、姓氏和电话号码。由于 FOR XML 子句指定了 TYPE 指令,因此 XML 返回为 xml 类型,并分配给某个变量。

DECLARE @x XML
SET @x = (
   SELECT ContactID, 
          FirstName, 
          LastName, 
          AdditionalContactInfo.query('
declare namespace aci="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo";
declare namespace act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";
              //act:telephoneNumber/act:number') as MorePhoneNumbers
   FROM Person.Contact
   FOR XML AUTO, TYPE)
SELECT @x
GO

C. 查询 FOR XML 查询的结果

FOR XML 查询返回 XML。因此,可以将 xml 类型方法(如 query()value())应用于 FOR XML 查询返回的 XML 结果。

在下面的查询中,xml 数据类型的 query() 方法用于查询 FOR XML 查询的结果。有关详细信息,请参阅 query() 方法(xml 数据类型)

SELECT (SELECT ContactID, FirstName, LastName, AdditionalContactInfo.query('
declare namespace aci="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo";
declare namespace act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";
 //act:telephoneNumber/act:number
') as PhoneNumbers
FROM Person.Contact
FOR XML AUTO, TYPE).query('/Person.Contact[1]')

内部 SELECT … FOR XML 查询返回 xml 类型结果,外部 SELECT 将 query() 方法应用于 xml 类型。请注意指定的 TYPE 指令。

结果如下:

<Person.Contact ContactID="1" FirstName="Gustavo" LastName="Achong">
  <PhoneNumbers>
    <act:number xmlns:act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">111-111-1111</act:number>
    <act:number xmlns:act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">112-111-1111</act:number>
  </PhoneNumbers>
</Person.Contact>

在下面的查询中,xml 数据类型的 value() 方法用于检索 SELECT…FOR XML 查询返回的 XML 结果中的值。有关详细信息,请参阅 value() 方法(xml 数据类型)

declare @FirstPhoneFromAdditionalContactInfo varchar(40);
SELECT @FirstPhoneFromAdditionalContactInfo = 
 ( SELECT ContactID, FirstName, LastName, AdditionalContactInfo.query('
declare namespace aci="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo";
declare namespace act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";

   //act:telephoneNumber/act:number
   ') as PhoneNumbers
   FROM Person.Contact Contact
   FOR XML AUTO, TYPE).value('
declare namespace act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";
  /Contact[@ContactID="1"][1]/PhoneNumbers[1]/act:number[1]', 'varchar(40)'
 )
select @FirstPhoneFromAdditionalContactInfo

value() 方法中的 XQuery 路径表达式检索 ContactID 为 1 的客户联系的第一个电话号码。

ms190025.note(zh-cn,SQL.90).gif注意:
如果未指定 TYPE 指令,则返回的 FOR XML 查询结果的类型为 nvarchar(max)

D. 在 INSERT、UPDATE 和 DELETE 中使用 FOR XML 查询结果 (Transact-SQL DML)

下面的示例说明了如何在数据操作语言 (DML) 语句中使用 FOR XML 查询。下面的示例中,FOR XML 返回 xml 类型的实例。INSERT 语句将此 XML 插入表中。

CREATE TABLE T1(intCol int, XmlCol xml)
go
INSERT INTO T1 
VALUES(1, '<Root><ProductDescription ProductModelID="1" /></Root>')
go

CREATE TABLE T2(XmlCol xml)
go
INSERT INTO T2(XmlCol) 
SELECT (SELECT XmlCol.query('/Root') 
        FROM T1 
        FOR XML AUTO,TYPE) 
go