批注解释 - sql:relationship 和键排序规则
由于 XML 大容量加载在其节点进入范围时生成记录,并将这些记录作为其节点退出范围发送到Microsoft SQL Server,因此记录的数据必须存在于节点的作用域内。
请考虑以下 XSD 架构,其中 Customer> 和< Order> 元素(一个客户可以放置多个订单)之间的<一对多关系是使用< 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>
<当 Customer> 元素节点进入范围时,XML 大容量加载将生成客户记录。 此记录一直保留到 XML 大容量加载读取 </Customer>。 在处理 <Order> 元素节点时,XML 大容量加载使用 <sql:relationship> 从< Customer> 父元素获取 CustOrder 表的 CustomerID 外键列的值,因为 <Order> 元素未指定 CustomerID 属性。 这意味着在定义 <Customer> 元素时,必须先在架构中指定 CustomerID 属性,然后才能指定 <sql:relationship。> 否则,当 Order> 元素进入范围时<,XML 大容量加载将为 CustOrder 表生成一条记录,当 XML 大容量加载到达< /Order> 结束标记时,它将记录发送到 SQL Server 而不使用 CustomerID 外键列值。
将在该示例中提供的架构另存为 SampleSchema.xml。
测试工作示例
创建以下表:
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
将下面的示例数据另存为 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>
若要执行 XML 大容量加载,请保存并执行以下Microsoft Visual Basic 脚本版本(VBScript)示例作为 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
结果是 XML 大容量加载在 CustOrder 表的 CustomerID 外键列中插入一个 NULL 值。 如果修改 XML 示例数据,以便 <CustomerID> 子元素出现在 Order> 子元素之前<,则会收到预期结果:XML 大容量加载会将指定的外键值插入列中。
这是等效的 XDR 架构:
<?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>