使用 sql:relationship 指定关系(XDR 架构)

重要说明重要提示

本主题是针对早期应用程序提供的参考,以后不会就该功能继续进行开发。请避免在新的开发工作中使用此功能,而应使用带批注的 XSD 架构来创建 XML 视图。有关详细信息,请参阅带批注的 XSD 架构简介 (SQLXML 4.0)。可以将现有带批注的 XDR 架构转换为 XSD 架构。有关详细信息,请参阅将带批注的 XDR 架构转换为等效的 XSD 架构 (SQLXML 4.0)

可以对 XML 文档中的元素建立相关性。元素可以按层次结构方式嵌套,并且可以在元素之间指定 ID、IDREF 或 IDREFS 关系。

例如,在 XDR 架构中,<Customer> 元素包含 <Order> 子元素。<Customer> 元素映射到存储客户数据的表(如 AdventureWorks 数据库中的 Sales.Customer)。<Order> 元素映射到同一数据库中存储订单数据的表(如 Sales.SalesOrderHeader)。由于客户下订单,因此,这些基础表 Sales.Customer 和 Sales.SalesOrderHeader 是相关的。Sales.SalesOrderHeader 表中的 CustomerID 是外键,它引用 Sales.Customer 表中的 CustomerID 主键。您可以使用 <sql:relationship> 批注在映射架构元素之间建立这些关系。

在带批注的 XDR 架构中,<sql:relationship> 批注用于根据元素所映射到的基础表之间的主键和外键关系,在层次结构中嵌套架构元素。指定 <sql:relationship> 批注时,必须标识:

  • 主表 (Sales.Customer) 和外表 (Sales.SalesOrderHeader) 以及

  • 必需的联接条件(Sales.SalesOrderHeader 中的 CustomerID 是外键,它引用 Sales.Customer 表中的 CustomerID 主键)。

在生成合适的层次结构时使用此信息(对于每个 <customer> 元素,相关的 <order> 元素显示为子元素)。

为了提供表名和必需的联接信息,使用 <sql:relationship> 批注指定以下属性。这些属性仅对于 sql:relationship 元素有效:

  • key-relation
    指定主关系(表)。

  • key
    指定 key-relation 的主键。如果主键由多列组成,则指定值时应在各值之间使用空格。在为多列键指定的值与为对应的外键指定的值之间存在位置映射。

  • foreign-relation
    指定外关系(表)。

  • foreign-key
    在引用 key-relation 中 key 的 foreign-relation 中指定外键。如果外键由多个属性(列)组成,则指定外键值时应在各值之间使用空格。在为多列键指定的值与为对应的外键指定的值之间存在位置映射。

注意注意

必须确保 key 和 foreign-key 的 Microsoft SQL Server 数据类型可以根据需要进行隐式转换。

在带批注的架构中,只能将 sql:relationship 标记添加到 <element> 或 <attribute> 元素。为属性指定 sql:relationship 时,应存在为该属性指定的 sql:relation 和 sql:field,以确保检索到单个值(相同名称的多个属性在 XML 中无效)。为元素指定 sql:relationship 时,关系可能导致单个值或一组值。

sql:relationship 标记用于指定两个实体之间的单一逻辑关系。使用定义关系和字段的属性来定义该逻辑关系。在带批注的架构中,可以在元素或属性内指定 sql:relationship 的多个实例,这指示在元素或属性与它包含的元素之间存在复杂的关系。sql:relationship 的所有实例都用来定义这种复杂的关系。

在元素或属性内指定 sql:relationship 标记的多个实例时,它们的显示顺序很重要。

必须在包含子元素、与子元素之间定义了 sql:relationship 且未提供表的主键(在父元素中指定)的元素中指定 sql:key-fields 批注。有关详细信息,请参阅使用 sql:key-fields 标识键列 (SQLXML 4.0)。若要在结果中生成正确的嵌套,建议在所有架构中指定 sql:key-fields。

注意注意

在映射架构中,关系值(如表名和列名)区分大小写。

示例

若要创建使用以下示例的工作示例,必须满足某些要求。有关详细信息,请参阅运行 SQLXML 示例的要求

A. 为 <element> 指定 sql:relationship

这个带批注的 XDR 架构包含 <Customer><Order> 元素。<Order> 元素是 <Customer> 元素的子元素。

