oracle表结构同步到oracle 问题修复
This commit is contained in:
parent
528479f777
commit
e62f546a95
|
|
@ -136,7 +136,7 @@ public class StasSyncStrategyServiceImpl extends ServiceImpl<StasSyncStrategyMap
|
|||
* @return 创建表的SQL语句
|
||||
* @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 {
|
||||
if (!isTableExists(conn, sourceOwner, table, sourceDbType)) {
|
||||
throw new SQLException("表 " + table + " 在源数据库中不存在");
|
||||
|
|
@ -146,16 +146,114 @@ public class StasSyncStrategyServiceImpl extends ServiceImpl<StasSyncStrategyMap
|
|||
// Oracle转PostgreSQL的特殊处理
|
||||
return generatePgCreateTableFromOracle(conn, sourceOwner, targetOwner, table);
|
||||
} else {
|
||||
// 其他情况使用原始方式
|
||||
return String.format("CREATE TABLE \"%s\".\"%s\" AS SELECT * FROM \"%s\".\"%s\" WHERE 1=0",
|
||||
targetOwner.toUpperCase(), table, sourceOwner.toUpperCase(), table);
|
||||
return generateOracleCreateTable(conn, sourceOwner, targetOwner, 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的建表语句
|
||||
*/
|
||||
private static String generatePgCreateTableFromOracle(Connection conn, String sourceOwner,
|
||||
private String generatePgCreateTableFromOracle(Connection conn, String sourceOwner,
|
||||
String targetOwner, String tableName) throws SQLException {
|
||||
StringBuilder sqlBuilder = new StringBuilder();
|
||||
//模式名称
|
||||
|
|
@ -236,7 +334,7 @@ public class StasSyncStrategyServiceImpl extends ServiceImpl<StasSyncStrategyMap
|
|||
/**
|
||||
* 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()) {
|
||||
case "VARCHAR2":
|
||||
return "VARCHAR(" + (length > 0 ? length : 255) + ")";
|
||||
|
|
@ -284,7 +382,7 @@ public class StasSyncStrategyServiceImpl extends ServiceImpl<StasSyncStrategyMap
|
|||
* @return 表是否存在
|
||||
* @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;
|
||||
if (SourceDataTypeEnum.ORACLE.getKey().equals(dbType)) {
|
||||
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 列是否存在
|
||||
* @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 sql;
|
||||
if (SourceDataTypeEnum.ORACLE.getKey().equals(dbType)) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user