解决的问题
对于很对财税的业务系统,修改新老科目比较麻烦。
因为报表里面配置了很多公式,里面写了很多老科目,如果一个个手工替换,会耗时较久。
我的思路是通过程序来跑这个功能。下面用科目编码来举例。如何修改。
准备工作
1.首先要有一个新老科目的对照表:
老科目 | 新科目 |
---|---|
6602051401 | 66021011 |
2.根据新老科目对照表建一个数据库表:
– 创建B表,包含原编码和新编码的对照关系
CREATE TABLE B (b1 VARCHAR(255) PRIMARY KEY, -- 原编码b2 VARCHAR(255) -- 新编码
);
– 插入示例数据到B表
INSERT INTO B (b1, b2) VALUES
('6602051401', '66021011'),
('6602040101', '66020901');
关于excel数据可以用根据直接导入数据库,或者可以手工拼接一个insert语句。
拼接语句的链接可以参考如下:
https://blog.csdn.net/qq_42985657/article/details/129079141
我之前的链接写了一个update的,把语法调整一下就可以了。
准备工作总结:
1.现在数据库中有一个需要更新数据的业务表A的a1列(a1列就是要修改的列),以及a2列(a2列就是表A的唯一标识字段或者是组合唯一标识字段)。
2.一个表B来存储新老科目的对照关系,b1是原编码,b2是新编码。
代码编写
思路
遍历A表的每一行,并使用字符串函数来精确定位和替换原编码。下面的代码中数据库链接方式,以及6个参数要根据实际情况来编写。
代码
import java.sql.*;
import java.util.*;public class CodeUpdater {// 封装数据库连接信息private static class DBConfig {String url;String username;String password;DBConfig(String url, String username, String password) {this.url = url;this.username = username;this.password = password;}}// 封装表及字段信息private static class TableConfig {String sourceTable;String fieldToUpdate;String uniqueIdentifier;String mappingTable;String mappingFieldOldCode;String mappingFieldNewCode;TableConfig(String sourceTable, String fieldToUpdate, String uniqueIdentifier,String mappingTable, String mappingFieldOldCode, String mappingFieldNewCode) {this.sourceTable = sourceTable;this.fieldToUpdate = fieldToUpdate;this.uniqueIdentifier = uniqueIdentifier;this.mappingTable = mappingTable;this.mappingFieldOldCode = mappingFieldOldCode;this.mappingFieldNewCode = mappingFieldNewCode;}}// 更新编码的核心逻辑方法private static void updateCodes(Connection conn, TableConfig tableConfig) throws SQLException {Map<String, String> codeMap = loadCodeMap(conn, tableConfig);updateSourceTable(conn, tableConfig, codeMap);}// 从映射表中加载编码映射关系private static Map<String, String> loadCodeMap(Connection conn, TableConfig tableConfig) throws SQLException {Map<String, String> codeMap = new HashMap<>();String sql = "SELECT " + tableConfig.mappingFieldOldCode + ", " + tableConfig.mappingFieldNewCode +" FROM " + tableConfig.mappingTable;try (PreparedStatement pstmt = conn.prepareStatement(sql); ResultSet rs = pstmt.executeQuery()) {while (rs.next()) {codeMap.put(rs.getString(tableConfig.mappingFieldOldCode), rs.getString(tableConfig.mappingFieldNewCode));}}return codeMap;}// 更新源表中的编码private static void updateSourceTable(Connection conn, TableConfig tableConfig, Map<String, String> codeMap) throws SQLException {conn.setAutoCommit(false); // 开启事务String sqlSelect = "SELECT " + tableConfig.uniqueIdentifier + ", " + tableConfig.fieldToUpdate +" FROM " + tableConfig.sourceTable;String sqlUpdate = "UPDATE " + tableConfig.sourceTable + " SET " + tableConfig.fieldToUpdate + " = ? WHERE " +tableConfig.uniqueIdentifier + " = ?";try (PreparedStatement pstmtSelect = conn.prepareStatement(sqlSelect);ResultSet rs = pstmtSelect.executeQuery();PreparedStatement pstmtUpdate = conn.prepareStatement(sqlUpdate)) {while (rs.next()) {String id = rs.getString(tableConfig.uniqueIdentifier);String originalString = rs.getString(tableConfig.fieldToUpdate);// 替换编码for (Map.Entry<String, String> entry : codeMap.entrySet()) {if (originalString != null && originalString.contains(entry.getKey())) {originalString = originalString.replace(entry.getKey(), entry.getValue());}}// 更新记录pstmtUpdate.setString(1, originalString);pstmtUpdate.setString(2, id);pstmtUpdate.executeUpdate();}conn.commit(); // 提交事务} catch (SQLException e) {conn.rollback(); // 发生异常时回滚事务throw e; // 重新抛出异常以便上层处理}}// 主方法,用于启动更新流程public static void main(String[] args) {// 示例命令行参数
String[] exampleArgs = {"employees", // sourceTable: 源数据表名"department", // fieldToUpdate: 需要更新的字段名"employee_id", // uniqueIdentifier: 用于唯一标识记录的字段名"dept_mapping", // mappingTable: 映射表名,用于查找旧代码对应的新代码"old_dept_code", // mappingFieldOldCode: 映射表中存储旧代码的字段名"new_dept_code" // mappingFieldNewCode: 映射表中存储新代码的字段名
};// 检查参数数量(虽然这里使用示例参数,但通常在实际应用中仍需检查)
// if (args.length != 6) {
// System.out.println("Usage: java CodeUpdater <sourceTable> <fieldToUpdate> <uniqueIdentifier> <mappingTable> <mappingFieldOldCode> <mappingFieldNewCode>");
// return;
// }// 解析命令行参数(这里使用示例参数进行演示)
TableConfig tableConfig = new TableConfig(exampleArgs[0], // 源数据表名exampleArgs[1], // 需要更新的字段名exampleArgs[2], // 用于唯一标识记录的字段名exampleArgs[3], // 映射表名,用于查找旧代码对应的新代码exampleArgs[4], // 映射表中存储旧代码的字段名exampleArgs[5] // 映射表中存储新代码的字段名
);// 数据库连接配置DBConfig dbConfig = new DBConfig("jdbc:mysql://localhost:3306/your_database_name", "your_database_username", "your_database_password");Connection conn = null;try {// 建立数据库连接conn = DriverManager.getConnection(dbConfig.url, dbConfig.username, dbConfig.password);// 调用核心逻辑方法更新编码updateCodes(conn, tableConfig);System.out.println("编码替换完成。");} catch (SQLException e) {e.printStackTrace();} finally {// 关闭数据库连接if (conn != null) {try { conn.close(); } catch (SQLException e) { e.printStackTrace(); }}}}
}