在此架构中,针对 <Order> 子元素指定 sql:relationship 批注。该批注将 Sales.SalesOrderHeader 表中的 CustomerID 标识为外键,它引用 Sales.Customer 表中的 CustomerID 主键。因此,属于某个客户的订单将显示为该 <Customer> 元素的子元素。

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<ElementType name="Order" sql:relation="Sales.SalesOrderHeader" >
    <AttributeType name="CustomerID" />
    <AttributeType name="SalesOrderID" />
    <AttributeType name="OrderDate" />

    <attribute type="CustomerID" />
    <attribute type="SalesOrderID" />
    <attribute type="OrderDate" />
</ElementType>
<ElementType name="Customer" sql:relation="Sales.Customer" >
    <AttributeType name="CustomerID" />
    <attribute type="CustomerID" />
    <element type="Order" >
             <sql:relationship 
                     key-relation="Sales.Customer"
                    key="CustomerID"
                    foreign-key="CustomerID"
                    foreign-relation="Sales.SalesOrderHeader" />
    </element>
</ElementType>
</Schema>
注意注意

在映射架构中,关系值(如表名和列名)区分大小写。在上面的示例中,Customers 是 sql:relation 属性的值。相应的 key-relation 属性值必须也是 Customers。

针对该架构测试示例 XPath 查询

  1. 复制上面的架构代码,并将它粘贴到文本文件中。将该文件另存为 sql-relationship-xdr.xml。

  2. 复制以下模板,并将它粘贴到文本文件中。在保存 sql-relationship-xdr.xml 的相同目录中将文件另存为 sql-relationship-xdrT.xml。模板中的查询选择 CustomerID 为 1 的客户。

    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
      <sql:xpath-query mapping-schema="sql-relationship-xdr.xml">
        Customer[@CustomerID="1"]
      </sql:xpath-query>
    </ROOT>
    

    为映射架构 (sql-relationship-xdr.xml) 指定的目录路径是相对于模板保存目录的相对路径。也可以指定绝对路径,例如:

    mapping-schema="C:\SqlXmlTest\sql-relationship-xdr.xml"
    
  3. 创建并使用 SQLXML 4.0 测试脚本 (Sqlxml4test.vbs) 执行该模板。

    有关详细信息,请参阅使用 ADO 执行 SQLXML 4.0 查询

下面是部分结果集:

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Customer CustomerID="1">
    <Order CustomerID="1" SalesOrderID="43860" OrderDate="2001-08-01T00:00:00" /> 
    <Order CustomerID="1" SalesOrderID="44501" OrderDate="2001-11-01T00:00:00" /> 
    <Order CustomerID="1" SalesOrderID="45283" OrderDate="2002-02-01T00:00:00" /> 
    <Order CustomerID="1" SalesOrderID="46042" OrderDate="2002-05-01T00:00:00" /> 
  </Customer>
</ROOT>

B. 为 <attribute> 指定 sql:relationship 并使用 ID 和 IDREFS 创建文档引用。

在此示例中,使用 ID 和 IDREFS 指定本地文档引用。示例 XDR 架构由映射到 Sales.Customer 表的 <Customer> 元素组成。此元素由映射到 Sales.SalesOrderHeader 表的 <Order> 子元素组成。

在此示例中,指定了两次 sql:relationship:

  • <Order> 子元素指定 sql:relationship。因此,属于某个客户的订单将显示为该 <Customer> 元素的子元素。

  • 还为 <Customer> 元素的 OrderIDList 属性指定 sql:relationship。将此属性定义为 IDREFS 类型,它引用 <Order> 元素的 SalesOrderID 属性(ID 类型属性)。因此,需要使用 sql:relationship。在此示例中,sql:relationship 批注允许显示属于某个客户的订单列表,该客户具有该 <Customer> 元素。

    可以使用指定为 IDREFS 的属性引用 ID 类型属性,从而启用文档内链接。

