Partilhar via


Processo de Geração de Registos (SQLXML 4.0)

Aplica-se a:SQL ServerBanco de Dados SQL do Azure

O XML Bulk Load processa os dados de entrada XML e prepara registos para as tabelas apropriadas no Microsoft SQL Server. A lógica no XML Bulk Load determina quando gerar um novo registo, que valores de elemento ou atributo filho copiar para os campos do registo, e quando o registo está completo e pronto para ser enviado para SQL Server para inserção.

O XML Bulk Load não carrega todos os dados de entrada XML na memória e não produz conjuntos completos de registos antes de enviar os dados para o SQL Server. Isto deve-se ao facto de os dados de entrada XML poderem ser um documento grande e carregar o documento inteiro na memória pode ser dispendioso. Em vez disso, o XML Bulk Load faz o seguinte:

  1. Analisa o esquema de mapeamento e prepara o plano de execução necessário.

  2. Aplica o plano de execução aos dados no fluxo de entrada.

Este processamento sequencial torna importante fornecer os dados de entrada XML de uma forma específica. Deve compreender como o XML Bulk Load analisa o esquema de mapeamento e como ocorre o processo de geração de registos. Com esta compreensão, pode fornecer um esquema de mapeamento para XML Bulk Load que produza os resultados que pretende.

O XML Bulk Load trata anotações comuns de esquemas de mapeamento, incluindo mapeamentos de colunas e tabelas (especificados explicitamente através de anotações ou implicitamente através do mapeamento padrão), e relações de junção.

Observação

Presume-se que está familiarizado com esquemas de mapeamento XSD ou XDR anotados. Para mais informações sobre esquemas, consulte Introdução aos Esquemas XSD Anotados (SQLXML 4.0) ou Esquemas XDR Anotados (Descontinuados no SQLXML 4.0).

Compreender a geração de registos requer compreender os seguintes conceitos:

  • Âmbito de um nó

  • Regra da Geração de Registos

  • Subconjunto de registos e a Regra de Ordenação de Tonalidades

  • Exceções à Regra da Geração de Registos

Âmbito de um Nó

Um nó (um elemento ou atributo) num documento XML entra no âmbito quando o XML Bulk Load o encontra no fluxo de dados de entrada XML. Para um nó de elemento, a etiqueta de início do elemento traz o elemento para o âmbito. Para um nó de atributo, o nome do atributo traz o atributo para dentro do âmbito.

Um nó sai do âmbito quando não há mais dados para ele: seja na etiqueta final (no caso de um nó elemento) ou no final de um valor de atributo (no caso de um nó de atributo).

Regra da Geração de Registos

Quando um nó (elemento ou atributo) entra no âmbito, existe a possibilidade de gerar um registo a partir desse nó. O registo permanece enquanto o nó associado estiver dentro do âmbito. Quando o nó sai do âmbito, o XML Bulk Load considera o registo gerado completo (com dados) e envia-o para o SQL Server para inserção.

Por exemplo, considere o seguinte fragmento do esquema XSD:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"  
            xmlns:sql="urn:schemas-microsoft-com:mapping-schema">  
  <xsd:element name="Customer" sql:relation="Customers" >  
   <xsd:complexType>  
     <xsd:attribute name="CustomerID" type="xsd:string" />  
     <xsd:attribute name="CompanyName" type="xsd:string" />  
    </xsd:complexType>  
  </xsd:element>  
</xsd:schema>  

O esquema especifica um <elemento Cliente> com atributos CustomerID e Companyname . A anotação sql:relation mapeia o <elemento Cliente> para a tabela Clientes.

Considere este fragmento de um documento XML:

<Customer CustomerID="1" CompanyName="xyz" />  
<Customer CustomerID="2" CompanyName="abc" />  
...  

Quando o XML Bulk Load é fornecido com o esquema descrito nos parágrafos anteriores e dados XML como entrada, processa os nós (elementos e atributos) nos dados de origem da seguinte forma:

  • A etiqueta inicial do primeiro <elemento Cliente> traz esse elemento para um alcance. Este nó corresponde à tabela Clientes. Portanto, o XML Bulk Load gera um registo para a tabela Clientes.

  • No esquema, todos os atributos do <elemento Cliente> correspondem às colunas da tabela Clientes. À medida que estes atributos entram no âmbito, o XML Bulk Load copia os seus valores para o registo do cliente já gerado pelo âmbito pai.

  • Quando o XML Bulk Load chega à etiqueta final do <elemento Cliente> , o elemento sai do âmbito do alcance. Isto faz com que o XML Bulk Load considere o registo completo e o envie para o SQL Server.

