package com.chaozhou; import lombok.extern.slf4j.Slf4j; import java.io.IOException; import java.io.InputStream; import java.sql.*; import java.time.LocalDateTime; import java.util.HashSet; import java.util.Properties; import java.util.Set; /** * @ClassName ArchiveSync * @Description * @Author linjj * @Date 2025/9/26 16:17 * @Version 1.0 */ @Slf4j public class ArchiveSync { /* 读取当天全部病例 */ private static final String SQL_ORA_TODAY = "SELECT ID号,住院号,住院次数,姓名,性别,入院时间,入院科室编码," + "主管医生工号,年龄,身份证号,出院日期,当前科室编码 " + "FROM PORTAL_HIS.V_WZHGD_HZJCXX h " + "WHERE 出院日期 >= TRUNC(SYSDATE) " + // 今天 00:00:00 "AND 出院日期 < TRUNC(SYSDATE) + 1"; // 明天 00:00:00(不含) /* SQL Server:当天已归档主键 */ private static final String SQL_MSS_TODAY_KEYS = "SELECT inp_no + '|' + CAST(visit_id AS VARCHAR) AS key1 " + "FROM archive_master " + "WHERE CONVERT(date, discharge_date_time) = CONVERT(date, GETDATE())"; /* 写入 SQL Server */ private static final String SQL_MSS_INSERT = "INSERT INTO archive_master " + "(id, patient_id, inp_no, visit_id, name, sex, dept_admission_to, " + " admission_date_time, discharge_date_time, DOCTOR_IN_CHARGE, SubAssort, ID_NO, " + " dept_name,id_card,ArchiveState,C1) " + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?, '64','ljj')"; /* MySQL:根据工号查询医生姓名 */ private static final String SQL_MYSQL_DOCTOR_NAME = "SELECT name FROM power_user WHERE user_name = ?"; /* 当前最大 id */ private static final String SQL_MAX_ID = "SELECT ISNULL(MAX(id), 0) FROM archive_master"; public static void main(String[] args) throws Exception { Properties cfg = new Properties(); try (InputStream in = ArchiveSync.class.getResourceAsStream("/application.properties")) { cfg.load(in); } while (true) { try (Connection ora = getConn(cfg, "oracle"); Connection mss = getConn(cfg, "sqlserver"); Connection mysql = getConn(cfg, "mysql"); // 新增 MySQL 连接 PreparedStatement psOra = ora.prepareStatement(SQL_ORA_TODAY); PreparedStatement psKeys = mss.prepareStatement(SQL_MSS_TODAY_KEYS); PreparedStatement psMaxId = mss.prepareStatement(SQL_MAX_ID); PreparedStatement psIns = mss.prepareStatement(SQL_MSS_INSERT)) { /*取 SQL Server 当天已归档主键 */ Set archivedToday = new HashSet<>(); try (ResultSet rs = psKeys.executeQuery()) { while (rs.next()) archivedToday.add(rs.getString(1)); } log.info("SQL Server 当天已存在 {} 条", archivedToday.size()); /* 获取当前最大 id */ ResultSet rsMax = psMaxId.executeQuery(); rsMax.next(); long baseId = rsMax.getLong(1); rsMax.close(); /*查询 Oracle 缺失数据 */ ResultSet rs = psOra.executeQuery(); int total = 0, insert = 0; while (rs.next()) { total++; String key = rs.getString("住院号") + "|" + rs.getString("住院次数"); if (archivedToday.contains(key)) continue; // 已归档,跳过 psIns.setLong(1, baseId + (++insert)); // id psIns.setString(2, rs.getString("ID号")); // patient_id psIns.setString(3, rs.getString("住院号")); // inp_no psIns.setString(4, rs.getString("住院次数")); // visit_id psIns.setNString(5, rs.getString("姓名")); // name // 取出 Oracle 值 String sexOra = rs.getString("性别"); // 字典转换 String sexMss; if (sexOra == null || sexOra.trim().isEmpty()) { sexMss = "不详"; } else if ("1".equals(sexOra)) { sexMss = "男"; } else if ("2".equals(sexOra)) { sexMss = "女"; } else { sexMss = sexOra; } psIns.setNString(6, sexMss); // 对应 archive_master.sex psIns.setNString(7, rs.getString("入院科室编码")); // dept_admission_to psIns.setTimestamp(8, rs.getTimestamp("入院时间")); // admission_date_time psIns.setTimestamp(9, rs.getTimestamp("出院日期")); // discharge_date_time /* 查询 MySQL 获取医生姓名 */ String doctorCode = rs.getString("主管医生工号"); String doctorName = doctorCode; // 默认用编码 if (doctorCode != null && !doctorCode.trim().isEmpty()) { try (PreparedStatement psDoctor = mysql.prepareStatement(SQL_MYSQL_DOCTOR_NAME)) { psDoctor.setString(1, doctorCode.trim()); try (ResultSet rsDoctor = psDoctor.executeQuery()) { if (rsDoctor.next()) { String nameFromMysql = rsDoctor.getString("name"); // 仅当查询到非空姓名时才替换 if (nameFromMysql != null && !nameFromMysql.trim().isEmpty()) { doctorName = nameFromMysql; } } } catch (SQLException e) { log.info("查询医生姓名失败,工号: {}", doctorCode, e); } } } psIns.setString(10, doctorName); // 将查询到的姓名存入 DOCTOR_IN_CHARGE 字段 psIns.setNString(11, rs.getString("年龄")); // SubAssort psIns.setString(12, rs.getString("身份证号")); // id_card psIns.setString(13, rs.getString("当前科室编码")); // dept_name psIns.setString(14, rs.getString("身份证号")); // ID_NO psIns.addBatch(); if (insert % 1000 == 0) psIns.executeBatch(); } if (insert % 1000 != 0) psIns.executeBatch(); mss.commit(); log.info("Oracle 当天共 {} 条,缺失 {} 条,已插入 {} 条", total, insert, insert); } catch (SQLException e) { log.error("同步异常", e); Thread.sleep(5000); } Thread.sleep(Integer.parseInt(System.getProperty("poll.interval", "30")) * 1000L); } } /* 工具:根据前缀拿连接 */ private static Connection getConn(Properties cfg, String db) throws SQLException { String url = cfg.getProperty(db + ".url"); String user = cfg.getProperty(db + ".user"); String pwd = cfg.getProperty(db + ".password"); return DriverManager.getConnection(url, user, pwd); } }