由于数字不是有效的 ID 值(必须是名称标记),因此使用了 sql:id-prefix 将订单 ID 生成为字符串值。有关详细信息,请参阅使用 sql:id-prefix 创建有效的 ID、IDREF 和 IDREFS 类型属性(XDR 架构)

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <ElementType name="Order" sql:relation="Sales.SalesOrderHeader" >
    <AttributeType name="SalesOrderID" dt:type="id" sql:id-prefix="Ord-" />
    <AttributeType name="OrderDate" />
 
    <attribute type="SalesOrderID" />
    <attribute type="OrderDate" />
  </ElementType>

  <ElementType name="Customer" sql:relation="Sales.Customer">
    <AttributeType name="CustomerID"  />

    <attribute type="CustomerID" />
    <AttributeType name="OrderIDList" dt:type="idrefs" 
                                      sql:id-prefix="Ord-"/>
    <attribute type="OrderIDList" sql:relation="Sales.SalesOrderHeader" 
                                  sql:field="SalesOrderID">
                 <sql:relationship
                      key-relation="Sales.Customer"
                      key="CustomerID"
                      foreign-relation="Sales.SalesOrderHeader"
                      foreign-key="CustomerID" />
    </attribute>
    <element type="Order">
                 <sql:relationship key-relation="Sales.Customer"
                      key="CustomerID"
                      foreign-relation="Sales.SalesOrderHeader"
                      foreign-key="CustomerID" />
    </element>
  </ElementType>
</Schema>

针对该架构测试示例 XPath 查询

  1. 复制上面的架构代码,并将它粘贴到文本文件中。将该文件另存为 idIdref-xdr.xml。

  2. 复制以下模板,并将它粘贴到文本文件中。在保存 idIdref-xdr.xml 的相同目录中将文件另存为 idIdref-xdrT.xml。模板中的查询选择 CustomerID 为 1 的客户。

    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
      <sql:xpath-query mapping-schema="idIdref-xdr.xml">
        Customer[@CustomerID="1"]
      </sql:xpath-query>
    </ROOT>
    

    为映射架构 (idIdref-xdr.xml) 指定的目录路径是相对于模板保存目录的相对路径。也可以指定绝对路径,例如:

    mapping-schema="C:\SqlXmlTest\idIdref-xdr.xml"
    
  3. 创建并使用 SQLXML 4.0 测试脚本 (Sqlxml4test.vbs) 执行该模板。

    有关详细信息,请参阅使用 ADO 执行 SQLXML 4.0 查询

下面是结果集:

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Customer CustomerID="1" 
            OrderIDList="Ord-43860 Ord-44501 Ord-45283 Ord-46042">
    <Order SalesOrderID="Ord-43860" OrderDate="2001-08-01T00:00:00" /> 
    <Order SalesOrderID="Ord-44501" OrderDate="2001-11-01T00:00:00" /> 
    <Order SalesOrderID="Ord-45283" OrderDate="2002-02-01T00:00:00" /> 
    <Order SalesOrderID="Ord-46042" OrderDate="2002-05-01T00:00:00" /> 
  </Customer>
</ROOT>

C. 为多个元素指定 sql:relationship

在此示例中,带批注的 XDR 架构由 <Customer><Order><OD> 元素组成。

<Order> 元素是 <Customer> 元素的子元素。为 <Order> 子元素指定 sql:relationship,以便属于某个客户的订单显示为 <Customer> 的子元素。

<Order> 元素包含 <OD> 子元素。为 <OD> 子元素指定 sql:relationship,以便属于某个订单的订单详细信息显示为该 <Order> 元素的子元素。

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql">

<ElementType name="OD" sql:relation="Sales.SalesOrderDetail" >
    <AttributeType name="SalesOrderID" />
    <AttributeType name="ProductID" />

    <attribute type="SalesOrderID" />
    <attribute type="ProductID" />
</ElementType>

<ElementType name="Order" sql:relation="Sales.SalesOrderHeader" >
    <AttributeType name="CustomerID" />
    <AttributeType name="SalesOrderID" />
    <AttributeType name="OrderDate" />

    <attribute type="CustomerID" />
    <attribute type="SalesOrderID" />
    <attribute type="OrderDate" />
    <element type="OD" >
             <sql:relationship 
                   key-relation="Sales.SalesOrderHeader"
                   key="SalesOrderID"
                   foreign-key="SalesOrderID"
                   foreign-relation="Sales.SalesOrderDetail" />
    </element>
</ElementType>

<ElementType name="Customer" sql:relation="Sales.Customer" >
    <AttributeType name="CustomerID" />

    <attribute type="CustomerID" />
    <element type="Order" >
      <sql:relationship 
                key-relation="Sales.Customer"
                key="CustomerID"
                foreign-key="CustomerID"
                foreign-relation="Sales.SalesOrderHeader" />
    </element>
