Ошибки при сравнении вывода текста из JDBC ResultSet - PullRequest
0 голосов
/ 02 мая 2018

Я пытаюсь выполнить пословное сравнение списка строк, возвращаемых из двух баз данных Oracle.

Я попытался сравнить текст с помощью этой библиотеки ( java-diff-utils ).

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

Я пытался удалить специальные символы или обрезать пробелы, но это не влияет на сравниваемые результаты, поэтому я подумал, что, возможно, существует проблема между двумя базами данных, использующими разные NLS_CHARACTERSETS и преобразованием в строки.

Использование select * from NLS_DATABASE_PARAMETERS; Я получаю, что одна база данных использует NLS_CHARACTERSET,AL32UTF8, а другая - NLS_CHARACTERSET,WE8MSWIN1252.

Можно ли стандартизировать вывод текста с помощью getString, который бы учитывал различные кодировки в базе данных? Или есть что-то еще, что я могу упускать из виду?

В настоящее время делаем это:

 List<String> databaseList = new ArrayList<>();
  while (rs.next()) {
    int columnCount = rs.getMetaData().getColumnCount();

    StringBuilder rsStringBuilder = new StringBuilder();


    for (int i = 1; i <= columnCount; i++ ){
        String rsString = null;
        try {
            rsString = rs.getString(i);
        } catch (SQLException e1) {
            e1.printStackTrace();
        }
        rsStringBuilder.append(rsString).append(",");

    }

    databaseList.add(rsStringBuilder.toString());
  }

Затем я бы сравнил результаты базы данных из базы данных 1 с базой данных из базы 2. Я также пытался это стандартизировать информацию, но он возвращает некоторые символы, которые печатаются неправильно, и различия по-прежнему отмечены неправильно в тех же местах:

   for (int i = 1; i <= columnCount; i++) {

          byte[] bytes = rs.getBytes(i);
          String rsString;
          if (bytes != null) {

            rsString = new String(bytes, StandardCharsets.UTF_8);
            rsStringBuilder.append(rsString).append(",");

          } else {

            rsString = "NULLVALUE";
            rsStringBuilder.append(rsString).append(",");
          }

}

Возвращает что-то вроде этого A_C16911,USUMMARY,VARCHAR2,�8,IAMNULL,Y,.
Я подумал об этом после прочтения некоторых других ответов об использовании UTF-8 в качестве стандарта. Любая помощь будет оценена.

1 Ответ

0 голосов
/ 02 мая 2018

Почти наверняка это связано с настройками базы данных NLS_CHARACTERSET; значение набора символов Unicode AL32UTF8 для правой одинарной кавычки равно U+2019; для WE8MSWIN1252 это 0x92.

Возможно, вам придется пройти через массив char [], заполненный из String , и для каждого элемента выполните следующие действия из класса Character: invoke codePointAt (char [] a, int index) вызов, а затем используйте возвращенный int для вызова isAlphabetic (int codePoint) , а затем, возможно, isDigit (int codePoint) , а затем, если любой из них Значение true, сравните с другой базой данных, и если оба значения имеют значение false, вы, вероятно, имеете дело со знаком препинания или символом, которые отличаются в двух наборах символов и, вероятно, могут быть проигнорированы.

Чтобы сделать сравнение более надежным, вы, возможно, захотите проверить isWhitespace (int codePoint) . В качестве распространенной проблемы я вижу, когда люди вырезают и вставляют, скажем, документ Microsoft Word или веб-страницу. это включает неразрывный пробел (U+00A0), а база данных содержит обычный пробел (U+0020). Этот метод также проверяет наличие вкладок, вертикальных вкладок и т. Д.

...