sql:relationship et la règle de tri par clé (SQLXML 4.0)
Dans la mesure où la fonctionnalité de chargement en masse XML génère des enregistrements lorsque les nœuds de ces derniers entrent dans l'étendue, et qu'elle envoie ces enregistrements à Microsoft SQL Server lorsque les nœuds correspondants sortent de l'étendue, les données de l'enregistrement doivent être présentes dans l'étendue du nœud.
Examinez le schéma XSD suivant, dans lequel la relation un-à-plusieurs entre les éléments <Customer> et <Order> (un client peut passer de nombreuses commandes) est spécifiée à l'aide de l'élément <sql:relationship> :
<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="CustCustOrder"
parent="Cust"
parent-key="CustomerID"
child="CustOrder"
child-key="CustomerID" />
</xsd:appinfo>
</xsd:annotation>
<xsd:element name="Customers" sql:relation="Cust" >
<xsd:complexType>
<xsd:sequence>
<xsd:element name="CustomerID" type="xsd:integer" />
<xsd:element name="CompanyName" type="xsd:string" />
<xsd:element name="City" type="xsd:string" />
<xsd:element name="Order"
sql:relation="CustOrder"
sql:relationship="CustCustOrder" >
<xsd:complexType>
<xsd:attribute name="OrderID" type="xsd:integer" />
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
Lorsque le nœud de l'élément <Customer> entre dans l'étendue, la fonctionnalité de chargement en masse XML génère un enregistrement de client. Cet enregistrement est conservé jusqu'à ce que la fonctionnalité de chargement en masse XML lise </Customer>. Lors du traitement du nœud de l'élément <Order>, la fonctionnalité de chargement en masse XML utilise <sql:relationship> pour obtenir la valeur de la colonne de clé étrangère CustomerID de la table CustOrder de l'élément parent <Customer>, car l'élément <Order> ne spécifie pas l'attribut CustomerID. Cela signifie que lors de la définition de l'élément <Customer>, vous devez spécifier l'attribut CustomerID dans le schéma avant de spécifier <sql:relationship>. Sinon, lorsqu'un élément <Order> entre dans l'étendue, la fonctionnalité de chargement en masse XML génère un enregistrement pour la table CustOrder, et lorsqu'elle atteint la balise de fin </Order>, elle envoie l'enregistrement à SQL Server sans la valeur de colonne clé étrangère CustomerID.
Enregistrez le schéma fourni dans cet exemple sous le nom SampleSchema.xml.
Pour tester un exemple fonctionnel
Créez les tables suivantes :
CREATE TABLE Cust ( CustomerID int PRIMARY KEY, CompanyName varchar(20) NOT NULL, City varchar(20) DEFAULT 'Seattle') GO CREATE TABLE CustOrder ( OrderID varchar(10) PRIMARY KEY, CustomerID int FOREIGN KEY REFERENCES Cust(CustomerID)) GO
Enregistrez l'exemple de données ci-après sous le nom SampleXMLData.xml :
<ROOT> <Customers> <CompanyName>Hanari Carnes</CompanyName> <City>NY</City> <Order OrderID="1" /> <Order OrderID="2" /> <CustomerID>1111</CustomerID> </Customers> <Customers> <CompanyName>Toms Spezialitten</CompanyName> <City>LA</City> <Order OrderID="3" /> <CustomerID>1112</CustomerID> </Customers> <Customers> <CompanyName>Victuailles en stock</CompanyName> <Order OrderID="4" /> <CustomerID>1113</CustomerID> </Customers> </ROOT>
Pour effectuer le chargement en masse XML, enregistrez l'exemple Microsoft Visual Basic Scripting Edition (VBScript) suivant sous le nom MySample.vbs, puis exécutez-le :
set objBL = CreateObject("SQLXMLBulkLoad.SQLXMLBulkload.4.0") objBL.ConnectionString = "provider=SQLOLEDB;data source=localhost;database=tempdb;integrated security=SSPI" objBL.ErrorLogFile = "c:\error.log" objBL.CheckConstraints = True objBL.Transaction=True objBL.Execute "c:\SampleSchema.xml", "c:\SampleXMLData.xml" set objBL=Nothing
Il en résulte que la fonctionnalité de chargement en masse XML insère une valeur NULL dans la colonne de clé étrangère CustomerID de la table CustOrder. Si vous modifiez l'exemple de données XML de sorte que l'élément enfant <CustomerID> apparaisse avant l'élément enfant <Order>, vous obtenez le résultat attendu : la fonctionnalité de chargement en masse XML insère la valeur de clé étrangère spécifiée dans la colonne.
Voici le schéma XDR équivalent :
<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
xmlns:dt="urn:schemas-microsoft-com:xml:datatypes"
xmlns:sql="urn:schemas-microsoft-com:xml-sql" >
<ElementType name="CustomerID" />
<ElementType name="CompanyName" />
<ElementType name="City" />
<ElementType name="root" sql:is-constant="1">
<element type="Customers" />
</ElementType>
<ElementType name="Customers" sql:relation="Cust" >
<element type="CustomerID" sql:field="CustomerID" />
<element type="CompanyName" sql:field="CompanyName" />
<element type="City" sql:field="City" />
<element type="Order" >
<sql:relationship
key-relation ="Cust"
key ="CustomerID"
foreign-key ="CustomerID"
foreign-relation="CustOrder" />
</element>
</ElementType>
<ElementType name="Order" sql:relation="CustOrder" >
<AttributeType name="OrderID" />
<AttributeType name="CustomerID" />
<attribute type="OrderID" />
<attribute type="CustomerID" />
</ElementType>
</Schema>