某专科医院老数据库迁移实战记录-Oracle10g sqlserver2008等

某专科医院老数据库迁移实战记录

一次与 Oracle 10g/11g 和 SQL Server 2008/2012 的"考古"式交手

一、背景

最近接手了一个有点"考古"意味的项目------某专科医院的老数据库迁移。环境是这样的:

  • Oracle:3个库,版本分别是 10g 和 11g
  • SQL Server:2个库,版本是 2008 和 2012

数据量其实不大,真正的挑战在于:年代久远,密码早就丢了。HIS 厂商换了好几拨,文档基本等于没有。好在技术层面,这事有门。

二、第一步:无密码登录------操作系统认证救场

2.1 Oracle:sqlplus / as sysdba

一开始最担心的是 Oracle 密码问题。结果试了一下:

powershell 复制代码
PS C:\Users\Administrator> sqlplus / as sysdba

SQL*Plus: Release 11.2.0.4.0 Production on 星期五 7月 24 10:15:16 2026
Copyright (c) 1982, 2013, Oracle. All rights reserved.

连接到: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

直接进去了。

原理 :Oracle 支持操作系统认证(OS Authentication) 。安装 Oracle 时,系统会创建 OSDBA 和 OSOPER 组,只要当前 Windows 用户属于这些组,执行 sqlplus / as sysdba 就可以绕过密码直接登录。这本质上是把数据库的认证信任交给了操作系统。

控制这个行为的参数在 sqlnet.ora 文件中:

  • SQLNET.AUTHENTICATION_SERVICES = (NTS) ------ 允许 Windows 操作系统认证
  • SQLNET.AUTHENTICATION_SERVICES = (NONE) ------ 关闭 OS 认证,必须用密码

既然能登录,说明这个参数是开放的。登录后可以用 ALTER USER 重置任何用户的密码:

sql 复制代码
-- 查看所有用户
SELECT username FROM dba_users;

-- 重置密码
ALTER USER hisuser IDENTIFIED BY newpassword;

几个 Oracle 库都如法炮制,全部连上了。

2.2 SQL Server:Windows 身份验证

SQL Server 的情况类似。SQL Server 的 Windows 身份验证模式 使用 Windows 操作系统的安全凭据来验证用户连接,SQL Server 本身不存储或管理密码。

操作很简单:

  1. 用 Administrator 账户登录 Windows
  2. 打开 SQL Server Management Studio(SSMS)
  3. 选择 Windows 身份验证 连接
  4. 连上之后,可以在"安全性 → 登录名"中重置 sa 密码,并把身份验证模式改为"SQL Server 和 Windows 身份验证模式"

连接字符串(供后续工具使用):

复制代码
Server=服务器IP;Database=库名;Trusted_Connection=True;

两个 SQL Server 库也顺利拿下。

三、第二步:数据迁移------Kettle 上场

3.1 为什么选 Kettle

跨库迁移的方案不少:可以写 Python/Pandas 脚本,也可以用数据库自带的工具(如 Oracle SQL*Loader)。但面对 5 个库、几十上百张表,Kettle(Pentaho Data Integration) 是最省力的选择------它提供可视化的 ETL 操作,尤其是批量迁移功能。

3.2 环境准备

  1. 下载 Kettle(开源版即可),解压后运行 spoon.bat
  2. 把数据库驱动放到 data-integration/lib 目录:
    • Oracle:ojdbc8-19.3.0.0.jar(或对应版本的驱动)
    • SQL Server:jtds-1.3.1.jar 或微软官方驱动

3.3 单表迁移

新建一个转换(右键"转换" → 新建):

  1. 拖入 表输入(源)→ 配置 Oracle 连接 → 点击"获取 SQL 查询语句"选表
  2. 拖入 表输出(目标)→ 配置 SQL Server 连接 → 指定目标表
  3. 用 Shift+连线 连接两个步骤
  4. 点击运行

3.4 批量迁移:复制多表向导

手动一张张表做太慢。Kettle 提供了 "复制多表向导" 功能:

操作路径:工具 → 向导 → 复制多表向导

然后按向导提示:

  1. 选择源数据库连接(Oracle)
  2. 选择目标数据库连接(SQL Server)
  3. 勾选需要迁移的表
  4. Kettle 自动生成迁移作业

注意:复制多表向导适合"目标表不存在、需自动建表并全量复制"的场景。如果目标表已存在且需要复杂的字段映射或值转换,则需要手动组合"表输入→表输出"链路并使用"值映射""字段选择"等组件。

3.5 数据类型转换的坑(重点!)

跨库迁移最大的坑不在连接,在数据类型

Oracle 类型 SQL Server 类型 注意事项
NUMBER numeric(38,0) / decimal 默认的 Oracle NUMBER 和 SQL Server numeric(38,0) 可能不匹配,需指定精度
VARCHAR2 varchar / nvarchar 注意字符集,SQL Server 的 nvarchar 最多 4000 字符,对应 Oracle 的 nvarchar2 只有 2000
DATE datetime / datetime2 精度有差异,Kettle 对日期类型的隐式转换缺乏控制,需统一使用 Timestamp 元数据
CLOB nvarchar(max) 大字段需特殊处理
无布尔型 bit Oracle 没有布尔型,需映射为 number(1) 或 varchar

