a
This commit is contained in:
@@ -0,0 +1,315 @@
|
||||
# 数据导入
|
||||
|
||||
<cite>
|
||||
**本文引用的文件**
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp)
|
||||
- [IOManager.h](file://h/IOManager.h)
|
||||
- [Constant.h](file://h/Constant.h)
|
||||
- [DataOperator.h](file://h/DataOperator.h)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构总览](#架构总览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考量](#性能考量)
|
||||
8. [故障排查指南](#故障排查指南)
|
||||
9. [结论](#结论)
|
||||
|
||||
## 简介
|
||||
本文件面向“数据导入”功能的完整流程进行深入文档化,重点覆盖:
|
||||
- CIOManager::Import 方法如何验证源.accdb文件的有效性(数据库版本检查、密码验证机制)
|
||||
- 导入过程中的事务管理与数据一致性保障
|
||||
- ImportProjectToDB、ImportTzToDB 等系列方法如何解析外部数据库并安全导入到当前系统数据库
|
||||
- 数据映射规则、主键处理、外键约束维护及冲突解决策略
|
||||
- 导入失败时的回滚机制与错误报告方式
|
||||
|
||||
## 项目结构
|
||||
数据导入功能位于 Managers 层,核心类为 CIOManager,负责导入与导出的统一入口;导入流程围绕 Access 数据库(.accdb)展开,使用 ADO/ADOX 进行连接与表结构创建,并通过事务保证一致性。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "导入模块"
|
||||
CIO["CIOManager<br/>导入/导出入口"]
|
||||
Imp["Import()<br/>验证与事务控制"]
|
||||
Proj["ImportProjectToDB()"]
|
||||
Tz["ImportTzToDB()"]
|
||||
Spt["ImportSptToDB()"]
|
||||
Rsp["ImportRspTdToDB()"]
|
||||
Ipsp["ImportIpspTdToDB()"]
|
||||
end
|
||||
subgraph "系统数据库"
|
||||
SysConn["_ConnectionPtr<br/>系统数据库连接"]
|
||||
Cat["ADOX::Catalog<br/>表结构管理"]
|
||||
end
|
||||
subgraph "外部数据库(.accdb)"
|
||||
ExtConn["_ConnectionPtr<br/>外部数据库连接"]
|
||||
DbVer["dbversion 表<br/>版本校验"]
|
||||
end
|
||||
CIO --> Imp
|
||||
Imp --> Proj
|
||||
Imp --> Tz
|
||||
Imp --> Spt
|
||||
Imp --> Rsp
|
||||
Imp --> Ipsp
|
||||
Imp --> SysConn
|
||||
CIO --> Cat
|
||||
Imp --> ExtConn
|
||||
ExtConn --> DbVer
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L100-L204)
|
||||
- [IOManager.h](file://h/IOManager.h#L15-L51)
|
||||
|
||||
章节来源
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L100-L204)
|
||||
- [IOManager.h](file://h/IOManager.h#L15-L51)
|
||||
|
||||
## 核心组件
|
||||
- CIOManager:导入/导出的统一入口,提供 Import/Export 方法,内部封装对各业务表的导入逻辑。
|
||||
- 外部数据库(.accdb):包含 project、tz、td、tdhead、parameter、rspcon、ipspcon、gr、scon、channel、script、dbversion 等表。
|
||||
- 系统数据库:通过 ADOX 创建目标表结构,使用 ADO 执行插入与更新。
|
||||
- 常量与返回码:统一的执行状态码(成功/失败/取消/重复/关联异常等),用于错误上报与流程控制。
|
||||
|
||||
章节来源
|
||||
- [IOManager.h](file://h/IOManager.h#L15-L51)
|
||||
- [Constant.h](file://h/Constant.h#L138-L151)
|
||||
|
||||
## 架构总览
|
||||
导入流程采用“打开外部数据库 -> 版本校验 -> 开启系统数据库事务 -> 分表导入 -> 提交或回滚”的模式。每个导入方法均以“先查询是否存在同名记录 -> 若不存在则插入 -> 存在则跳过(去重)”的策略避免重复导入;同时通过外键字段(如 PRID、TZID、PAID、SCID、DEID、TDID)将不同表之间的关系映射到系统数据库。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant U as "用户"
|
||||
participant M as "CIOManager"
|
||||
participant E as "外部数据库(.accdb)"
|
||||
participant S as "系统数据库"
|
||||
participant T as "事务"
|
||||
U->>M : 调用 Import()
|
||||
M->>E : 打开外部数据库并设置密码
|
||||
M->>E : 查询 dbversion 表进行版本校验
|
||||
alt 校验失败
|
||||
M-->>U : 返回取消/失败
|
||||
else 校验成功
|
||||
M->>S : BeginTrans()
|
||||
M->>S : 导入 project
|
||||
M->>S : 导入 tz
|
||||
M->>S : 导入 scon/channel/script
|
||||
M->>S : 导入 td/rspcon/ipspcon/gr
|
||||
alt 导入过程中发生异常
|
||||
M->>S : RollbackTrans()
|
||||
M-->>U : 返回失败
|
||||
else 成功
|
||||
M->>S : CommitTrans()
|
||||
M-->>U : 返回成功
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L100-L204)
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L1960-L2064)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### CIOManager::Import 验证与事务控制
|
||||
- 文件选择与连接
|
||||
- 弹出文件对话框选择 .accdb 文件,构造连接字符串并设置数据库密码。
|
||||
- 设置最大锁数属性以提升并发写入能力。
|
||||
- 版本检查
|
||||
- 通过查询外部数据库的 dbversion 表,要求存在特定键值(版本标识)才视为有效外部数据库。
|
||||
- 若未命中或抛出异常,关闭连接并提示错误后返回取消/失败。
|
||||
- 事务管理
|
||||
- 成功通过版本检查后,开启系统数据库事务。
|
||||
- 按顺序调用 ImportProjectToDB、ImportTzToDB、ImportSptToDB、ImportRspTdToDB、ImportIpspTdToDB。
|
||||
- 成功则提交,失败则回滚并返回失败。
|
||||
|
||||
章节来源
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L100-L204)
|
||||
|
||||
### ImportProjectToDB:工程表导入
|
||||
- 映射字段
|
||||
- 将外部 project 的 CN、PRname、PRdesc、location、PRdate、duration、PS、CS、PM、QAS、standard 映射到系统 project。
|
||||
- 冲突处理
|
||||
- 先按 CN 查询系统 project 是否已存在,若不存在则插入;存在则跳过。
|
||||
- 主键/唯一性
|
||||
- 以 CN 作为唯一键进行去重判断。
|
||||
|
||||
章节来源
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L2013-L2062)
|
||||
|
||||
### ImportTzToDB:测区表导入
|
||||
- 映射字段
|
||||
- 外部 tz 的 TZname、PRCN、TZdesc、location 映射到系统 tz。
|
||||
- 关系解析
|
||||
- 通过外部 tz.PRCN 查找系统 project 的 ID(PRID),再以 PRID+TZname 在系统 tz 中查重。
|
||||
- 冲突处理
|
||||
- 若系统 tz 中不存在相同 PRID+TZname,则插入;否则跳过。
|
||||
|
||||
章节来源
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L1960-L2011)
|
||||
|
||||
### ImportSptToDB:脚本与通道导入
|
||||
- 映射字段
|
||||
- 外部 scon 的 CN、Sname、Eamount、CHamount、TPamount、definer、DEdate、SCdesc 映射到系统 scon。
|
||||
- 外部 channel 的 CN、CHnumber、AR 映射到系统 channel(通过 SCID 关联 scon)。
|
||||
- 外部 script2d 的 CN、CHnumber、TSN、C1、C2、P1、P2、K、N 映射到系统 script2d(通过 CHID 关联 channel)。
|
||||
- 冲突处理
|
||||
- scon:按 CN 去重;插入后获取新 ID(SCID)。
|
||||
- channel:按 CN+CHnumber 去重;插入后获取新 ID(CHID)。
|
||||
- script2d:按 CN+CHnumber+TSN 去重;插入时使用 CHID。
|
||||
- 外键维护
|
||||
- td 表导入完成后,根据外部 SCCN 更新 td.SCID 字段,完成脚本与测线的关联。
|
||||
|
||||
章节来源
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L1385-L1519)
|
||||
|
||||
### ImportRspTdToDB:电阻率测线导入
|
||||
- 映射字段
|
||||
- 外部 td 的 TDname、DESN、PRCN、TZname、SCCN、TDtype、HFname、CFname、CFRamount、GRFname、GRFRamount 映射到系统 td。
|
||||
- 外部 tdhead 的 TDname、DESN、Cdate、Ctime、rolling、RCamount、Rdirection、CRtime、CPE、CPN、weather、temperature、height、humidity、PM、OP、QA 映射到系统 tdhead。
|
||||
- 外部 parameter 的 TDname、DESN 对应的 LCHamount、RCHamount、LCamount、RCamount、LEamount、REamount、Felectrode、Espacing、Clayout、CLfun 映射到系统 parameter。
|
||||
- 外部 rspcon 的 TDname、DESN 对应的 A、B、M、N、K、SP、Ro、Vp、Ip、SD、RgA、RgB、RgM、RgN、Ttime 映射到系统 rspcon。
|
||||
- 外部 gr 的 TDname、DESN 对应的 electrode、CableH、CableT、P1GR、P2GR 映射到系统 gr。
|
||||
- 关系解析
|
||||
- 通过 PRCN 获取 PRID,再通过 PRID+TZname 获取 TZID。
|
||||
- 通过 DESN 获取 DEID(设备 ID),若不存在则置为 0。
|
||||
- 通过 SCCN 获取 SCID,若不存在则置为 0。
|
||||
- 插入 parameter 后获取 PAID;插入 td 后获取 TDID;随后插入 rspcon/gr 使用 TDID。
|
||||
- 冲突处理
|
||||
- td:按 TDname+DESN 去重;不存在则插入并生成 TDID。
|
||||
- rspcon/gr:按 TDname+DESN+时间戳(或唯一组合)去重;不存在则插入。
|
||||
- 外键维护
|
||||
- 通过 PRID、TZID、PAID、SCID、DEID、TDID 维护层级关系。
|
||||
|
||||
章节来源
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L1743-L1957)
|
||||
|
||||
### ImportIpspTdToDB:激电测线导入
|
||||
- 映射字段
|
||||
- 与电阻率测线类似,但映射到系统 rspcon 的字段为 SP、Ro、VP、IP、M1..M7、TH、D、Zp、FG、Am、Bm、Cm、Dm、r。
|
||||
- 关系解析与冲突处理
|
||||
- 同样基于 PRCN->PRID、PRID+TZname->TZID、DESN->DEID、SCCN->SCID、TDname+DESN->TDID 的映射链路。
|
||||
- 以 TDname+DESN 去重插入 td;随后按 TDname+DESN+唯一字段去重插入 rspcon/gr。
|
||||
|
||||
章节来源
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L1521-L1741)
|
||||
|
||||
### 数据映射规则与主键/外键处理
|
||||
- 映射规则
|
||||
- 外部表字段与系统表字段一一对应,部分日期/数值类型在插入前进行格式化或空值处理。
|
||||
- 外部表中的“编号”字段(如 CN、PRCN、SCCN、DESN)作为跨表关联与去重的关键键。
|
||||
- 主键处理
|
||||
- 系统侧通过自增主键(如 scon.ID、channel.ID、script2d.ID、td.ID、parameter.ID)生成并维护。
|
||||
- 外部侧以 CN、PRCN、SCCN、DESN 等作为唯一键进行去重。
|
||||
- 外键约束维护
|
||||
- 通过 PRCN->PRID、PRID+TZname->TZID、DESN->DEID、SCCN->SCID、TDname+DESN->TDID 等映射,确保 td、rspcon、gr、parameter 等表的外键字段正确指向父表。
|
||||
- 冲突解决策略
|
||||
- 优先采用“存在即跳过”的策略,避免重复导入导致的数据冗余与索引冲突。
|
||||
- 对于脚本与测线的二次关联(如 td.SCID 的更新),在导入 scon 后统一执行,确保外键完整性。
|
||||
|
||||
章节来源
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L1385-L1519)
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L1521-L1957)
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L2013-L2062)
|
||||
|
||||
### 事务管理与一致性保障
|
||||
- 事务边界
|
||||
- 在 Import() 中开启系统数据库事务,随后依次导入各表;任一环节失败均触发回滚。
|
||||
- 错误传播
|
||||
- 导入过程中捕获 COM 错误并返回失败码;UI 层根据返回码进行提示与后续处理。
|
||||
- 并发与锁
|
||||
- 外部数据库连接设置最大锁数,减少锁竞争带来的写入阻塞。
|
||||
|
||||
章节来源
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L100-L204)
|
||||
|
||||
### 导入失败的回滚与错误报告
|
||||
- 回滚机制
|
||||
- 导入任一阶段抛错,立即回滚系统数据库事务并关闭外部数据库连接。
|
||||
- 错误报告
|
||||
- 通过统一的状态码(成功/失败/取消/重复/关联异常等)向调用方反馈结果。
|
||||
- UI 层根据状态码弹出提示或进入错误处理流程。
|
||||
|
||||
章节来源
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L100-L204)
|
||||
- [Constant.h](file://h/Constant.h#L138-L151)
|
||||
|
||||
## 依赖关系分析
|
||||
- CIOManager 依赖系统数据库连接与 ADOX Catalog,用于创建目标表结构与执行插入。
|
||||
- 导入方法之间存在强依赖顺序:project -> tz -> scon/channel/script -> td/rspcon/ipspcon/gr。
|
||||
- 外部数据库必须包含 dbversion 表且包含特定键值,否则导入被拒绝。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class CIOManager {
|
||||
+Import() uint
|
||||
+Export() uint
|
||||
-ImportProjectToDB(pImp)
|
||||
-ImportTzToDB(pImp)
|
||||
-ImportSptToDB(pImp)
|
||||
-ImportRspTdToDB(pImp)
|
||||
-ImportIpspTdToDB(pImp)
|
||||
-m_pConnection
|
||||
-m_pCatalog
|
||||
}
|
||||
class Constant {
|
||||
+APP_SUCCESS
|
||||
+APP_FAIL
|
||||
+APP_CANCLE
|
||||
+APP_DUPLICATE
|
||||
+APP_RELATION
|
||||
+APP_OVERFLOW
|
||||
+APP_DEFAULT
|
||||
}
|
||||
CIOManager --> Constant : "使用返回码"
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [IOManager.h](file://h/IOManager.h#L15-L51)
|
||||
- [Constant.h](file://h/Constant.h#L138-L151)
|
||||
|
||||
章节来源
|
||||
- [IOManager.h](file://h/IOManager.h#L15-L51)
|
||||
- [Constant.h](file://h/Constant.h#L138-L151)
|
||||
|
||||
## 性能考量
|
||||
- 外部数据库写入优化
|
||||
- 在导入前设置最大锁数,降低锁竞争,提高批量写入效率。
|
||||
- 查询与去重策略
|
||||
- 通过唯一键(CN、PRCN、SCCN、DESN、TDname+DESN 等)进行去重,避免重复插入。
|
||||
- 事务粒度
|
||||
- 将所有导入步骤置于同一事务内,减少中间态,保证一致性的同时也意味着单次失败需整体回滚。
|
||||
- I/O 与网络
|
||||
- .accdb 文件通常本地存储,性能瓶颈主要在数据库写入与索引构建;建议在导入前关闭不必要的 UI 刷新与日志输出。
|
||||
|
||||
[本节为通用性能建议,不直接分析具体文件]
|
||||
|
||||
## 故障排查指南
|
||||
- 常见问题与定位
|
||||
- 外部数据库无法打开或密码错误:检查连接字符串与密码设置;确认 .accdb 文件未损坏。
|
||||
- 版本校验失败:确认外部数据库包含 dbversion 表且包含指定键值。
|
||||
- 导入失败回滚:查看返回码与异常栈,定位具体导入方法;检查唯一键冲突与外键映射是否正确。
|
||||
- 建议排查步骤
|
||||
- 独立运行 ImportProjectToDB/ImportTzToDB,确认基础表导入成功。
|
||||
- 检查 scon/channel/script 的关联是否正确,必要时手动执行 td.SCID 更新。
|
||||
- 对照外部与系统表结构,核对字段映射与空值处理逻辑。
|
||||
|
||||
章节来源
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L100-L204)
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L1385-L1519)
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L1521-L1957)
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L1960-L2062)
|
||||
|
||||
## 结论
|
||||
本导入流程通过严格的版本校验、事务控制与去重策略,实现了从外部 .accdb 到系统数据库的可靠迁移。其关键特性包括:
|
||||
- 明确的验证与错误处理路径
|
||||
- 以唯一键驱动的去重与外键映射
|
||||
- 事务边界内的原子性与一致性
|
||||
- 清晰的失败回滚与状态码反馈
|
||||
|
||||
在实际部署中,建议结合业务场景对字段映射与去重策略进行微调,并在导入前做好备份与测试,以确保数据完整性与可追溯性。
|
||||
Reference in New Issue
Block a user