</ElementType>
</Schema>

针对该架构测试示例 XPath 查询

  1. 复制上面的架构代码,并将它粘贴到文本文件中。将该文件另存为 sql-relationship-multi-xdr.xml。

  2. 复制以下模板,并将它粘贴到文本文件中。在保存 sql-relationship-multi-xdr.xml 的相同目录中将文件另存为 sql-relationship-multi-xdrT.xml。模板中的查询将返回 CustomerID 为 1 且 SalesOrderID 为 43860 的客户的订单信息。

    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
      <sql:xpath-query mapping-schema="sql-relationship-multi-xdr.xml">
        /Customer[@CustomerID="1"]/Order[@SalesOrderID=43860]
      </sql:xpath-query>
    </ROOT>
    

    为映射架构 (sql-relationship-multi-xdr.xml) 指定的目录路径是相对于模板保存目录的相对路径。也可以指定绝对路径,例如:

    mapping-schema="C:\SqlXmlTest\sql-relationship-multi-xdr.xml"
    
  3. 创建并使用 SQLXML 4.0 测试脚本 (Sqlxml4test.vbs) 执行该模板。

    有关详细信息,请参阅使用 ADO 执行 SQLXML 4.0 查询

下面是结果集:

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Order CustomerID="1" SalesOrderID="43860" OrderDate="2001-08-01T00:00:00">
    <OD SalesOrderID="43860" ProductID="761" /> 
    <OD SalesOrderID="43860" ProductID="770" /> 
    <OD SalesOrderID="43860" ProductID="758" /> 
    <OD SalesOrderID="43860" ProductID="765" /> 
    <OD SalesOrderID="43860" ProductID="732" /> 
    <OD SalesOrderID="43860" ProductID="762" /> 
    <OD SalesOrderID="43860" ProductID="738" /> 
    <OD SalesOrderID="43860" ProductID="768" /> 
    <OD SalesOrderID="43860" ProductID="753" /> 
    <OD SalesOrderID="43860" ProductID="729" /> 
    <OD SalesOrderID="43860" ProductID="763" /> 
    <OD SalesOrderID="43860" ProductID="756" /> 
  </Order>
</ROOT>

D. 指定间接关系

在此示例中,带批注的 XDR 架构由 <Customer><OD> 元素组成。这些元素之间的关系是间接的(Sales.Customer 表通过 Sales.SalesOrderHeader 表与 Sales.SalesOrderDetail 表关联)。为了将客户与订单详细信息关联,首先指定 Sales.Customer 表和 Sales.SalesOrderHeader 表之间的关系。然后指定 Sales.SalesOrderHeader 表和 Sales.SalesOrderDetail 表之间的关系。

以下是架构:

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<ElementType name="OD" sql:relation="Sales.SalesOrderDetail" >
    <AttributeType name="SalesOrderID" />
    <AttributeType name="ProductID" />
    <AttributeType name="UnitPrice" />

    <attribute type="SalesOrderID" />
    <attribute type="ProductID" />
    <attribute type="UnitPrice" />
</ElementType>
<ElementType name="Customer" sql:relation="Sales.Customer" >
    <AttributeType name="CustomerID" />
    <attribute type="CustomerID" />
    <element type="OD" >
             <sql:relationship 
                    key-relation="Sales.Customer"
                    key="CustomerID"
                    foreign-relation="Sales.SalesOrderHeader"
                    foreign-key="CustomerID"/>
             <sql:relationship 
                    key-relation="Sales.SalesOrderHeader"
                    key="SalesOrderID"
                    foreign-relation="Sales.SalesOrderDetail" 
                    foreign-key="SalesOrderID" />
    </element>
</ElementType>
</Schema>

针对该架构测试示例 XPath 查询

  1. 复制上面的架构代码,并将它粘贴到文本文件中。将该文件另存为 indirect-relationship-xdr.xml。

  2. 复制以下模板,并将它粘贴到文本文件中。在保存 indirect-relationship-xdr.xml 的相同目录中将文件另存为 indirect-relationship-xdrT.xml。模板中的查询将返回 CustomerID 为 1 的客户的订单信息。

    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql" >
    <sql:xpath-query mapping-schema="indirect-relationship-xdr.xml" >
    /Customer[@CustomerID="1"]
    </sql:xpath-query>
    </ROOT>
    

    为映射架构 (indirect-relationship-xdr.xml) 指定的目录路径是相对于模板保存目录的相对路径。也可以指定绝对路径,例如:

    mapping-schema="C:\SqlXmlTest\indirect-relationship-xdr.xml"
    
  3. 创建并使用 SQLXML 4.0 测试脚本 (Sqlxml4test.vbs) 执行该模板。

    有关详细信息,请参阅使用 ADO 执行 SQLXML 4.0 查询

