Как сравнить схему между двумя разными пользователями базы данных? - PullRequest
0 голосов
/ 26 июня 2019

Я разрабатываю собственный процессор nifi для сравнения схем двух разных пользователей базы данных в БД Oracle.Таким образом, этот пользовательский процессор nifi сможет проверять схему между различными пользователями БД, где нам нужно выбрать одного пользователя в качестве источника, а другого - в качестве цели.

Если у источника есть таблица, которая недоступна в целевойзатем процессор сгенерирует сценарий создания для этой таблицы. Если у источника и цели есть таблица с одинаковым именем, он будет сравнивать столбцы.

Если исходная таблица имеет имя столбца, которого нет вВ целевой таблице процессор сгенерирует скрипт изменения (ADD).Если присутствуют те же столбцы, он сравнивает тип данных и длину.Если есть несоответствие в типе данных и длине, процессор сгенерирует другое изменение сценария (Изменить).

Для этого я выбрал подход, получив подробности таблицы из таблицы user_tab_columns, он выдаст всеимена столбцов, тип данных, длина данных, точность, масштаб и т.д.Затем я буду сравнивать каждое значение для источника и цели, если есть несоответствие, я выполню необходимые операции.

Я просто хотел знать, есть ли другой подход для выполнения сравнения схемы междуразличные пользователи БД, а также как я могу улучшить текущий подход.

private void validateCurrentTable(XelerateJsonTableDetail currentTable,DataValidationDetails dataValidationDetails) throws SQLException {

    boolean isDataAvailable = true;
    boolean validationFlag;
    List<DataValidationMetaDetails> sourceMetaDetailsList = new ArrayList<DataValidationMetaDetails>();
    List<DataValidationMetaDetails> targetMetaDetailsList = new ArrayList<DataValidationMetaDetails>();

    ResultSet metaDataSource = getColumns(sourceConnection,currentTable.getTableName());

    while(isDataAvailable){
        DataValidationMetaDetails sourceMetaDetails = new DataValidationMetaDetails() ;
        if(!metaDataSource.next()){
            isDataAvailable = false;
        }else{
            sourceMetaDetails.settableName(metaDataSource.getString("TABLE_NAME"));
            sourceMetaDetails.setColumnName(metaDataSource.getString("COLUMN_NAME"));
            sourceMetaDetails.setdataType(metaDataSource.getString("DATA_TYPE"));
            sourceMetaDetails.setdataLength(metaDataSource.getString("DATA_LENGTH"));
            sourceMetaDetails.setdataPrescision(checkNull(metaDataSource.getString("DATA_PRECISION")));
            sourceMetaDetails.setdataScale(checkNull(metaDataSource.getString("DATA_SCALE")));
            if("C".equals(metaDataSource.getString("CHAR_USED"))){
                sourceMetaDetails.setDataCharLength(metaDataSource.getString("CHAR_LENGTH"));
                sourceMetaDetails.setDataCharUsed(metaDataSource.getString("CHAR_USED"));
            }
            sourceMetaDetailsList.add(sourceMetaDetails);
        }
    }

    isDataAvailable = true;
    ResultSet metaDataTarget = getColumns(targetConnection,currentTable.getTableName());

    while(isDataAvailable){
        DataValidationMetaDetails targetMetaDetails = new DataValidationMetaDetails() ;
        if(!metaDataTarget.next()){
            isDataAvailable = false;
        }else{
            targetMetaDetails.settableName(metaDataTarget.getString("TABLE_NAME"));
            targetMetaDetails.setColumnName(metaDataTarget.getString("COLUMN_NAME"));
            targetMetaDetails.setdataType(metaDataTarget.getString("DATA_TYPE"));
            targetMetaDetails.setdataLength(metaDataTarget.getString("DATA_LENGTH"));
            targetMetaDetails.setdataPrescision(checkNull(metaDataTarget.getString("DATA_PRECISION")));
            targetMetaDetails.setdataScale(checkNull(metaDataTarget.getString("DATA_SCALE")));
            if("C".equals(metaDataTarget.getString("CHAR_USED"))){
                targetMetaDetails.setDataCharLength(metaDataTarget.getString("CHAR_LENGTH"));
                targetMetaDetails.setDataCharUsed(metaDataTarget.getString("CHAR_USED"));
            }
            targetMetaDetailsList.add(targetMetaDetails);
        }
    }
    validationFlag = compareSchema(sourceMetaDetailsList,targetMetaDetailsList);
}

