Compartir a través de


Interpretación de anotaciones: sql:relationship y regla de ordenación de claves

Se aplica a: SQL ServerAzure SQL Database

Dado que la carga masiva XML genera registros a medida que sus nodos entran en el ámbito y los envía a Microsoft SQL Server como ámbito de salida de los nodos, los datos del registro deben estar presentes dentro del ámbito del nodo.

Considere el siguiente esquema XSD, en el que se especifica la relación uno a varios entre los elementos Customer> y< Order> (un cliente puede realizar muchos pedidos) mediante el <elemento 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>  

A medida que el nodo elemento Customer> entra en el <ámbito, la carga masiva XML genera un registro de cliente. Este registro permanece hasta que XML Bulk Load lee /Customer>.< Al procesar el nodo del elemento Order>, la carga masiva XML usa <sql:relationship> para obtener el valor de la columna de clave externa CustomerID de la tabla CustOrder del< elemento primario Customer>, ya que el< elemento Order> no especifica el atributo CustomerID.< Esto significa que, al definir el elemento Customer>, debe especificar el atributo CustomerID en el esquema antes de especificar <sql:relationship>.< De lo contrario, cuando un <elemento Order> entra en el ámbito, la carga masiva XML genera un registro para la tabla CustOrder y cuando la carga masiva XML alcanza la <etiqueta final /Order> , envía el registro a SQL Server sin el valor de columna de clave externa CustomerID.

Guarde el esquema que se proporciona en este ejemplo como SampleSchema.xml.

Para probar un ejemplo funcional

  1. Cree estas tablas:

    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. Guarde los siguientes datos de ejemplo como 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. Para ejecutar la carga masiva XML, guarde y ejecute el siguiente ejemplo de Microsoft Visual Basic Scripting Edition (VBScript) como 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  
    

    Como resultado, la carga masiva XML inserta un valor NULL en la columna de clave externa CustomerID de la tabla CustOrder. Si revisa los datos de ejemplo XML para que el <elemento secundario CustomerID> aparezca antes del <elemento secundario Order> , obtendrá el resultado esperado: Carga masiva XML inserta el valor de clave externa especificado en la columna.

Éste es el esquema XDR equivalente:

<?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>