下面是部分结果:

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Customer CustomerID="1">
    <OD SalesOrderID="43860" ProductID="761" UnitPrice="503.3507" /> 
    <OD SalesOrderID="43860" ProductID="770" UnitPrice="503.3507" /> 
    <OD SalesOrderID="43860" ProductID="758" UnitPrice="1049.7528" /> 
    <OD SalesOrderID="43860" ProductID="765" UnitPrice="503.3507" /> 
    ...
  </Customer>
  </ROOT>

E. 指定多键联接关系

在使用 sql:relationship 指定联接时,可以指定涉及两个或更多列的联接。在这种情况下,使用空格分隔 key 和 foreign-key 的列名。

此示例假定这两个表位于临时数据库(如 tempdb)中:

  • dbo.Cust (fname, lname)

  • dbo.Ord (OrderID, fname, lname)

fname 和 lname 列构成 Cust 表的主键。OrderID 是 Ord 表的主键。Ord 表中的 fname 和 lname 是外键,它们引用 Cust 表中的 fname 和 lname 主键。

架构则由 <Cust><Ord> 元素组成。sql:relationship 用于联接它们。

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<ElementType name="Ord" sql:relation="Ord" >
    <AttributeType name="OrderID" />

    <attribute type="OrderID" />
</ElementType>

<ElementType name="Cust" sql:relation="Cust" >
    <AttributeType name="fname" />
    <AttributeType name="lname" />
    <attribute type="fname" />
    <attribute type="lname" />
    <element type="Ord" >
             <sql:relationship 
                    key-relation="Cust"
                    key="fname lname"
                    foreign-relation="Ord"
                    foreign-key="fname lname"/>
    </element>
</ElementType>
</Schema>

针对该架构测试示例 XPath 查询

  1. 创建两个表:Cust 和 Ord。

    USE tempdb
    CREATE TABLE dbo.Cust(
           fname  varchar(20), 
           lname   varchar(20)
           )
    CREATE TABLE dbo.Ord (
           OrderID int primary key, 
           fname  varchar(20), 
           lname   varchar(20)
           )
    GO
    
  2. 添加以下示例数据:

    INSERT INTO Cust values ('Nancy', 'Davolio')
    INSERT INTO Cust values('Andrew', 'Fuller')
    INSERT INTO Ord values (1,'Nancy', 'Davolio')
    INSERT INTO Ord values (2,'Nancy', 'Davolio')
    INSERT INTO Ord values (3,'Andrew', 'Fuller')
    
  3. 复制上面的架构代码,并将它粘贴到文本文件中。将该文件另存为 multikey-join-xdr.xml。

  4. 复制以下模板,并将它粘贴到文本文件中。在保存 multikey-join-xdr.xml 的相同目录中将文件另存为 multikey-join-xdrT.xml。模板中的查询将返回客户信息。

    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql" >
      <sql:xpath-query mapping-schema="multikey-join-xdr.xml" >
        /Cust
      </sql:xpath-query>
    </ROOT>
    

    为映射架构 (multikey-join-xdr.xml) 指定的目录路径是相对于模板保存目录的相对路径。也可以指定绝对路径,例如:

    mapping-schema="C:\SqlXmlTest\multikey-join-xdr.xml"
    
  5. 创建并使用 SQLXML 4.0 测试脚本 (Sqlxml4test.vbs) 执行该模板。

    有关详细信息,请参阅使用 ADO 执行 SQLXML 4.0 查询

下面是部分结果:

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql"> 
  <Cust fname="Andrew" lname="Fuller"> 
    <Ord OrderID="3" /> 
  </Cust> 
  <Cust fname="Nancy" lname="Davolio"> 
    <Ord OrderID="1" /> 
    <Ord OrderID="2" /> 
  </Cust> 
</ROOT>