You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

168 lines
7.1 KiB
Java

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不含
// /* 读取 9 月 25 日到今天的全部病例 */
// private static final String SQL_ORA_TODAY =
// "SELECT ID号,住院号,住院次数,姓名,性别,入院时间,入院科室编码," +
// " 主管医生工号,年龄,身份证号,出院日期,当前科室编码 " +
// "FROM PORTAL_HIS.V_WZHGD_HZJCXX h " +
// "WHERE 出院日期 >= TO_DATE('2025-09-25', 'YYYY-MM-DD') " +
// "AND 出院日期 <= TRUNC(SYSDATE)";
/* 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 Server9 月 25 日到今天已归档主键 */
// 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) >= '2025-09-25' " +
// "AND 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')";
/* 当前最大 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");
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<String> 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
psIns.setString(10, rs.getString("主管医生工号")); // 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);
}
}