oracle表结构同步到oracle 问题修复
This commit is contained in:
parent
528479f777
commit
e62f546a95
|
|
@ -136,7 +136,7 @@ public class StasSyncStrategyServiceImpl extends ServiceImpl<StasSyncStrategyMap
|
||||||
* @return 创建表的SQL语句
|
* @return 创建表的SQL语句
|
||||||
* @throws SQLException 数据库异常
|
* @throws SQLException 数据库异常
|
||||||
*/
|
*/
|
||||||
private static String getCreateTableSql(Connection conn, String sourceOwner, String targetOwner,
|
private String getCreateTableSql(Connection conn, String sourceOwner, String targetOwner,
|
||||||
String table, Integer sourceDbType, Integer targetDbType) throws SQLException {
|
String table, Integer sourceDbType, Integer targetDbType) throws SQLException {
|
||||||
if (!isTableExists(conn, sourceOwner, table, sourceDbType)) {
|
if (!isTableExists(conn, sourceOwner, table, sourceDbType)) {
|
||||||
throw new SQLException("表 " + table + " 在源数据库中不存在");
|
throw new SQLException("表 " + table + " 在源数据库中不存在");
|
||||||
|
|
@ -146,16 +146,114 @@ public class StasSyncStrategyServiceImpl extends ServiceImpl<StasSyncStrategyMap
|
||||||
// Oracle转PostgreSQL的特殊处理
|
// Oracle转PostgreSQL的特殊处理
|
||||||
return generatePgCreateTableFromOracle(conn, sourceOwner, targetOwner, table);
|
return generatePgCreateTableFromOracle(conn, sourceOwner, targetOwner, table);
|
||||||
} else {
|
} else {
|
||||||
// 其他情况使用原始方式
|
return generateOracleCreateTable(conn, sourceOwner, targetOwner, table);
|
||||||
return String.format("CREATE TABLE \"%s\".\"%s\" AS SELECT * FROM \"%s\".\"%s\" WHERE 1=0",
|
}
|
||||||
targetOwner.toUpperCase(), table, sourceOwner.toUpperCase(), table);
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String generateOracleCreateTable(Connection conn, String sourceOwner, String targetOwner, String tableName) {
|
||||||
|
try {
|
||||||
|
DatabaseMetaData metaData = conn.getMetaData();
|
||||||
|
StringBuilder ddl = new StringBuilder();
|
||||||
|
|
||||||
|
// 使用双引号括起targetOwner和tableName
|
||||||
|
ddl.append("CREATE TABLE \"").append(targetOwner).append("\".\"").append(tableName).append("\" (\n");
|
||||||
|
|
||||||
|
// 获取列信息
|
||||||
|
String columnSql = "SELECT column_name, data_type, data_length, data_precision, data_scale, nullable " +
|
||||||
|
"FROM all_tab_columns " +
|
||||||
|
"WHERE owner = ? AND table_name = ? " +
|
||||||
|
"ORDER BY column_id";
|
||||||
|
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(columnSql)) {
|
||||||
|
pstmt.setString(1, sourceOwner.toUpperCase());
|
||||||
|
pstmt.setString(2, tableName.toUpperCase());
|
||||||
|
|
||||||
|
ResultSet rs = pstmt.executeQuery();
|
||||||
|
boolean first = true;
|
||||||
|
|
||||||
|
while (rs.next()) {
|
||||||
|
if (!first) {
|
||||||
|
ddl.append(",\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
String columnName = rs.getString("column_name");
|
||||||
|
String dataType = rs.getString("data_type");
|
||||||
|
int dataLength = rs.getInt("data_length");
|
||||||
|
int dataPrecision = rs.getInt("data_precision");
|
||||||
|
int dataScale = rs.getInt("data_scale");
|
||||||
|
String nullable = rs.getString("nullable");
|
||||||
|
|
||||||
|
String isNullable = "";
|
||||||
|
if ("N".equalsIgnoreCase(nullable)) {
|
||||||
|
isNullable = " NOT NULL";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 列名也用双引号括起来
|
||||||
|
ddl.append(" \"").append(columnName).append("\" ").append(dataType);
|
||||||
|
|
||||||
|
// 处理数据类型长度/精度
|
||||||
|
if (dataPrecision > 0) {
|
||||||
|
// 数字类型:NUMBER(p,s), NUMERIC(p,s) 等
|
||||||
|
ddl.append("(").append(dataPrecision);
|
||||||
|
if (dataScale > 0) {
|
||||||
|
ddl.append(",").append(dataScale);
|
||||||
|
}
|
||||||
|
ddl.append(")");
|
||||||
|
} else if (dataLength > 0 &&
|
||||||
|
("VARCHAR2".equalsIgnoreCase(dataType) ||
|
||||||
|
"CHAR".equalsIgnoreCase(dataType) ||
|
||||||
|
"NVARCHAR2".equalsIgnoreCase(dataType) ||
|
||||||
|
"NCHAR".equalsIgnoreCase(dataType) ||
|
||||||
|
"RAW".equalsIgnoreCase(dataType))) {
|
||||||
|
// 字符类型和RAW类型
|
||||||
|
ddl.append("(").append(dataLength).append(")");
|
||||||
|
} else if ("DATE".equalsIgnoreCase(dataType) ||
|
||||||
|
"CLOB".equalsIgnoreCase(dataType) ||
|
||||||
|
"BLOB".equalsIgnoreCase(dataType) ||
|
||||||
|
"LONG".equalsIgnoreCase(dataType) ||
|
||||||
|
"FLOAT".equalsIgnoreCase(dataType)) {
|
||||||
|
// 这些类型不需要长度/精度信息
|
||||||
|
// 什么也不做
|
||||||
|
} else {
|
||||||
|
// 其他可能需要长度的类型
|
||||||
|
ddl.append("(").append(dataLength).append(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
ddl.append(isNullable);
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取主键信息
|
||||||
|
ResultSet primaryKeys = metaData.getPrimaryKeys(null, sourceOwner.toUpperCase(), tableName.toUpperCase());
|
||||||
|
List<String> pkColumns = new ArrayList<>();
|
||||||
|
|
||||||
|
while (primaryKeys.next()) {
|
||||||
|
// 主键列名也用双引号括起来
|
||||||
|
pkColumns.add("\"" + primaryKeys.getString("COLUMN_NAME") + "\"");
|
||||||
|
}
|
||||||
|
primaryKeys.close();
|
||||||
|
|
||||||
|
if (!pkColumns.isEmpty()) {
|
||||||
|
ddl.append(",\n PRIMARY KEY (");
|
||||||
|
ddl.append(String.join(", ", pkColumns));
|
||||||
|
ddl.append(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移除末尾的分号,只保留右括号
|
||||||
|
ddl.append("\n)");
|
||||||
|
|
||||||
|
return ddl.toString();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException("生成表DDL失败: " + e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成从Oracle到PostgreSQL的建表语句
|
* 生成从Oracle到PostgreSQL的建表语句
|
||||||
*/
|
*/
|
||||||
private static String generatePgCreateTableFromOracle(Connection conn, String sourceOwner,
|
private String generatePgCreateTableFromOracle(Connection conn, String sourceOwner,
|
||||||
String targetOwner, String tableName) throws SQLException {
|
String targetOwner, String tableName) throws SQLException {
|
||||||
StringBuilder sqlBuilder = new StringBuilder();
|
StringBuilder sqlBuilder = new StringBuilder();
|
||||||
//模式名称
|
//模式名称
|
||||||
|
|
@ -236,7 +334,7 @@ public class StasSyncStrategyServiceImpl extends ServiceImpl<StasSyncStrategyMap
|
||||||
/**
|
/**
|
||||||
* Oracle数据类型到PostgreSQL的映射
|
* Oracle数据类型到PostgreSQL的映射
|
||||||
*/
|
*/
|
||||||
private static String mapOracleTypeToPg(String oracleType, int length, int precision, int scale) {
|
private String mapOracleTypeToPg(String oracleType, int length, int precision, int scale) {
|
||||||
switch (oracleType.toUpperCase()) {
|
switch (oracleType.toUpperCase()) {
|
||||||
case "VARCHAR2":
|
case "VARCHAR2":
|
||||||
return "VARCHAR(" + (length > 0 ? length : 255) + ")";
|
return "VARCHAR(" + (length > 0 ? length : 255) + ")";
|
||||||
|
|
@ -284,7 +382,7 @@ public class StasSyncStrategyServiceImpl extends ServiceImpl<StasSyncStrategyMap
|
||||||
* @return 表是否存在
|
* @return 表是否存在
|
||||||
* @throws SQLException 数据库异常
|
* @throws SQLException 数据库异常
|
||||||
*/
|
*/
|
||||||
private static boolean isTableExists(Connection conn, String schema, String tableName, Integer dbType) throws SQLException {
|
private boolean isTableExists(Connection conn, String schema, String tableName, Integer dbType) throws SQLException {
|
||||||
String sql;
|
String sql;
|
||||||
if (SourceDataTypeEnum.ORACLE.getKey().equals(dbType)) {
|
if (SourceDataTypeEnum.ORACLE.getKey().equals(dbType)) {
|
||||||
sql = "SELECT COUNT(*) FROM all_tables WHERE owner = ? AND (table_name = ? OR table_name = ?)";
|
sql = "SELECT COUNT(*) FROM all_tables WHERE owner = ? AND (table_name = ? OR table_name = ?)";
|
||||||
|
|
@ -321,7 +419,7 @@ public class StasSyncStrategyServiceImpl extends ServiceImpl<StasSyncStrategyMap
|
||||||
* @return 列是否存在
|
* @return 列是否存在
|
||||||
* @throws SQLException 数据库异常
|
* @throws SQLException 数据库异常
|
||||||
*/
|
*/
|
||||||
private static boolean isColumnExists(Connection conn, String schema, String tableName,
|
private boolean isColumnExists(Connection conn, String schema, String tableName,
|
||||||
String columnName, Integer dbType) throws SQLException {
|
String columnName, Integer dbType) throws SQLException {
|
||||||
String sql;
|
String sql;
|
||||||
if (SourceDataTypeEnum.ORACLE.getKey().equals(dbType)) {
|
if (SourceDataTypeEnum.ORACLE.getKey().equals(dbType)) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user