記錄產生行程 (SQLXML 4.0)
XML 大量載入會處理 XML 輸入數據,並為 Microsoft SQL Server 中的適當數據表準備記錄。 XML 大量載入中的邏輯會決定何時產生新記錄、要複製到記錄欄位的子項目或屬性值,以及記錄何時完成且準備好要傳送至 SQL Server 進行插入。
XML 大量載入不會將整個 XML 輸入資料載入記憶體中,而且不會在將數據傳送至 SQL Server 之前產生完整的記錄集。 這是因為 XML 輸入數據可以是大型檔,而且在記憶體中載入整個檔的成本可能很高。 相反地,XML 大量載入會執行下列動作:
分析對應架構,並準備必要的執行計劃。
將執行計劃套用至輸入數據流中的數據。
這個循序處理可讓您以特定方式提供 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),因為這些元素進入範圍時, 和 <City> 子元素。<
<當 Order> 元素節點進入範圍時,XML 大量載入會產生 CustOrder 資料表的記錄。 XML 大量載入會將 OrderID 屬性的值複製到此記錄。 CustomerID 資料行所需的值是從 Customer 元素的 CustomerID>> 子元素取得<。< XML 大量載入會使用 sql:relationship 中指定的<資訊來取得此記錄的 CustomerID 外鍵值,除非 Order> 元素中<指定 CustomerID 屬性。> 一般規則是,如果子項目明確指定外鍵屬性的值,XML 大量載入會使用該值,而且不會使用指定的 <sql:relationship> 從父元素取得值。 當這個 Order> 元素節點超出範圍時,XML 大量載入會將記錄傳送至 SQL Server,然後以相同方式處理所有後續<的 Order> 元素節點。<
最後, <Customer> 元素節點超出範圍。 屆時,XML 大量載入會將客戶記錄傳送至 SQL Server。 XML 大量載入會針對 XML 資料流中的所有後續客戶遵循此程式。
以下是關於對應架構的兩個觀察:
當架構滿足「內含專案」規則時(例如,與客戶相關聯的所有數據,以及訂單定義在相關聯 <Customer> 和< Order> 元素節點的範圍內),大量載入就會成功。
在描述 Customer> 元素時<,會依適當的順序指定其子元素。 在此情況下,<CustomerID> 子專案會在 Order> 子元素之前<指定。 這表示在輸入 XML 資料檔中,當 Order> 元素進入範圍時<,<CustomerID> 元素值會當做外鍵值使用。 會先指定索引鍵屬性;這是「索引鍵排序規則」。
如果您在 Order 子元素之後<指定< CustomerID> 子元素,當 Order>> 元素進入範圍時<,將無法使用此值。 <然後讀取 /Order> 結束標記時,CustOrder 資料表的記錄會視為完成,而且會插入 CustOrder 資料表中,其中包含 CustomerID 資料行的 NULL 值,這不是所需的結果。
若要建立工作範例
將此範例中提供的架構儲存為 SampleSchema.xml。
建立這些資料表:
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
將下列範例 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>
若要執行 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
記錄產生規則的例外狀況
如果該節點為IDREF或IDREFS類型,XML大量載入不會在進入範圍時產生節點的記錄。 您必須確定記錄的完整描述發生在架構中的某個位置。 dt:type=“nmtokens” 註釋會忽略,就像忽略 IDREFS 類型一樣。
例如,請考慮下列描述 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> 元素中的<值。 您必須負責維護引用完整性。
測試工作範例
建立這些資料表:
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
將本範例中提供的對應架構儲存為SampleSchema.xml。
將下列範例 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>
若要執行 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