Share via


レコードの生成処理 (SQLXML 4.0)

適用対象:SQL ServerAzure SQL Database

XML 一括読み込みでは、XML 入力データが処理され、Microsoft SQL Serverの適切なテーブルのレコードが準備されます。 XML 一括読み込みのロジックは、新しいレコードを生成するタイミング、レコードのフィールドにコピーする子要素または属性値、およびレコードが完了し、挿入のためにSQL Serverに送信する準備ができた時点を決定します。

XML 一括読み込みでは、XML 入力データ全体がメモリに読み込まれるのではなく、データをSQL Serverに送信する前に完全なレコード セットが生成されることはありません。 これは、XML 入力データが大きなドキュメントの場合に、ドキュメント全体をメモリに読み込むと時間がかかる可能性があるためです。 代わりに、XML 一括読み込みでは次の操作が行われます。

  1. マッピング スキーマを分析し、必要な実行プランを準備する。

  2. 実行プランを入力ストリームのデータに適用する。

この順次処理では、決まった方法で XML 入力データを指定することが重要です。 また、XML 一括読み込みでマッピング スキーマがどのように分析されるかと、レコード生成処理がどのように行われるかについて理解しておく必要があります。 これらを理解しておくと、XML 一括読み込みに対し、必要な結果を生成するマッピング スキーマを指定できます。

XML 一括読み込みでは、注釈により明示的に、または既定のマッピングにより暗黙的に行われる列とテーブルのマッピングを含む一般的なマッピング スキーマ注釈、および結合リレーションシップが処理されます。

注意

注釈付き XSD または XDR マッピング スキーマについて理解していることを前提としています。 スキーマの詳細については、「 注釈付き XSD スキーマの概要 (SQLXML 4.0)」 または 「注釈付き XDR スキーマ (SQLXML 4.0 では非推奨)」を参照してください。

レコード生成を理解するには、次の概念を理解する必要があります。

  • ノードのスコープ

  • レコード生成の規則

  • レコードのサブセットとキーの順序付け規則

  • レコード生成の規則の例外

ノードのスコープ

XML ドキュメント内のノード (要素または属性) は、XML 一括読み込みが XML 入力データ ストリームで検出されると スコープ に入ります。 要素ノードの場合、要素はその開始タグが現れた時点でスコープ内に入ります。 属性ノードの場合、属性はその名前が現れた時点でスコープ内に入ります。

要素ノードの場合は終了タグ、属性ノードの場合は属性値の最後に達し、ノードのデータがなくなると、ノードはスコープ外に出ます。

レコード生成の規則

ノード (要素または属性) がスコープ内に入ると、そのノードからレコードを生成できるようになります。 レコードは、関連付けられたノードがスコープ内にある間、存在します。 ノードがスコープ外になると、XML 一括読み込みでは、生成されたレコードが (データを含む) 完了したと見なされ、挿入のためにSQL Serverに送信されます。

たとえば、次の 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>  

スキーマでは、<CustomerID> 属性と CompanyName 属性を持つ Customer 要素を指定します。 sql:relation 注釈は、Customer 要素を <Customers> テーブルにマップします。

次の XML ドキュメントの一部を考えてみます。

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

XML 一括読み込みで、入力用に前の段落で説明したスキーマと XML データが指定された場合、ソース データのノード (要素と属性) は次のように処理されます。

  • 最初 <の Customer> 要素の開始タグは、その要素をスコープに取り込みます。 このノードは Customers テーブルにマップされます。 したがって、XML 一括読み込みでは Customers テーブルのレコードが生成されます。

  • スキーマでは、Customer 要素のすべての属性が <Customers> テーブルの列にマップされます。 これらの属性がスコープ内に入ると、XML 一括読み込みでは、これらの値が親スコープで生成された顧客レコードにコピーされます。

  • XML 一括読み込みが Customer> 要素の終了タグに<達すると、要素はスコープ外になります。 これにより、XML 一括読み込みでレコードが完了したと見なされ、SQL Serverに送信されます。

XML 一括読み込みは、後続 <の Customer 要素ごとにこのプロセスに> 従います。

重要

このモデルでは、終了タグに達した (ノードがスコープ外に出た) ときにレコードが挿入されるため、レコードに関連付けるすべてのデータをノードのスコープ内に定義する必要があります。

レコード サブセットとキー順序付け規則

sql:relationship> を使用<するマッピング スキーマを指定すると、サブセット用語はリレーションシップの外部側で生成されるレコードのセットを参照します。 次の例では、CustOrder レコードは外部側 <の sql:relationship> にあります。

たとえば、データベースに次のテーブルが含まれているとします。

  • Cust (CustomerID、CompanyName、City)

  • CustOrder (CustomerID、OrderID)

