客户端与服务器端 XML 格式 (SQLXML 4.0)

本主题说明在 SQLXML 中客户端与服务器端 XML 格式的一般差异。

客户端格式中不支持多行集查询

使用客户端 XML 格式时不支持生成多个行集的查询。例如,假定您有一个虚拟目录,在其中指定了客户端格式。考虑下面的示例模板,其中的 <sql:query> 块中有两个 SELECT 语句:

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:query>
     SELECT FirstName FROM Person.Person FOR XML Nested; 
     SELECT LastName FROM Person.Person FOR XML Nested  
  </sql:query>
</ROOT>

您可以在应用程序代码中执行此模板,但会返回错误,因为客户端 XML 格式不支持多个行集的格式。如果在两个单独的 <sql:query> 块中指定上述查询,将会得到所需结果。

timestamp 在客户端与服务器端格式中的映射方式不同

在服务器端 XML 格式中,timestamp 类型的数据库列映射为 i8 XDR 类型(如果在查询中指定了 XMLDATA 选项)。

在客户端 XML 格式中,timestamp 类型的数据库列映射为 uri 或 bin.base64 XDR 类型(取决于是否在查询中指定了二进制 base64 选项)。bin.base64 XDR 类型在使用 updategram 和 bulkload 功能时十分有用,因为此类型将转换为 SQL Servertimestamp 类型。这样即可成功执行插入、更新或删除操作。

服务器端 XML 格式使用深层 VARIANT

在服务器端 XML 格式中,使用深层类型的 VARIANT 类型。如果使用客户端 XML 格式,变量将转换为 Unicode 字符串,并且不使用 VARIANT 的子类型。

NESTED 模式与 AUTO 模式

客户端 FOR XML 的 NESTED 模式类似于服务器端 FOR XML 的 AUTO 模式,不过以下方面除外:

使用服务器端的 AUTO 模式查询视图时,在生成的 XML 中将视图名称返回为元素名称。

例如,假定对 AdventureWorks2008R2 数据库中的 Person.Person 表创建了以下视图:

CREATE VIEW ContactView AS (SELECT BusinessEntityID as CID,
                               FirstName  as FName,
                               LastName  as LName
                        FROM Person.Person);

以下模板指定针对 ContactView 视图的查询,同时指定了服务器端 XML 格式:

 <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:query client-side-xml="0">
    SELECT *
    FROM   ContactView
    FOR XML AUTO
  </sql:query>
</ROOT>

执行该模板时,将返回以下 XML。(仅显示部分结果。)请注意,元素名称就是对其执行查询的视图的名称。

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <ContactView CID="1" FName="Gustavo" LName="Achong" /> 
  <ContactView CID="2" FName="Catherine" LName="Abel" /> 
...
</ROOT>

使用对应的 NESTED 模式指定客户端 XML 格式时,在生成的 XML 中将基表名称返回为元素名称。例如,以下修订的模板执行同一 SELECT 语句,但在客户端执行 XML 格式设置(即 client-side-xml 在该模板中设置为 true):

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:query client-side-xml="1">
    SELECT *
    FROM   ContactView
    FOR XML NESTED
  </sql:query>
</ROOT>

执行此模板将生成以下 XML。请注意,在此情况下的元素名称就是基表名称。

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Person.Person CID="1" FName="Gustavo" LName="Achong" /> 
  <Person.Person CID="2" FName="Catherine" LName="Abel" /> 
...
</ROOT>

使用服务器端 FOR XML 的 AUTO 模式时,在生成的 XML 中将查询中指定的表别名返回为元素名称。

例如,考虑以下模板:

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:query client-side-xml="0">
    SELECT FirstName as fname,
           LastName as lname
    FROM   Person.Person AS C
    FOR XML AUTO
  </sql:query>
</ROOT>

执行此模板将生成以下 XML:

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <C fname="Gustavo" lname="Achong" /> 
  <C fname="Catherine" lname="Abel" /> 
...
</ROOT> 

使用客户端 FOR XML 的 NESTED 模式时,在生成的 XML 中将表名返回为元素名称。(不使用查询中指定的表别名。)例如,考虑以下模板:

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:query client-side-xml="1">
    SELECT FirstName as fname,
           LastName as lname
    FROM   Person.Person C
    FOR XML NESTED
  </sql:query>
</ROOT>

执行此模板将生成以下 XML:

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Person.Person fname="Gustavo" lname="Achong" /> 
  <Person.Person fname="Catherine" lname="Abel" /> 
...
</ROOT>

如果您的查询将列返回为 dbobject 查询,则无法对这些列使用别名。

例如,考虑下面的模板,该模板执行的查询返回员工 ID 和照片。

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<sql:query client-side-xml="1">
   SELECT ProductPhotoID, LargePhoto as P
   FROM   Production.ProductPhoto
   WHERE  ProductPhotoID=5
   FOR XML NESTED, elements
</sql:query>
</ROOT>

执行此模板将返回作为 dbobject 查询的 Photo 列。在这个 dbobject 查询中,@P 指不存在的列名。

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Production.ProductPhoto>
    <ProductPhotoID>5</ProductPhotoID>
    <LargePhoto>dbobject/Production.ProductPhoto[@ProductPhotoID=&apos;5&apos;]/@P</LargePhoto>
  </Production.ProductPhoto>
</ROOT>

如果在服务器上执行 XML 格式设置 (client-side-xml="0"),则可以对返回 dbobject 查询的列使用别名,该查询返回实际表和列名(即便已经指定了别名)。例如,以下模板执行一个查询,并且在服务器上执行 XML 格式设置(未指定 client-side-xml 选项,且没有为虚拟根目录选择**“在客户端运行”**选项)。该查询还指定了 AUTO 模式(而不是客户端 NESTED 模式)。

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<sql:query 
   SELECT ProductPhotoID, LargePhoto as P
   FROM   Production.ProductPhoto
   WHERE  ProductPhotoID=5
   FOR XML AUTO, elements
</sql:query>
</ROOT>

执行此模板时,将返回以下 XML 文档(请注意,没有在针对 LargePhoto 列的 dbobject 查询中使用别名):

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Production.ProductPhoto>
    <ProductPhotoID>5</ProductPhotoID>
    <LargePhoto>dbobject/Production.ProductPhoto[@ProductPhotoID=&apos;5&apos;]/@LargePhoto</LargePhoto>
  </Production.ProductPhoto>
</ROOT>

客户端与服务器端 XPath

客户端 XPath 与服务器端 XPath 的工作方式相同,以下几点除外:

  • 使用客户端 XPath 查询时所应用的数据转换与使用服务器端 XPath 查询时所应用的数据转换有所不同。客户端 XPath 使用 CAST 而不是 CONVERT 模式 126。

  • 如果在模板中指定 client-side-xml="0" (false),则表示请求服务器端 XML 格式。因此,不能指定 FOR XML NESTED,因为服务器不识别 NESTED 选项。这将生成一个错误。必须使用服务器确实可以识别的 AUTO、RAW 或 EXPLICIT 模式。

  • 如果在模板中指定 client-side-xml="1" (true),则表示请求客户端 XML 格式。在这种情况下,可以指定 FOR XML NESTED。如果指定 FOR XML AUTO,尽管在模板中指定了 client-side-xml="1" ,也将在服务器端执行 XML 格式设置。