--- title: "Set relationships with sql:relationship (SQLXML)" description: "Learn how to use the sql:relationship annotation in SQLXML 4.0 to specify relationships between XML elements." author: MikeRayMSFT ms.author: mikeray ms.date: "03/16/2017" ms.prod: sql ms.prod_service: "database-engine, sql-database" ms.technology: xml ms.topic: "reference" ms.custom: "seo-lt-2019" helpviewer_keywords: - "IDREFS relationships [SQLXML]" - "parent attribute [SQLXML]" - "element relationships [SQLXML]" - "multiple element relationships" - "attribute relationships [SQLXML]" ms.assetid: 98820afa-74e1-4e62-b336-6111a3dede4c monikerRange: "=azuresqldb-current||>=sql-server-2016||>=sql-server-linux-2017||=azuresqldb-mi-current" --- # Specifying Relationships Using sql:relationship (SQLXML 4.0) [!INCLUDE [SQL Server Azure SQL Database](../../includes/applies-to-version/sql-asdb.md)] The elements in an XML document can be related. The elements can be nested hierarchically, and ID, IDREF, or IDREFS relationships can be specified between the elements. For example, in an XSD schema, a **\** element contains **\** child elements. When the schema is mapped to the AdventureWorks database, the **\** element maps to the Sales.Customer table and the **\** element maps to the Sales.SalesOrderHeader table. These underlying tables, Sales.Customer and Sales.SalesOrderHeader, are related because customers place orders. The CustomerID in the Sales.SalesOrderHeader table is a foreign key referring to the CustomerID primary key in the Sales.Customer table. You can establish these relationships among mapping schema elements by using the **sql:relationship** annotation. In the annotated XSD schema, the **sql:relationship** annotation is used to nest the schema elements hierarchically, on the basis of primary key and foreign key relationships among the underlying tables to which the elements map. In specifying the **sql:relationship** annotation, you must identify the following: - The parent table (Sales.Customer) and the child table (Sales.SalesOrderHeader). - The column or columns that compose the relationship between the parent and child tables. For example, the CustomerID column, which appears in both the parent and child tables. This information is used to generate the proper hierarchy. To provide the table names and the necessary join information, the following attributes are specified on the **sql:relationship** annotation. These attributes are valid only with the **\** element: **Name** Specifies the unique name of the relationship. **Parent** Specifies the parent relation (table). This is an optional attribute; if the attribute is not specified, the parent table name is obtained from information in the child hierarchy in the document. If the schema specifies two parent-child hierarchies that use the same **\** but different parent elements, you do not specify the parent attribute in **\**. This information is obtained from the hierarchy in the schema. **parent-key** Specifies the parent key of the parent. If the parent key is composed of multiple columns, values are specified with a space between them. There is a positional mapping between the values that are specified for the multicolumn key and for the corresponding child key. **Child** Specifies the child relation (table). **child-key** Specifies the child key in the child referring to parent-key in parent. If the child key is composed of multiple attributes (columns), the child-key values are specified with a space between them. There is a positional mapping between the values that are specified for the multicolumn key and for the corresponding parent key. **Inverse** This attribute specified on **\** is used by updategrams. For more information, see [Specifying the sql:inverse Attribute on sql:relationship](../../relational-databases/sqlxml-annotated-xsd-schemas-using/specifying-the-sql-inverse-attribute-on-sql-relationship-sqlxml-4-0.md). The **sql:key-fields** annotation must be specified in an element that contains a child element, that has a **\** defined between the element and the child, and that does not provide the primary key of the table specified in the parent element. Even if the schema does not specify **\**, you must specify **sql:key-fields** to produce the proper hierarchy. For more information, see [Identifying Key Columns by Using sql:key-fields](../../relational-databases/sqlxml-annotated-xsd-schemas-using/identifying-key-columns-using-sql-key-fields-sqlxml-4-0.md). To produce proper nesting in the result, it is recommended that **sql:key-fields** are specified in all schemas. ## Examples To create working samples using the following examples, you must meet certain requirements. For more information, see [Requirements for Running SQLXML Examples](../../relational-databases/sqlxml/requirements-for-running-sqlxml-examples.md). ### A. Specifying the sql:relationship annotation on an element The following annotated XSD schema includes **\** and **\** elements. The **\** element is a child element of the **\** element. In the schema, the **sql:relationship** annotation is specified on the **\** child element. The relationship itself is defined in the **\** element. The **\** element identifies CustomerID in the Sales.SalesOrderHeader table as a foreign key that refers to the CustomerID primary key in the Sales.Customer table. Therefore, orders that belong to a customer appear as a child element of that **\** element. ``` ``` The previous schema uses a named relationship. You can also specify an unnamed relationship. The results are same. This is the revised schema in which an unnamed relationship is specified: ``` ``` ##### To test a sample XPath query against the schema 1. Copy the schema code above and paste it into a text file. Save the file as sql-relationship.xml. 2. Copy the following template below and paste it into a text file. Save the file as sql-relationshipT.xml in the same directory where you saved sql-relationship.xml. ``` /Customer[@CustomerID=1] ``` The directory path specified for the mapping schema (sql-relationship.xml) is relative to the directory where the template is saved. An absolute path also can be specified, for example: ``` mapping-schema="C:\MyDir\sql-relationship.xml" ``` 3. Create and use the SQLXML 4.0 Test Script (Sqlxml4test.vbs) to execute the template. For more information, see [Using ADO to Execute SQLXML Queries](../../relational-databases/sqlxml/using-ado-to-execute-sqlxml-4-0-queries.md). Here is the result set: ``` ``` ### B. Specifying a relationship chain For this example, assume that you want the following XML document using data obtained from the AdventureWorks database: ``` ... ... ``` For each order in the Sales.SalesOrderHeader table, the XML document has one **\** element. And each **\** element has a list of **\** child elements, one for each product requested in the order. To specify an XSD schema that will produce this hierarchy, you must specify two relationships: OrderOD and ODProduct. The OrderOD relationship specifies the parent-child relationship between the Sales.SalesOrderHeader and Sales.SalesOrderDetail tables. The ODProduct relationship specifies the relationship between the Sales.SalesOrderDetail and Production.Product tables. In the following schema, the **msdata:relationship** annotation on the **\** element specifies two values: OrderOD and ODProduct. The order in which these values are specified is important. ``` ``` Instead of specifying a named relationship, you can specify an anonymous relationship. In this case, the entire contents of **\**...**\**, which describes the two relationships, appear as a child element of **\**. ``` ``` ##### To test a sample XPath query against the schema 1. Copy the schema code above and paste it into a text file. Save the file as relationshipChain.xml. 2. Copy the following template below and paste it into a text file. Save the file as relationshipChainT.xml in the same directory where you saved relationshipChain.xml. ``` /Order ``` The directory path specified for the mapping schema (relationshipChain.xml) is relative to the directory where the template is saved. An absolute path also can be specified, for example: ``` mapping-schema="C:\MyDir\relationshipChain.xml" ``` 3. Create and use the SQLXML 4.0 Test Script (Sqlxml4test.vbs) to execute the template. For more information, see [Using ADO to Execute SQLXML Queries](../../relational-databases/sqlxml/using-ado-to-execute-sqlxml-4-0-queries.md). Here is the result set: ``` ... ... ``` ### C. Specifying the relationship annotation on an attribute The schema in this example includes a \ element with a \ child element and an OrderIDList attribute of IDREFS type. The \ element maps to the Sales.Customer table in the AdventureWorks database. By default, the scope of this mapping applies to all the child elements or attributes unless **sql:relation** is specified on the child element or attribute, in which case, the appropriate primary-key/foreign-key relationship must be defined using the \ element. And the child element or attribute, which specifies the different table using the **relation** annotation, must also specify the **relationship** annotation. ``` ``` ##### To test a sample XPath query against the schema 1. Copy the schema code above and paste it into a text file. Save the file as relationship-on-attribute.xml. 2. Copy the following template and paste it into a file. Save the file as relationship-on-attributeT.xml in the same directory where you saved relationship-on-attribute.xml. The query in the template selects a customer with the CustomerID of 1. ``` /Customer[CustomerID=1] ``` The directory path specified for the mapping schema (relationship-on-attribute.xml) is relative to the directory where the template is saved. An absolute path also can be specified, for example: ``` mapping-schema="C:\MyDir\relationship-on-attribute.xml" ``` 3. Create and use the SQLXML 4.0 Test Script (Sqlxml4test.vbs) to execute the template. For more information, see [Using ADO to Execute SQLXML Queries](../../relational-databases/sqlxml/using-ado-to-execute-sqlxml-4-0-queries.md). Here is the result set: ``` 1 ``` ### D. Specifying sql:relationship on multiple elements In this example, the annotated XSD schema contains the **\**, **\**, and **\** elements. The **\** element is a child element of the **\** element. **\** is specified on the **\** child element; therefore, orders that belong to a customer appear as child elements of **\**. The **\** element includes the **\** child element. **\** is specified on **\** child element, so the order details that pertain to an order appear as child elements of that **\** element. ``` ``` ##### To test a sample XPath query against the schema 1. Copy the schema code above and paste it into a text file. Save the file as relationship-multiple-elements.xml. 2. Copy the following template and paste it into a text file. Save the file as relationship-multiple-elementsT.xml in the same directory where you saved relationship-multiple-elements.xml. The query in the template returns order information for a customer with the CustomerID of 1 and SalesOrderID of 43860. ``` /Customer[@CustomerID=1]/Order[@SalesOrderID=43860] ``` The directory path specified for the mapping schema (relationship-multiple-elements.xml) is relative to the directory where the template is saved. An absolute path also can be specified, for example: ``` mapping-schema="C:\MyDir\relationship-multiple-elements.xml" ``` 3. Create and use the SQLXML 4.0 Test Script (Sqlxml4test.vbs) to execute the template. For more information, see [Using ADO to Execute SQLXML Queries](../../relational-databases/sqlxml/using-ado-to-execute-sqlxml-4-0-queries.md). Here is the result set: ``` ``` ### E. Specifying the \ without the parent attribute This example illustrates specifying the **\** without the **parent** attribute. For example, assume you have the following employee tables: ``` Emp1(SalesPersonID, FirstName, LastName, ReportsTo) Emp2(SalesPersonID, FirstName, LastName, ReportsTo) ``` The following XML view has the **\** and **\** elements mapping to the Sales.Emp1 and Sales.Emp2 tables: ``` ``` In the schema, both the **\** element and **\** element are of type **EmpType**. The type **EmpType** describes an **\** child element and the corresponding **\**. In this case, there is no single parent that can be identified in **\** by using the **parent** attribute. In this situation, you don't specify the **parent** attribute in **\**; the **parent** attribute information is obtained from the hierarchy in the schema. ##### To test a sample XPath query against the schema 1. Create these tables in the AdventureWorks database: ``` USE AdventureWorks 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 ``` 2. Add this sample data in the tables: ``` 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) ``` 3. Copy the schema code above and paste it into a text file. Save the file as relationship-noparent.xml. 4. Copy the following template and paste it into a text file. Save the file as relationship-noparentT.xml in the same directory where you saved relationship-noparent.xml. The query in the template selects all the \ elements (therefore, the parent is Emp1). ``` /Emp1 ``` The directory path specified for the mapping schema (relationship-noparent.xml) is relative to the directory where the template is saved. An absolute path also can be specified, for example: ``` mapping-schema="C:\MyDir\relationship-noparent.xml" ``` 5. Create and use the SQLXML 4.0 Test Script (Sqlxml4test.vbs) to execute the template. For more information, see [Using ADO to Execute SQLXML Queries](../../relational-databases/sqlxml/using-ado-to-execute-sqlxml-4-0-queries.md). Here is a partial result set: ``` ... ```