Partager via


sql:relationship et la règle de tri par clé (SQLXML 4.0)

Étant donné que le chargement en masse XML génère des enregistrements à mesure que leurs nœuds entrent dans l’étendue et les envoie à Microsoft SQL Server lorsque leurs nœuds quittent l’étendue, les données de l’enregistrement doivent être présentes dans l’étendue du nœud.

Considérez le schéma XSD suivant, dans lequel la relation un-à-plusieurs entre <les éléments Customer> et <Order> (un client peut passer plusieurs 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>  

À mesure que le <nœud d’élément Customer> entre dans l’étendue, le chargement en masse XML génère un enregistrement client. Cet enregistrement reste jusqu’à ce que le chargement en masse XML indique </Customer>. Lors du traitement du <nœud d’élément Order> , le chargement en masse XML utilise <sql:relationship> pour obtenir la valeur de la colonne clé étrangère CustomerID de la table CustOrder à partir 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, le chargement en masse XML génère un enregistrement pour la table CustOrder et lorsque le chargement en masse XML atteint la <balise /Order> de fin, il envoie l’enregistrement à SQL Server sans la valeur de colonne de clé étrangère CustomerID.

Enregistrez le schéma fourni dans cet exemple sous le nom SampleSchema.xml.

Pour tester un exemple fonctionnel

  1. 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  
    
  2. 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>  
    
  3. Pour exécuter le chargement en masse XML, enregistrez et exécutez l’exemple microsoft Visual Basic Scripting Edition (VBScript) suivant en tant que MySample.vbs :

    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 révisez les exemples de données XML afin que l’élément <enfant CustomerID> apparaisse avant l’élément <enfant Order> , vous obtenez le résultat attendu : Le 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>