客户端与服务器端 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='5']/@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='5']/@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 格式设置。