O XML Bulk Load segue este processo para cada elemento cliente> subsequente<.

Importante

Neste modelo, como um registo é inserido quando a tag final é atingida (ou o nó está fora do âmbito), deve definir todos os dados associados ao registo dentro do âmbito do nó.

Subconjunto de registos e a regra de ordenação de tonalidades

Quando especificas um esquema de mapeamento que usa <sql:relationship>, o termo do subconjunto refere-se ao conjunto de registos gerados no lado estrangeiro da relação. No exemplo seguinte, os registos CustOrder estão do lado estrangeiro, <sql:relationship>.

Por exemplo, suponha que uma base de dados contém as seguintes tabelas:

  • Cust (CustomerID, Nome da Empresa, Cidade)

  • CustOrder (CustomerID, OrderID)

O CustomerID na tabela CustOrder é uma chave externa que se refere à chave primária CustomerID na tabela Cust.

Agora, considere a vista XML conforme especificada no seguinte esquema XSD anotado. Este esquema utiliza <sql:relation> para especificar a relação entre as tabelas Cust e CustOrder.

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

Os dados XML de exemplo e os passos para criar uma amostra funcional são apresentados abaixo.

  • Quando um <nó de elemento cliente> no ficheiro de dados XML entra no âmbito, o XML Bulk Load gera um registo para a tabela Cust. O XML Bulk Load copia então os valores das colunas necessários (CustomerID, CompanyName e City) dos <elementos filhos CustomerID>, <CompanyName> e <City> à medida que estes elementos entram no âmbito de aplicação.

  • Quando um nó de elemento Order> entra no âmbito, o XML Bulk Load gera um registo para a tabela CustOrder.< O XML Bulk Load copia o valor do atributo OrderID para este registo. O valor necessário para a coluna CustomerID é obtido do <elemento filho CustomerID> do <elemento Cliente> . XML Bulk Load utiliza a informação especificada em <sql:relation> para obter o valor da chave estrangeira CustomerID para este registo, a menos que o atributo CustomerID tenha sido especificado no <elemento Ordem> . A regra geral é que, se o elemento filho especificar explicitamente um valor para o atributo da chave estrangeira, o XML Bulk Load usa esse valor e não obtém o valor do elemento pai usando a relação> sql:especificada<. À medida que este <nó de elemento de Ordem> sai do âmbito, o XML Bulk Load envia o registo para o SQL Server e depois processa todos os nós subsequentes <de elementos de Ordem> da mesma forma.

  • Finalmente, o <nó do elemento Cliente> sai do âmbito. Nesse momento, o XML Bulk Load envia o registo do cliente para o SQL Server. O XML Bulk Load segue este processo para todos os clientes subsequentes no fluxo de dados XML.

Aqui estão duas observações sobre o esquema de mapeamento:

  • Quando o esquema satisfaz a regra de "contenção" (por exemplo, todos os dados associados ao cliente e à encomenda são definidos dentro do âmbito dos nós de Cliente> e elemento de Encomenda associados<), a carga em massa tem sucesso.><

  • Ao descrever o <elemento Cliente> , os seus elementos filhos são especificados na ordem apropriada. Neste caso, o <elemento filho CustomerID> é especificado antes do <elemento filho da Ordem> . Isto significa que, no ficheiro de dados XML de entrada, o <valor do elemento CustomerID> está disponível como valor de chave estrangeira quando o <elemento da Ordem> entra no âmbito. Os atributos-chave são especificados primeiro; esta é a "Regra de Ordenação de Teclas."

    Se especificar o <elemento filho CustomerID> após o <elemento filho da Ordem> , o valor não está disponível quando o <elemento da Ordem> entra no âmbito. Quando a <tag final /> Order é então lida, o registo da tabela CustOrder é considerado completo e é inserido na tabela CustOrder com um valor NULL para a coluna CustomerID, que não é o resultado desejado.