空字符串和 NULL 也是大坑:Kettle 迁移时,源库的空字符串在插入目标库时可能被转为 NULL,触发非空校验失败。

实践建议

  • 迁移前先在目标库建好表结构,手动确认字段类型映射
  • 先用一两张测试表跑通,验证类型转换没问题再批量执行
  • 目标表在加载数据前禁用所有主键、外键约束和索引,加载完成后再重建

四、第三步:数据结构梳理 + 查询入口

数据迁移完了,但问题才到一半------这些表是干什么的?字段是什么意思?

HIS 厂商不配合是常态。数据字典一旦透明,他们的"独家解释权"就没了。十年间系统经过无数次升级、补丁,文档要么过期要么不存在。

4.1 破局思路:用工具生成"60分字典"

不需要 100% 准确的数据字典,只需要一份能用的"底稿":

  1. 用 SQL 扫描元数据:从系统表中读取所有表名、字段名、字段类型
  2. 抽样分析数据 :看字段里的实际值分布(如 STATUS 字段里有哪些值)
  3. 结合业务上下文推断 :比如 PATIENT_NAMEDIAGNOSIS_CODE 这种命名,含义基本能猜

4.2 技术实现方案

方案一:Streamlit + Python(快速原型)

Streamlit 适合快速搭建数据查询工具:

python 复制代码
import streamlit as st
import cx_Oracle
import pymssql
import pandas as pd

# 配置多数据源连接
oracle_conn = st.connection("oracle", type=SQLConnection)
sqlserver_conn = st.connection("sqlserver", type=SQLConnection)

# 查询并展示
df = oracle_conn.query("SELECT table_name, column_name FROM all_tab_columns WHERE owner='HIS'")
st.dataframe(df)

方案二:Java + Vue(正式系统)

如果要做成生产级工具:

  • 后端:Spring Boot + MyBatis,支持多数据源动态切换
  • 前端:Vue + Element UI
  • 功能:数据源管理、表结构浏览、SQL 查询面板、数据字典导出

4.3 倒逼厂商配合的策略

拿着"60分字典"去和 HIS 厂商谈,效果完全不同:

  1. 用具体问题代替笼统需求 :不说"我们要患者数据",而是问"ZY_PATIENT 表的 STATUS 字段值为 2 时对应什么业务逻辑?"
  2. 让对方知道你已掌握一定信息:对话性质从"单方面需求提报"变成"双方对等的技术讨论"
  3. 利用合同条款:检查原始合同中是否有数据字典、接口文档的交付条款

五、踩坑总结

坑1:Oracle 监听配置

老 Oracle 的 listener.oratnsnames.ora 配置可能有问题。如果远程连接不上,检查监听状态:

bash 复制代码
lsnrctl status
lsnrctl reload

坑2:SQL Server 2008 的兼容性

SQL Server 2008 比较老,某些新版驱动可能不兼容。建议使用 jtds 驱动,或者 SQL Server 2008 对应的旧版微软驱动。

坑3:字符集

Oracle 和 SQL Server 的字符集可能不一致。迁移后出现乱码,需要在 Kettle 的数据库连接配置中指定字符集参数。

坑4:Kettle 版本

Kettle 高版本可能对老数据库驱动支持不好。如果遇到连接问题,可以尝试低版本(如 5.2)。

六、时间线参考

阶段 工作内容 预估时间
第 1 周 用 OS 认证连上所有库,确认数据可达 2-3 天
第 2 周 Kettle 环境搭建 + 单表迁移验证 3-5 天
第 3 周 批量迁移所有表 2-3 天
第 4 周 SQL 扫描生成初步数据字典 3-5 天
第 5 周+ 拿着字典与 HIS 厂商谈判/核对 持续
第 6 周+ 查询工具开发 2-4 周

七、总结

老数据库迁移这件事,技术层面其实不难:

  • Oracle 无密码sqlplus / as sysdba 搞定
  • SQL Server 无密码:Windows 身份验证搞定
  • 数据迁移:Kettle 的复制多表向导一键搞定

真正的难点在业务层面------弄清楚这些表是干什么的。但借助 SQL 元数据扫描 + 数据内容分析,至少可以生成一份"60 分字典",把谈判主动权拿回来。

技术不是瓶颈,信息差才是。

相关推荐
白猫不黑1 小时前
SQL注入实战:手工注入全流程详解
网络·数据库·sql·web安全·网络安全·信息安全
kirs_ur11 小时前
ECC & LDPC — SSD 的数据卫士
服务器·数据库·性能优化
是三一seven11 小时前
Sql注入基础
数据库·安全·网络安全
Sirens.12 小时前
MySQL表设计进阶-约束范式连接索引与事务
android·数据库·mysql
字节跳动开源13 小时前
火山引擎开源 Agent 驱动的搜索自迭代技术
数据库·开源·agent
Oo大司命oO15 小时前
藏在正则表达式里的陷阱
数据库·mysql·正则表达式
_oP_i16 小时前
mysql统计数据库使用存储大小
数据库
会编程的土豆16 小时前
MySQL 入门:库、表、行、主键是什么
linux·数据库·网络协议·http
jjjava2.016 小时前
系统日志:从入门到精通的完整指南
网络·数据库