SQLXML 4.0批量导入2TB XML数据至MSSQL主键外键关联问题求助
解决方案
1 调整XSD映射配置
这是问题的核心原因:你在XSD中定义了表关联关系,但没有显式声明自增主键字段的映射规则,SQLXML BulkLoad不知道这些ID是数据库自增生成的,会尝试从XML文件读取对应值插入,自然报错。
你需要为每个表对应的<xs:element>节点下,补充对应自增主键的属性声明,添加sql:identity="ignore"标记,告诉SQLXML忽略XML中的值,由数据库生成自增ID,且自动将生成的ID同步到关联子表的外键字段。
示例修改(以Foos、Foo节点为例,所有父节点都要对应修改):
<!-- 原来的Foos节点修改后 --> <xs:element minOccurs="0" name="Foos" sql:relation="Foos"> <xs:complexType> <xs:sequence> <!-- 原有sequence内容完全保留 --> <xs:element minOccurs="0" maxOccurs="unbounded" name="Foo" sql:relation="Foo" sql:relationship="FoosFoo"> <xs:complexType> <xs:sequence> <!-- 原有Foo节点下的sequence内容完全保留 --> </xs:sequence> <!-- 新增Foo表自增主键声明 --> <xs:attribute name="Foo_Id" sql:field="Foo_Id" sql:identity="ignore" type="xs:long" /> </xs:complexType> </xs:element> </xs:sequence> <!-- 新增Foos表自增主键声明 --> <xs:attribute name="Foos_Id" sql:field="Foos_Id" sql:identity="ignore" type="xs:long" /> </xs:complexType> </xs:element>
按照上述规则,为所有在sql:relationship中用到的主键表,都补充对应ID字段的sql:identity="ignore"声明即可。
2 确认数据库表配置
- 所有父表、子表的主键字段(如Foos_Id、Foo_Id等)均设置为
IDENTITY(1,1)自增属性 - 子表的外键字段(如Foo表的Foos_Id字段)不要设置自增属性,保持普通数值类型即可
3 代码参数优化
你当前的KeepIdentity = false配置是正确的,该参数作用就是允许数据库生成自增ID,不需要修改。可以额外补充两个配置提升导入性能和稳定性:
SQLXMLBULKLOADLib.SQLXMLBulkLoad4Class xs = new SQLXMLBULKLOADLib.SQLXMLBulkLoad4Class { ConnectionString = @"Provider=sqloledb;server=foo\Foo01;database=FooXsd;integrated security=SSPI", ErrorLogFile = @"c:\tmp\error.xml", KeepIdentity = false, CheckConstraints = false, // 可按需调整:设为true保证单个文件导入原子性,失败自动回滚,会牺牲少量性能 Transaction = true, // 新增批量提交参数,大幅提升导入性能 BatchSize = 10000 };
4 2TB级数据导入优化建议
- 导入期间将数据库恢复模式调整为简单模式,大幅减少事务日志占用
- 导入前删除所有表的非聚集索引,导入完成后再重建,速度可提升3-10倍
- 采用多线程并行导入不同XML文件,并发数控制在4-8个(根据服务器磁盘IO、CPU负载调整),避免单线程导入速度瓶颈
- 定期清理错误日志,避免单日志文件过大影响性能
内容的提问来源于stack exchange,提问作者JayKayOf4
相关产品推荐
相关产品推荐

