我试图通过两个Oracle数据库返回的字符串列表进行单词比较。
我尝试使用此库(java-diff-utils)比较文本。
在比较文本输出时,我遇到了不一致的结果。我打开的一个问题There is a longer description here,但似乎错误可能是数据库上数据编码的结果。
我尝试删除特殊字符或修剪空格,但它似乎不会影响比较结果,所以我想可能使用不同的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中的databaseList与数据库2中的databaseList的结果进行比较。 我也尝试过这样做来标准化信息,但它会返回一些无法正确打印的字符,并且差异在同一位置仍然标记错误:
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作为标准的其他一些答案后,我想到了这个。任何帮助,将不胜感激。
答案 0 :(得分:0)
几乎可以肯定,这是由数据库的NLS_CHARACTERSET设置引起的;右侧单引号’
的Unicode AL32UTF8字符集值为U+2019
;对于WE8MSWIN1252,它是0x92
。
您可能必须碰到从String填充的char []数组,并且对于每个元素,从Character类执行以下操作:调用codePointAt(char[] a, int index)调用,然后使用返回的{ {1}}调用isAlphabetic(int codePoint),然后调用isDigit(int codePoint)然后如果其中任何一个为真,则与其他数据库进行比较,如果两者都为假,则可能正在处理标点符号或两个字符集中不同的符号,可能会被忽略。
为了使您的比较更加强大,您可能还需要检查isWhitespace(int codePoint)作为一个常见问题,我看到的是当人们剪切和粘贴时说出Microsoft Word文档或包含非破坏性的网页space(int
)和数据库包含一个常规空格(U+00A0
)。该方法还会检查制表符,垂直制表符等。