记录生成过程 (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 数据作为输入,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 大容量加载使用 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 脚本版本(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