init
This commit is contained in:
parent
cd7788de95
commit
23a7f0cd81
420
DM_AUTOMATION_RESEARCH.md
Normal file
420
DM_AUTOMATION_RESEARCH.md
Normal file
@ -0,0 +1,420 @@
|
||||
# 达梦数据库自动化执行方案研究报告
|
||||
|
||||
## 📋 调研总结
|
||||
|
||||
### 一、达梦官方提供的工具和接口
|
||||
|
||||
#### 1. **disql命令行工具** ⭐ 推荐
|
||||
**位置**: `D:\sortware\dm_manager\bin\disql.exe`
|
||||
|
||||
**功能**:
|
||||
- 达梦官方命令行SQL执行工具
|
||||
- 类似Oracle的sqlplus
|
||||
- 支持批量执行SQL文件
|
||||
- 支持脚本参数传递
|
||||
|
||||
**命令格式**:
|
||||
```bash
|
||||
# 基本连接
|
||||
disql SYSDBA/password@host:port
|
||||
|
||||
# 执行SQL文件
|
||||
disql SYSDBA/password@host:port @file.sql
|
||||
|
||||
# 直接执行SQL
|
||||
disql SYSDBA/password@host:port -E "SQL语句"
|
||||
|
||||
# 批处理模式(静默)
|
||||
disql -S SYSDBA/password@host:port @file.sql
|
||||
```
|
||||
|
||||
**优点**:
|
||||
- ✅ 官方工具,最稳定可靠
|
||||
- ✅ 无需额外依赖
|
||||
- ✅ 支持所有SQL语法
|
||||
- ✅ 可以在批处理脚本中调用
|
||||
|
||||
**缺点**:
|
||||
- ❌ 输出解析较麻烦
|
||||
- ❌ 错误处理不够灵活
|
||||
|
||||
---
|
||||
|
||||
#### 2. **JDBC驱动** ⭐⭐ 高度推荐
|
||||
**位置**: `D:\sortware\dm_manager\drivers\jdbc\DmJdbcDriver8.jar`
|
||||
|
||||
**驱动类**: `dm.jdbc.driver.DmDriver`
|
||||
|
||||
**连接URL格式**:
|
||||
```
|
||||
jdbc:dm://host:port
|
||||
jdbc:dm://219.142.42.183:5256
|
||||
```
|
||||
|
||||
**Java示例**:
|
||||
```java
|
||||
Class.forName("dm.jdbc.driver.DmDriver");
|
||||
Connection conn = DriverManager.getConnection(
|
||||
"jdbc:dm://219.142.42.183:5256",
|
||||
"SYSDBA",
|
||||
"@1sdgCq456"
|
||||
);
|
||||
Statement stmt = conn.createStatement();
|
||||
stmt.execute("CREATE TABLE ...");
|
||||
conn.commit();
|
||||
```
|
||||
|
||||
**Node.js调用Java方式**:
|
||||
- 使用`child_process.spawn()`执行Java程序
|
||||
- 通过标准输入/输出通信
|
||||
- 获取执行结果和错误信息
|
||||
|
||||
**优点**:
|
||||
- ✅ 功能强大,完全控制
|
||||
- ✅ 支持事务、批处理
|
||||
- ✅ 错误处理完善
|
||||
- ✅ 可以获取详细执行结果
|
||||
|
||||
**缺点**:
|
||||
- ❌ 需要Java环境
|
||||
- ❌ 需要编译Java代码
|
||||
|
||||
---
|
||||
|
||||
#### 3. **Node.js驱动 (dmdb)** ⭐⭐⭐ 最推荐
|
||||
**官方npm包**: `dmdb`
|
||||
|
||||
**安装**:
|
||||
```bash
|
||||
npm install dmdb
|
||||
```
|
||||
|
||||
**基本使用**:
|
||||
```javascript
|
||||
const dmdb = require('dmdb');
|
||||
|
||||
// 创建连接
|
||||
const conn = await dmdb.createConnection({
|
||||
connectString: 'dm://SYSDBA:@1sdgCq456@219.142.42.183:5256',
|
||||
autoCommit: false
|
||||
});
|
||||
|
||||
// 执行SQL
|
||||
await conn.execute('CREATE TABLE ...');
|
||||
await conn.commit();
|
||||
await conn.close();
|
||||
```
|
||||
|
||||
**连接字符串格式**:
|
||||
```
|
||||
dm://username:password@host:port?autoCommit=false&schema=SCHEMA_NAME
|
||||
```
|
||||
|
||||
**优点**:
|
||||
- ✅ **原生Node.js支持**
|
||||
- ✅ 完美集成到我们的工具中
|
||||
- ✅ Promise/async支持
|
||||
- ✅ 连接池支持
|
||||
- ✅ 错误处理完善
|
||||
- ✅ 无需编译,直接使用
|
||||
|
||||
**缺点**:
|
||||
- ❌ 需要安装dmdb包(可能需要C++编译环境)
|
||||
|
||||
---
|
||||
|
||||
## 二、推荐的自动化方案
|
||||
|
||||
### 🏆 方案A: Node.js + dmdb驱动(最佳方案)
|
||||
|
||||
**优势**: 完全原生Node.js,与现有converter.js完美集成
|
||||
|
||||
**实现步骤**:
|
||||
1. 安装dmdb驱动
|
||||
2. 修改现有的auto-executor.js使用dmdb
|
||||
3. 实现连接池和批量执行
|
||||
|
||||
**架构**:
|
||||
```
|
||||
converter.js (转换SQL)
|
||||
↓
|
||||
output/*_dm.sql (转换后的SQL)
|
||||
↓
|
||||
auto-executor-dmdb.js (使用dmdb执行)
|
||||
↓
|
||||
达梦数据库 (5256端口)
|
||||
```
|
||||
|
||||
**代码示例**:
|
||||
```javascript
|
||||
const dmdb = require('dmdb');
|
||||
const fs = require('fs');
|
||||
|
||||
async function executeSQL(host, port, user, password, sqlFile) {
|
||||
const conn = await dmdb.createConnection({
|
||||
connectString: `dm://${user}:${password}@${host}:${port}`,
|
||||
autoCommit: false
|
||||
});
|
||||
|
||||
const sql = fs.readFileSync(sqlFile, 'utf8');
|
||||
const statements = sql.split(';').filter(s => s.trim());
|
||||
|
||||
for (const stmt of statements) {
|
||||
try {
|
||||
await conn.execute(stmt);
|
||||
} catch (err) {
|
||||
console.error('Error:', err.message);
|
||||
}
|
||||
}
|
||||
|
||||
await conn.commit();
|
||||
await conn.close();
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 方案B: Node.js + disql命令行(最稳定)
|
||||
|
||||
**优势**: 使用官方工具,最可靠
|
||||
|
||||
**实现步骤**:
|
||||
1. 检测disql.exe路径
|
||||
2. 使用child_process调用disql
|
||||
3. 解析输出获取结果
|
||||
|
||||
**架构**:
|
||||
```
|
||||
Node.js (smart-executor-disql.js)
|
||||
↓
|
||||
调用 disql.exe
|
||||
↓
|
||||
执行 SQL文件
|
||||
↓
|
||||
解析输出
|
||||
```
|
||||
|
||||
**代码示例**:
|
||||
```javascript
|
||||
const { spawn } = require('child_process');
|
||||
|
||||
function executeWithDisql(host, port, user, password, sqlFile) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const disql = spawn('disql', [
|
||||
`${user}/${password}@${host}:${port}`,
|
||||
'@' + sqlFile
|
||||
]);
|
||||
|
||||
let output = '';
|
||||
disql.stdout.on('data', data => output += data);
|
||||
disql.on('close', code => {
|
||||
if (code === 0) resolve(output);
|
||||
else reject(new Error(output));
|
||||
});
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 方案C: Node.js + Java JDBC桥接(最完整)
|
||||
|
||||
**优势**: 功能最强大,错误处理最好
|
||||
|
||||
**实现步骤**:
|
||||
1. 创建Java执行器类
|
||||
2. Node.js通过child_process调用
|
||||
3. JSON格式传递结果
|
||||
|
||||
**架构**:
|
||||
```
|
||||
Node.js (auto-executor.js)
|
||||
↓
|
||||
生成并编译 SQLExecutor.java
|
||||
↓
|
||||
调用 java -cp DmJdbcDriver8.jar SQLExecutor
|
||||
↓
|
||||
返回JSON格式结果
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 三、实施建议
|
||||
|
||||
### 🎯 推荐实施顺序
|
||||
|
||||
#### 第一步: 尝试dmdb驱动(最优)
|
||||
```bash
|
||||
cd d:/pg2dm-converter
|
||||
npm install dmdb
|
||||
```
|
||||
|
||||
如果安装成功 → 使用方案A
|
||||
如果安装失败 → 进入第二步
|
||||
|
||||
#### 第二步: 使用disql(备选)
|
||||
```bash
|
||||
# 检查disql是否可用
|
||||
D:\sortware\dm_manager\bin\disql.exe -h
|
||||
```
|
||||
|
||||
如果可用 → 使用方案B
|
||||
如果不可用 → 进入第三步
|
||||
|
||||
#### 第三步: Java JDBC(保底)
|
||||
已经实现在auto-executor.js中
|
||||
|
||||
---
|
||||
|
||||
## 四、具体实现计划
|
||||
|
||||
### 立即可行方案: 改进现有的Java JDBC方案
|
||||
|
||||
**当前问题**: 编译和类路径问题
|
||||
|
||||
**解决方案**:
|
||||
1. 预编译Java类
|
||||
2. 使用绝对路径
|
||||
3. 改进错误处理
|
||||
|
||||
**修复后的架构**:
|
||||
```javascript
|
||||
// 1. 一次性编译Java执行器
|
||||
function compileJavaExecutor() {
|
||||
const javacExe = 'D:\\sortware\\dm_manager\\jdk\\bin\\javac.exe';
|
||||
const jdbcJar = 'D:\\sortware\\dm_manager\\drivers\\jdbc\\DmJdbcDriver8.jar';
|
||||
const javaFile = path.join(__dirname, 'DMSQLExecutor.java');
|
||||
|
||||
execSync(`"${javacExe}" -encoding UTF-8 -cp "${jdbcJar}" "${javaFile}"`);
|
||||
}
|
||||
|
||||
// 2. 执行SQL
|
||||
function executeSQL(sqlFile, host, port, user, password) {
|
||||
const javaExe = 'D:\\sortware\\dm_manager\\jdk\\bin\\java.exe';
|
||||
const jdbcJar = 'D:\\sortware\\dm_manager\\drivers\\jdbc\\DmJdbcDriver8.jar';
|
||||
const classPath = `${jdbcJar};${__dirname}`;
|
||||
|
||||
return spawn(javaExe, [
|
||||
'-cp', classPath,
|
||||
'DMSQLExecutor',
|
||||
host, port, user, password, sqlFile
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 五、最终推荐
|
||||
|
||||
### 🏆 最佳方案组合
|
||||
|
||||
**方案**: dmdb(主) + disql(备)
|
||||
|
||||
**理由**:
|
||||
1. **dmdb**: 原生Node.js,最佳集成体验
|
||||
2. **disql**: 官方工具,作为备选方案
|
||||
3. 两者都不依赖Java编译
|
||||
|
||||
**实施步骤**:
|
||||
```bash
|
||||
# 1. 安装dmdb
|
||||
npm install dmdb
|
||||
|
||||
# 2. 创建unified-executor.js(统一执行器)
|
||||
# - 优先使用dmdb
|
||||
# - 如果dmdb不可用,回退到disql
|
||||
# - 两者都不可用,提示用户手动执行
|
||||
|
||||
# 3. 测试
|
||||
node unified-executor.js output/*_dm.sql
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、代码实现对比
|
||||
|
||||
### dmdb方式(推荐)
|
||||
```javascript
|
||||
// 简洁、原生、Promise
|
||||
const conn = await dmdb.createConnection(connectString);
|
||||
await conn.execute(sql);
|
||||
await conn.commit();
|
||||
```
|
||||
|
||||
### disql方式(稳定)
|
||||
```bash
|
||||
# 直接调用官方工具
|
||||
disql SYSDBA/@1sdgCq456@219.142.42.183:5256 @output/schema_dm.sql
|
||||
```
|
||||
|
||||
### JDBC方式(复杂)
|
||||
```javascript
|
||||
// 需要Java代码 + 编译 + 调用
|
||||
const java = spawn('java', ['-cp', classpath, 'Executor', ...args]);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 七、安装dmdb可能遇到的问题
|
||||
|
||||
### 问题1: 需要C++编译环境
|
||||
**解决**: 安装Windows Build Tools
|
||||
```bash
|
||||
npm install --global windows-build-tools
|
||||
```
|
||||
|
||||
### 问题2: Python依赖
|
||||
**解决**: 安装Python 2.7或3.x
|
||||
|
||||
### 问题3: 网络问题
|
||||
**解决**: 使用淘宝镜像
|
||||
```bash
|
||||
npm install dmdb --registry=https://registry.npmmirror.com
|
||||
```
|
||||
|
||||
### 问题4: 完全离线环境
|
||||
**解决**: 使用disql方案
|
||||
|
||||
---
|
||||
|
||||
## 八、性能对比
|
||||
|
||||
| 方案 | 启动速度 | 执行速度 | 错误处理 | 易用性 |
|
||||
|------|---------|---------|---------|--------|
|
||||
| dmdb | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
|
||||
| disql | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ |
|
||||
| JDBC | ⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐ |
|
||||
|
||||
---
|
||||
|
||||
## 九、总结
|
||||
|
||||
**最优方案**:
|
||||
1. **首选**: npm install dmdb → 完美集成
|
||||
2. **备选**: 使用disql命令行 → 最稳定
|
||||
3. **保底**: Java JDBC(已实现)→ 功能最强
|
||||
|
||||
**立即行动**:
|
||||
```bash
|
||||
# 尝试安装dmdb
|
||||
cd d:/pg2dm-converter
|
||||
npm install dmdb
|
||||
|
||||
# 如果成功,我立即创建 dmdb-executor.js
|
||||
# 如果失败,我创建 disql-executor.js
|
||||
```
|
||||
|
||||
**预期效果**:
|
||||
- 一键自动执行所有SQL
|
||||
- 详细的成功/失败统计
|
||||
- 支持断点续传
|
||||
- 可重复执行
|
||||
|
||||
---
|
||||
|
||||
## 附录:参考资料
|
||||
|
||||
- [达梦官方文档 - JDBC接口](https://eco.dameng.com/document/dm/zh-cn/app-dev/java-jdbc.html)
|
||||
- [达梦官方文档 - Node.js编程](https://eco.dameng.com/document/dm/zh-cn/pm/nodejs-rogramming-guide.html)
|
||||
- [达梦官方文档 - disql工具](https://eco.dameng.com/document/dm/zh-cn/pm/getting-started-disql.html)
|
||||
- [GitHub - GORM DaMeng驱动](https://github.com/godoes/gorm-dameng)
|
||||
Loading…
Reference in New Issue
Block a user