Para criar uma amostra funcional

  1. Guarde o esquema fornecido neste exemplo como SampleSchema.xml.

  2. Crie estas tabelas:

    CREATE TABLE Cust (  
                  CustomerID     int         PRIMARY KEY,  
                  CompanyName    varchar(20) NOT NULL,  
                  City           varchar(20) DEFAULT 'Seattle')  
    GO  
    CREATE TABLE CustOrder (  
                 OrderID        int         PRIMARY KEY,  
                 CustomerID     int         FOREIGN KEY REFERENCES                                          Cust(CustomerID))  
    GO  
    
  3. Guardar os seguintes dados XML de amostra como SampleXMLData.xml:

    <ROOT>  
      <Customers>  
        <CustomerID>1111</CustomerID>  
        <CompanyName>Hanari Carnes</CompanyName>  
        <City>NY</City>   
        <Order OrderID="1" />  
        <Order OrderID="2" />  
      </Customers>  
    
      <Customers>  
        <CustomerID>1112</CustomerID>  
        <CompanyName>Toms Spezialitten</CompanyName>  
        <City>LA</City>  
        <Order OrderID="3" />  
      </Customers>  
      <Customers>  
        <CustomerID>1113</CustomerID>  
        <CompanyName>Victuailles en stock</CompanyName>  
        <Order OrderID="4" />  
    </Customers>  
    </ROOT>  
    
  4. Para executar o XML Bulk Load, guarde e execute o seguinte exemplo do Microsoft Visual Basic Scripting Edition (VBScript) (BulkLoad.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.Execute "c:\SampleSchema.xml", "c:\SampleXMLData.xml"  
    set objBL=Nothing  
    

Exceções à Regra da Geração de Registos

O XML Bulk Load não gera um registo para um nó quando este entra no âmbito se esse nó for do tipo IDREF ou IDREFS. Deve garantir que uma descrição completa do registo ocorre em algum ponto do esquema. As anotações dt:type="nmtokens" são ignoradas tal como o tipo IDREFS é ignorado.

Por exemplo, considere o seguinte esquema XSD que descreve <os elementos do Cliente> e <da Encomenda> . O <elemento Customer> inclui um atributo OrderList do tipo IDREFS. A <etiqueta sql:relationship> especifica a relação um-para-muitos entre o cliente e a lista de encomendas.

Este é o esquema:

<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:attribute name="CustomerID" type="xsd:integer" />  
    <xsd:attribute name="CompanyName" type="xsd:string" />  
    <xsd:attribute name="City" type="xsd:string" />  
    <xsd:attribute name="OrderList"   
                       type="xsd:IDREFS"   
                       sql:relation="CustOrder"   
                       sql:field="OrderID"  
                       sql:relationship="CustCustOrder" >  
    </xsd:attribute>  
  </xsd:complexType>  
 </xsd:element>  
  
  <xsd:element name="Order" sql:relation="CustOrder" >  
   <xsd:complexType>  
    <xsd:attribute name="OrderID" type="xsd:string" />  
    <xsd:attribute name="CustomerID" type="xsd:integer" />  
    <xsd:attribute name="OrderDate" type="xsd:date" />  
  </xsd:complexType>  
 </xsd:element>  
</xsd:schema>  

Como o Bulk Load ignora os nós do tipo IDREFS, não há geração de registo quando o nó do atributo OrderList entra no âmbito. Portanto, se quiser que os registos de encomendas sejam adicionados à tabela de Encomendas, deve descrever essas ordens em algum lugar do esquema. Neste esquema, especificar o <elemento Order> assegura que o XML Bulk Load adiciona os registos de encomendas à tabela de Ordens. O <elemento Order> descreve todos os atributos necessários para preencher o registo da tabela CustOrder.

Deve garantir que os valores CustomerID e OrderID no <elemento Cliente> correspondem aos valores do <elemento Ordem> . És responsável por manter a integridade referencial.

Para testar uma amostra funcional

  1. Crie estas tabelas:

    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),  
                  OrderDate      datetime DEFAULT '2000-01-01')  
    GO  
    
  2. Guarde o esquema de mapeamento fornecido neste exemplo como SampleSchema.xml.

  3. Guarde os seguintes dados XML de exemplo como SampleXMLData.xml:

    <ROOT>  
      <Customers CustomerID="1111" CompanyName="Sean Chai" City="NY"  
                 OrderList="Ord1 Ord2" />  
      <Customers CustomerID="1112" CompanyName="Dont Know" City="LA"  
                 OrderList="Ord3 Ord4" />  
      <Order OrderID="Ord1" CustomerID="1111" OrderDate="1999-01-01" />  
      <Order OrderID="Ord2" CustomerID="1111" OrderDate="1999-02-01" />  
      <Order OrderID="Ord3" CustomerID="1112" OrderDate="1999-03-01" />  
      <Order OrderID="Ord4" CustomerID="1112" OrderDate="1999-04-01" />  
    </ROOT>  
    
  4. Para executar o XML Bulk Load, guarde e execute este exemplo de VBScript (SampleVB.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.Execute "c:\SampleSchema.xml", "c:\SampleXMLData.xml"  
    set objBL=Nothing