使用 sql:relationship 指定关系 (SQLXML 4.0)
适用于: SQL Server Azure SQL 数据库
可以对 XML 文档中的元素建立相关性。 元素可以按层次结构方式嵌套,并且可以在元素之间指定 ID、IDREF 或 IDREFS 关系。
例如,在 XSD 架构中,<Customer> 元素包含< Order> 子元素。 当架构映射到 AdventureWorks 数据库时,<Customer> 元素将映射到 Sales.Customer 表<,Order> 元素映射到 Sales.SalesOrderHeader 表。 由于是由客户下订单,因此,基础表 Sales.Customer 和 Sales.SalesOrderHeader 是相关的。 Sales.SalesOrderHeader 表中的 CustomerID 是外键,它引用 Sales.Customer 表中的 CustomerID 主键。 可以使用 sql:relationship 批注在映射架构元素之间建立这些关系。
在带批注的 XSD 架构中, sql:relationship 注释用于根据元素映射到的基础表之间的主键和外键关系分层嵌套架构元素。 在指定 sql:relationship 批注时,必须标识以下内容:
父表 (Sales.Customer) 和子表 (Sales.SalesOrderHeader)。
组成父表与子表间关系的一列或多列。 例如,CustomerID 列,该列同时出现在父表和子表中。
此信息用于生成适当的层次结构。
若要提供表名和必要的联接信息,请对 sql:relationship 批注指定以下属性。 这些属性仅对 <sql:relationship> 元素有效:
Name
指定关系的唯一名称。
Parent
指定父关系(表)。 这是一个可选属性;如果未指定此属性,将从文档的子层次结构中的信息获得父表名称。 如果架构指定两个父子层次结构,这些层次结构使用相同的 <sql:relationship> 但不同的父元素,则不要在 sql:relationship> 中<指定父属性。 此信息将从架构的层次结构中获得。
parent-key
指定父项的父键。 如果父键由多列组成,则指定值时应在各值之间使用空格。 在为多列键指定的值与为对应的子键指定的值之间存在位置映射。
孩子
指定子关系(表)。
child-key
在引用父项中父键的子项中指定子键。 如果子键由多个属性(列)组成,则指定子键值时应在各值之间使用空格。 在为多列键指定的值与为对应的父键指定的值之间存在位置映射。
逆
updategram 使用 sql:relationship> 指定的<此属性。 有关详细信息,请参阅 指定 sql:relationship 上的 sql:inverse 属性。
必须在包含子元素的元素中指定 sql:key-fields 批注,<该元素在元素和子元素之间定义了 sql:relationship>,并且不提供父元素中指定的表的主键。 即使架构未指定 <sql:relationship>,也必须指定 sql:key-fields 来生成正确的层次结构。 有关详细信息,请参阅 使用 sql:key-fields 标识键列。
若要在结果中生成适当的嵌套,建议 在所有架构中指定 sql:key-fields 。
示例
若要创建使用以下示例的工作示例,必须满足某些要求。 有关详细信息,请参阅 运行 SQLXML 示例的要求。
A. 针对元素指定 sql:relationship 批注
以下带批注的 XSD 架构包括 <Customer> 和< Order> 元素。 <Order> 元素是 Customer> 元素的<子元素。
在架构中,sql:relationship 注释是在 Order> 子元素上<指定的。 关系本身在 xsd:appinfo> 元素中<定义。
关系<>元素将 Sales.SalesOrderHeader 表中的 CustomerID 标识为引用 Sales.Customer 表中 CustomerID 主键的外键。 因此,属于客户的订单显示为该 <Customer> 元素的子元素。
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:sql="urn:schemas-microsoft-com:mapping-schema">
<xsd:annotation>
<xsd:appinfo>
<sql:relationship name="CustOrders"
parent="Sales.Customer"
parent-key="CustomerID"
child="Sales.SalesOrderHeader"
child-key="CustomerID" />
</xsd:appinfo>
</xsd:annotation>
<xsd:element name="Customer" sql:relation="Sales.Customer" type="CustomerType" />
<xsd:complexType name="CustomerType" >
<xsd:sequence>
<xsd:element name="Order"
sql:relation="Sales.SalesOrderHeader"
sql:relationship="CustOrders" >
<xsd:complexType>
<xsd:attribute name="SalesOrderID" type="xsd:integer" />
<xsd:attribute name="CustomerID" type="xsd:string" />
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="CustomerID" type="xsd:string" />
</xsd:complexType>
</xsd:schema>
前一个架构使用命名关系。 还可以指定未命名关系。 结果是相同的。
这是一个经修订的架构,在其中指定未命名关系:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:sql="urn:schemas-microsoft-com:mapping-schema">
<xsd:element name="Customer" sql:relation="Sales.Customer" type="CustomerType" />
<xsd:complexType name="CustomerType" >
<xsd:sequence>
<xsd:element name="Order"
sql:relation="Sales.SalesOrderHeader">
<xsd:annotation>
<xsd:appinfo>
<sql:relationship
parent="Sales.Customer"
parent-key="CustomerID"
child="Sales.SalesOrderHeader"
child-key="CustomerID" />
</xsd:appinfo>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="SalesOrderID" type="xsd:integer" />
<xsd:attribute name="CustomerID" type="xsd:string" />
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="CustomerID" type="xsd:string" />
</xsd:complexType>
</xsd:schema>
针对架构测试示例 XPath 查询
复制上面的架构代码,并将它粘贴到文本文件中。 将文件另存为 sql-relationship.xml。
复制下面的模板,然后将其粘贴到文本文件中。 在您保存 sql-relationship.xml 的相同目录中将该文件另存为 sql-relationshipT.xml。
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql"> <sql:xpath-query mapping-schema="sql-relationship.xml"> /Customer[@CustomerID=1] </sql:xpath-query> </ROOT>
为映射架构 (sql-relationship.xml) 指定的目录路径是相对于模板保存目录的相对路径。 也可以指定绝对路径,例如:
mapping-schema="C:\MyDir\sql-relationship.xml"
创建并使用 SQLXML 4.0 测试脚本 (Sqlxml4test.vbs) 执行该模板。
有关详细信息,请参阅 使用 ADO 执行 SQLXML 查询。
下面是结果集:
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<Customer CustomerID="1">
<Order OrderID="43860" CustomerID="1" />
<Order OrderID="44501" CustomerID="1" />
<Order OrderID="45283" CustomerID="1" />
<Order OrderID="46042" CustomerID="1" />
</Customer>
</ROOT>
B. 指定关系链
对于本示例,假定您需要以下 XML 文档,该文档使用从 AdventureWorks 数据库获得的数据:
<Order SalesOrderID="43659">
<Product Name="Mountain Bike Socks, M"/>
<Product Name="Sport-100 Helmet, Blue"/>
...
</Order>
...
对于 Sales.SalesOrderHeader 表中的每个订单,XML 文档有一个 <Order> 元素。 每个 <Order> 元素都有 Product> 子元素的列表<,每个产品针对订单中请求的每个产品都有一个。
若要指定将生成此层次结构的 XSD 架构,您必须指定两个关系:OrderOD 和 ODProduct。 OrderOD 关系在 Sales.SalesOrderHeader 表与 Sales.SalesOrderDetail 表之间指定父子关系。 ODProduct 关系指定 Sales.SalesOrderDetail 表与 Production.Product 表之间的关系。
在以下架构中,Product> 元素上的< msdata:relationship 注释指定两个值:OrderOD 和 ODProduct。 指定这些值的顺序非常重要。
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:msdata="urn:schemas-microsoft-com:mapping-schema">
<xsd:annotation>
<xsd:appinfo>
<msdata:relationship name="OrderOD"
parent="Sales.SalesOrderHeader"
parent-key="SalesOrderID"
child="Sales.SalesOrderDetail"
child-key="SalesOrderID" />
<msdata:relationship name="ODProduct"
parent="Sales.SalesOrderDetail"
parent-key="ProductID"
child="Production.Product"
child-key="ProductID" />
</xsd:appinfo>
</xsd:annotation>
<xsd:element name="Order" msdata:relation="Sales.SalesOrderHeader"
msdata:key-fields="SalesOrderID" type="OrderType" />
<xsd:complexType name="OrderType" >
<xsd:sequence>
<xsd:element name="Product" msdata:relation="Production.Product"
msdata:key-fields="ProductID"
msdata:relationship="OrderOD ODProduct">
<xsd:complexType>
<xsd:attribute name="Name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="SalesOrderID" type="xsd:integer" />
</xsd:complexType>
</xsd:schema>
您可以指定匿名关系,而不指定命名关系。 在本例中,批注>的<整个内容...</annotation> 描述这两种关系,显示为 Product> 的<子元素。
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:msdata="urn:schemas-microsoft-com:mapping-schema">
<xsd:element name="Order" msdata:relation="Sales.SalesOrderHeader"
msdata:key-fields="SalesOrderID" type="OrderType" />
<xsd:complexType name="OrderType" >
<xsd:sequence>
<xsd:element name="Product" msdata:relation="Production.Product"
msdata:key-fields="ProductID" >
<xsd:annotation>
<xsd:appinfo>
<msdata:relationship
parent="Sales.SalesOrderHeader"
parent-key="SalesOrderID"
child="Sales.SalesOrderDetail"
child-key="SalesOrderID" />
<msdata:relationship
parent="Sales.SalesOrderDetail"
parent-key="ProductID"
child="Production.Product"
child-key="ProductID" />
</xsd:appinfo>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="Name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="SalesOrderID" type="xsd:integer" />
</xsd:complexType>
</xsd:schema>
针对架构测试示例 XPath 查询
复制上面的架构代码,并将它粘贴到文本文件中。 将文件另存为 relationshipChain.xml。
复制下面的模板,然后将其粘贴到文本文件中。 在您保存 relationshipChain.xml 的相同目录中将该文件另存为 relationshipChainT.xml。
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql"> <sql:xpath-query mapping-schema="relationshipChain.xml"> /Order </sql:xpath-query> </ROOT>
为映射架构 (relationshipChain.xml) 指定的目录路径是相对于模板保存目录的相对路径。 也可以指定绝对路径,例如:
mapping-schema="C:\MyDir\relationshipChain.xml"
创建并使用 SQLXML 4.0 测试脚本 (Sqlxml4test.vbs) 执行该模板。
有关详细信息,请参阅 使用 ADO 执行 SQLXML 查询。
下面是结果集:
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<Order SalesOrderID="43659">
<Product Name="Mountain Bike Socks, M" />
<Product Name="Sport-100 Helmet, Blue" />
<Product Name="AWC Logo Cap" />
<Product Name="Long-Sleeve Logo Jersey, M" />
<Product Name="Long-Sleeve Logo Jersey, XL" />
...
</Order>
...
</ROOT>
°C 针对属性指定关系批注
此示例中的架构包括 <> <CustomerID> 子元素和 IDREFS 类型的 OrderIDList 属性。 Customer <> 元素映射到 AdventureWorks 数据库中的 Sales.Customer 表。 默认情况下,此映射的范围适用于所有子元素或属性,除非对子元素或属性指定 sql:relation,在这种情况下,必须使用关系>元素定义<适当的主键/外键关系。 使用关系注释指定不同表的子元素或属性还必须指定关系批注。
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:sql="urn:schemas-microsoft-com:mapping-schema">
<xsd:annotation>
<xsd:appinfo>
<sql:relationship name="CustOrders"
parent="Sales.Customer"
parent-key="CustomerID"
child="Sales.SalesOrderHeader"
child-key="CustomerID" />
</xsd:appinfo>
</xsd:annotation>
<xsd:element name="Customer" sql:relation="Sales.Customer" type="CustomerType" />
<xsd:complexType name="CustomerType" >
<xsd:sequence>
<xsd:element name="CustomerID" type="xsd:string" />
</xsd:sequence>
<xsd:attribute name="OrderIDList"
type="xsd:IDREFS"
sql:relation="Sales.SalesOrderHeader"
sql:field="SalesOrderID"
sql:relationship="CustOrders" >
</xsd:attribute>
</xsd:complexType>
</xsd:schema>
针对架构测试示例 XPath 查询
复制上面的架构代码,并将它粘贴到文本文件中。 将文件另存为 relationship-on-attribute.xml。
复制以下模板并将其粘贴到文件中。 在您保存 relationship-on-attribute.xml 的相同目录中将该文件另存为 relationship-on-attributeT.xml。 模板中的查询选择 CustomerID 为 1 的客户。
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql"> <sql:xpath-query mapping-schema="relationship-on-attribute.xml"> /Customer[CustomerID=1] </sql:xpath-query> </ROOT>
为映射架构 (relationship-on-attribute.xml) 指定的目录路径是相对于模板保存目录的相对路径。 也可以指定绝对路径,例如:
mapping-schema="C:\MyDir\relationship-on-attribute.xml"
创建并使用 SQLXML 4.0 测试脚本 (Sqlxml4test.vbs) 执行该模板。
有关详细信息,请参阅 使用 ADO 执行 SQLXML 查询。
下面是结果集:
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<Customer OrderIDList="43860 44501 45283 46042">
<CustomerID>1</CustomerID>
</Customer>
</ROOT>
D. 针对多个元素指定 sql:relationship
在此示例中,带批注的 XSD 架构包含 <Customer>、<Order 和< OrderDetail>> 元素。
<Order> 元素是 Customer> 元素的<子元素。 <sql:relationship> 是在 Order> 子元素上<指定的;因此,属于客户的订单显示为 Customer> 的<子元素。
<Order> 元素包括 <OrderDetail> 子元素。 <sql:relationship> 是在 OrderDetail> 子元素上<指定的,因此与订单相关的顺序详细信息显示为该< Order> 元素的子元素。
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:sql="urn:schemas-microsoft-com:mapping-schema">
<xsd:annotation>
<xsd:appinfo>
<sql:relationship name="CustOrders"
parent="Sales.Customer"
parent-key="CustomerID"
child="Sales.SalesOrderHeader"
child-key="CustomerID" />
<sql:relationship name="OrderOrderDetail"
parent="Sales.SalesOrderHeader"
parent-key="SalesOrderID"
child="Sales.SalesOrderDetail"
child-key="SalesOrderID" />
</xsd:appinfo>
</xsd:annotation>
<xsd:element name="Customer" sql:relation="Sales.Customer" >
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Order" sql:relation="Sales.SalesOrderHeader"
sql:relationship="CustOrders" maxOccurs="unbounded" >
<xsd:complexType>
<xsd:sequence>
<xsd:element name="OrderDetail"
sql:relation="Sales.SalesOrderDetail"
sql:relationship="OrderOrderDetail"
maxOccurs="unbounded" >
<xsd:complexType>
<xsd:attribute name="SalesOrderID" type="xsd:integer" />
<xsd:attribute name="ProductID" type="xsd:string" />
<xsd:attribute name="OrderQty" type="xsd:integer" />
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="SalesOrderID" type="xsd:integer" />
<xsd:attribute name="OrderDate" type="xsd:date" />
<xsd:attribute name="CustomerID" type="xsd:string" />
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="CustomerID" type="xsd:string" />
</xsd:complexType>
</xsd:element>
</xsd:schema>
针对架构测试示例 XPath 查询
复制上面的架构代码,并将它粘贴到文本文件中。 将文件另存为 relationship-multiple-elements.xml。
复制以下模板,并将它粘贴到文本文件中。 在您保存 relationship-multiple-elements.xml 的相同目录中将该文件另存为 relationship-multiple-elementsT.xml。 模板中的查询将返回 CustomerID 为 1 且 SalesOrderID 为 43860 的客户的订单信息。
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql"> <sql:xpath-query mapping-schema="relationship-multiple-elements.xml"> /Customer[@CustomerID=1]/Order[@SalesOrderID=43860] </sql:xpath-query> </ROOT>
为映射架构 (relationship-multiple-elements.xml) 指定的目录路径是相对于模板保存目录的相对路径。 也可以指定绝对路径,例如:
mapping-schema="C:\MyDir\relationship-multiple-elements.xml"
创建并使用 SQLXML 4.0 测试脚本 (Sqlxml4test.vbs) 执行该模板。
有关详细信息,请参阅 使用 ADO 执行 SQLXML 查询。
下面是结果集:
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<Order SalesOrderID="43860" OrderDate="2001-08-01" CustomerID="1">
<OrderDetail SalesOrderID="43860" ProductID="761" OrderQty="2" />
<OrderDetail SalesOrderID="43860" ProductID="770" OrderQty="1" />
<OrderDetail SalesOrderID="43860" ProductID="758" OrderQty="2" />
<OrderDetail SalesOrderID="43860" ProductID="765" OrderQty="2" />
<OrderDetail SalesOrderID="43860" ProductID="732" OrderQty="1" />
<OrderDetail SalesOrderID="43860" ProductID="762" OrderQty="1" />
<OrderDetail SalesOrderID="43860" ProductID="738" OrderQty="1" />
<OrderDetail SalesOrderID="43860" ProductID="768" OrderQty="1" />
<OrderDetail SalesOrderID="43860" ProductID="753" OrderQty="2" />
<OrderDetail SalesOrderID="43860" ProductID="729" OrderQty="1" />
<OrderDetail SalesOrderID="43860" ProductID="763" OrderQty="1" />
<OrderDetail SalesOrderID="43860" ProductID="756" OrderQty="1" />
</Order>
</ROOT>
E. 指定<不带父属性的 sql:relationship>
此示例演示如何指定不带父属性的 <sql:relationship>。 例如,假设您具有以下员工表:
Emp1(SalesPersonID, FirstName, LastName, ReportsTo)
Emp2(SalesPersonID, FirstName, LastName, ReportsTo)
以下 XML 视图具有映射到 Sales.Emp1 和 Sales.Emp2 表的 Emp1> 和 <Emp2> 元素:<
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:sql="urn:schemas-microsoft-com:mapping-schema">
<xsd:annotation>
<xsd:appinfo>
<sql:relationship name="EmpOrders"
parent-key="SalesPersonID"
child="Sales.SalesOrderHeader"
child-key="SalesPersonID" />
</xsd:appinfo>
</xsd:annotation>
<xsd:element name="Emp1" sql:relation="Sales.Emp1" type="EmpType" />
<xsd:element name="Emp2" sql:relation="Sales.Emp2" type="EmpType" />
<xsd:complexType name="EmpType" >
<xsd:sequence>
<xsd:element name="Order"
sql:relation="Sales.SalesOrderHeader"
sql:relationship="EmpOrders" >
<xsd:complexType>
<xsd:attribute name="SalesOrderID" type="xsd:integer" />
<xsd:attribute name="CustomerID" type="xsd:string" />
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="SalesPersonID" type="xsd:integer" />
<xsd:attribute name="LastName" type="xsd:string" />
</xsd:complexType>
</xsd:schema>
在架构中,Emp1> 元素和< Emp2> 元素均为 EmpType 类型。< 类型 EmpType 描述 <Order> 子元素和相应的< sql:relationship。> 在这种情况下,不能使用父属性在 sql:relationship> 中<标识单个父级。 在这种情况下,请不要在 sql:relationship> 中<指定父属性;父属性信息是从架构中的层次结构获取的。
针对架构测试示例 XPath 查询
在 AdventureWorks 数据库中创建这些表:
USE AdventureWorks2022; CREATE TABLE Sales.Emp1 ( SalesPersonID int primary key, FirstName varchar(20), LastName varchar(20), ReportsTo int) Go CREATE TABLE Sales.Emp2 ( SalesPersonID int primary key, FirstName varchar(20), LastName varchar(20), ReportsTo int) Go
在这些表中添加此示例数据:
INSERT INTO Sales.Emp1 values (279, 'Nancy', 'Devolio',NULL) INSERT INTO Sales.Emp1 values (282, 'Andrew', 'Fuller',1) INSERT INTO Sales.Emp1 values (276, 'Janet', 'Leverling',1) INSERT INTO Sales.Emp2 values (277, 'Margaret', 'Peacock',3) INSERT INTO Sales.Emp2 values (283, 'Steven', 'Devolio',4) INSERT INTO Sales.Emp2 values (275, 'Nancy', 'Buchanan',5) INSERT INTO Sales.Emp2 values (281, 'Michael', 'Suyama',6)
复制上面的架构代码,并将它粘贴到文本文件中。 将文件另存为 relationship-noparent.xml。
复制以下模板,并将它粘贴到文本文件中。 在您保存 relationship-noparent.xml 的相同目录中将该文件另存为 relationship-noparentT.xml。 模板中的查询选择所有 <Emp1> 元素(因此,父元素为 Emp1)。
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql"> <sql:xpath-query mapping-schema="relationship-noparent.xml"> /Emp1 </sql:xpath-query> </ROOT>
为映射架构 (relationship-noparent.xml) 指定的目录路径是相对于模板保存目录的相对路径。 也可以指定绝对路径,例如:
mapping-schema="C:\MyDir\relationship-noparent.xml"
创建并使用 SQLXML 4.0 测试脚本 (Sqlxml4test.vbs) 执行该模板。
有关详细信息,请参阅 使用 ADO 执行 SQLXML 查询。
以下为部分结果集:
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<Emp1 SalesPersonID="276" LastName="Leverling">
<Order SalesOrderID="43663" CustomerID="510" />
<Order SalesOrderID="43666" CustomerID="511" />
<Order SalesOrderID="43859" CustomerID="259" />
...
</Emp1>