CustOrder テーブルの CustomerID は、Cust テーブルの CustomerID 主キーを参照する外部キーです。

ここで、次の注釈付き XSD スキーマで指定される XML ビューを考えてみます。 このスキーマでは、sql:relationship> を使用<して、Cust テーブルと 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>  

サンプル XML データと、実際のサンプルを作成する手順は次のとおりです。

  • XML データ ファイルの Customer> 要素ノードがスコープに入ると、XML 一括読み込みによって Cust テーブルのレコードが生成されます。< 次に、XML 一括読み込みでは、必要な列値 (CustomerID、CompanyName、City) が CustomerID>、CompanyName、City の子要素から<コピーされ<、これらの要素がスコープに入>ります。 <>

  • Order 要素ノードが<スコープに入ると、XML 一括読み込みによって CustOrder テーブルのレコードが生成されます。> XML 一括読み込みでは、 OrderID 属性の値がこのレコードにコピーされます。 CustomerID 列に必要な値は、Customer> 要素の CustomerID 子要素<から取得されます。>< XML 一括読み込みでは、Order> 要素で CustomerID 属性が指定されていない限り、sql:relationship で指定された情報を使用して、このレコードの CustomerID 外部キー値を<取得します。<> 一般的なルールは、子要素が外部キー属性の値を明示的に指定した場合、XML 一括読み込みでその値が使用され、指定された <sql:relationship> を使用して親要素から値が取得されないことです。 この <Order> 要素ノードがスコープ外になると、XML 一括読み込みによってレコードがSQL Serverに送信され、後続<のすべての Order> 要素ノードが同じ方法で処理されます。

  • 最後に、 <Customer> 要素ノードがスコープ外になります。 その時点で、XML 一括読み込みによって顧客レコードがSQL Serverに送信されます。 XML 一括読み込みでは、XML データ ストリームの後続の顧客すべてについて、この処理が行われます。

マッピング スキーマに関しては、次の 2 つの点に注意してください。

  • スキーマが "包含" ルールを満たす場合 (たとえば、顧客に関連付けられているすべてのデータで、関連付けられた <Customer> 要素ノードと <Order> 要素ノードのスコープ内で注文が定義されている場合)、一括読み込みは成功します。

  • Customer> 要素を<記述する場合、その子要素は適切な順序で指定されます。 この場合、<CustomerID> 子要素は Order> 子要素の前に<指定されます。 つまり、入力 XML データ ファイルでは、<Order 要素がスコープに入ると、CustomerID> 要素の値を<外部キー値として使用できます。> キー属性は最初に指定されます。これを "キーの順序付け規則" といいます。

    Order> 子要素の後に CustomerID 子要素を<指定した場合、Order> 要素がスコープに入ると<、値は使用できません。>< /Order> 終了タグを<読み取ると、CustOrder テーブルのレコードは完全と見なされ、CustomerID 列の NULL 値を持つ CustOrder テーブルに挿入されます。これは目的の結果ではありません。

実際のサンプルを作成するには

  1. この例のスキーマを SampleSchema.xml として保存します。

  2. 次のテーブルを作成します。

    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. 次のサンプル XML 入力データを 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. XML 一括読み込みを実行するには、次の 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  
    

レコード生成の規則の例外

XML 一括読み込みでは、IDREF または IDREFS 型のノードがスコープ内に入っても、ノードのレコードは生成されません。 スキーマのどこかで、レコードを完全に記述するようにしてください。 IDREFS 型が無視されるのと同様に、 dt:type="nmtokens" 注釈は無視されます。

たとえば、Customer> 要素と Order 要素を記述する次の< XSD スキーマを考えてみましょう。>< <Customer> 要素には、IDREFS 型の OrderList 属性が含まれています。 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: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>  

一括読み込みでは IDREFS 型のノードが無視されるため、 OrderList 属性ノードがスコープに入ったときにレコードが生成されません。 このため、注文レコードを Orders テーブルに追加したい場合は、スキーマ内のどこかでこれらの注文を記述する必要があります。 このスキーマでは、Order> 要素を指定すると<、XML 一括読み込みによって Orders テーブルに注文レコードが確実に追加されます。 Order> 要素は<、CustOrder テーブルのレコードを入力するために必要なすべての属性を記述します。

Customer> 要素の CustomerID と OrderID の<値が Order> 要素の値と一致していることを確認する<必要があります。 参照の整合性は必ず維持する必要があります。

実際のサンプルをテストするには

  1. 次のテーブルを作成します。

    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. この例のマッピング スキーマを SampleSchema.xml として保存します。

  3. 次のサンプル XML データを 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. XML 一括読み込みを実行するには、次の 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