private boolean compareSchema(List<DataValidationMetaDetails> sourceMetaDetailsList, List<DataValidationMetaDetails> targetMetaDetailsList) {

    Map<String,DataValidationMetaDetails> schemaMap = new HashMap<String,DataValidationMetaDetails>();
    DataValidationMetaDetails mapMetaDeatils = new DataValidationMetaDetails();

    for(DataValidationMetaDetails metaDeatils : targetMetaDetailsList){
        schemaMap.put(metaDeatils.getColumnName(), metaDeatils);
    }

    for(DataValidationMetaDetails metaDeatils : sourceMetaDetailsList){
        if(null!=schemaMap.get(metaDeatils.getColumnName())){
            mapMetaDeatils = schemaMap.get(metaDeatils.getColumnName());
            if(mapMetaDeatils.getdataType().equals(metaDeatils.getdataType())){
                if(!mapMetaDeatils.getdataLength().equals(metaDeatils.getdataLength())){
                    if(!mapMetaDeatils.getdataPrescision().equals(metaDeatils.getdataPrescision())){
                        if(!mapMetaDeatils.getdataScale().equals(metaDeatils.getdataScale())){
                            String dataTypeMod = "";
                            genAlterModifyScript(metaDeatils,"");
                        }
                    }else{

                    }
                }else{

                    genAlterModifyScript(metaDeatils,"L");
                }
            }else{
                logger.info("Data Type Mismatch for the Column : "+metaDeatils.getColumnName());
            }

        }else{
            genAlterAddScript(metaDeatils);
        }
    }
    return false;
}


private void genAlterModifyScript(DataValidationMetaDetails metaDeatils,String flag) {

    alterModifyQuery.append("\n");
    alterModifyQuery.append("ALTER TABLE ");
    alterModifyQuery.append(metaDeatils.gettableName());
    alterModifyQuery.append(" MODIFY ");
    alterModifyQuery.append(metaDeatils.getColumnName());

    switch(flag){
        case "L" : alterModifyQuery.append("("+metaDeatils.getdataLength()+")");
        break;

        case "P" : alterModifyQuery.append("("+metaDeatils.getdataPrescision()+","+metaDeatils.getdataScale()+")");
        break;

        case "S" : alterModifyQuery.append("("+metaDeatils.getdataPrescision()+","+metaDeatils.getdataScale()+")");
        break;
    }
}

1 Ответ

4 голосов
/ 26 июня 2019

В Oracle вы можете найти несоответствия таблиц между SCHEMA_1 и SCHEMA_2, выполнив что-то вроде:

SELECT *
  FROM DBA_TABLES t1
  WHERE t1.OWNER = 'SCHEMA_1'
MINUS
SELECT *
  FROM DBA_TABLES t2
  WHERE t2.OWNER = 'SCHEMA_2';

Аналогично, чтобы найти несоответствия столбцов, вы можете использовать

SELECT c1.COLUMN_NAME,
       c1.DATA_TYPE
  FROM DBA_TAB_COLS c1
  WHERE c1.OWNER = 'SCHEMA_1' AND
        c1.TABLE_NAME IN (SELECT t2.TABLE_NAME
                            FROM DBA_TABLES t2
                            WHERE t2.OWNER = 'SCHEMA_2')
MINUS
SELECT c2.COLUMN_NAME,
       c2.DATA_TYPE
  FROM DBA_TAB_COLS c2
  WHERE c2.OWNER = 'SCHEMA_2' AND
        c2.TABLE_NAME IN (SELECT t1.TABLE_NAME
                            FROM DBA_TABLES t1
                            WHERE t1.OWNER = 'SCHEMA_1')

Настройте это, чтобы сравнить все, что вы хотели бы сравнить. Вы можете легко распространить это на другие объекты базы данных, запрашивая правильные представления и поля DBA.

Удачи.

...