如果问题是检查两个表的身份,即答案是yes - 表包含
相同的数据或no - 有区别,还有另一种方法,在关系数据库中不太常见,
但最先进的文件。
这与检查下载文件的“正确性”(即与原始文件的身份)相同的方法
使用哈希码。如果您看到相同的哈希码,则答案是 yes 您拥有正确的文件。
如何将这种方法转换为关系数据库?
Oracle 提供函数standard_hash 计算字符串的MD5 哈希码
select standard_hash('foo bar', 'MD5') hash_code from dual;
HASH_CODE
--------------------------------
327B6F07435811239BC47E1544353273
因此您可以比较列值。
函数standard_hash 也适用于CLOBs,所以(理论上)你可以连接
列和行并计算整个表的哈希码。但这不是正确的方法,请记住
文件的哈希码是通过组合行的哈希码递增计算的。
这里是如何使用Java类java.security.MessageDigest计算MD5哈希码的演示
我正在使用 Groovy 脚本,因为不幸的是,这在 PL/SQL 中是不可能的。
MessageDigest digest = MessageDigest.getInstance("MD5")
byte[] md5hash
groovyCon.eachRow ('select txt from MY_TABLE order by id')
{
digest.update(it.txt.getBytes(StandardCharsets.UTF_8))
}
md5hash = digest.digest();
println md5hash.encodeHex().toString()
脚本启动哈希码,然后遍历行和updates 哈希码,最后
将其预设为字符串。这是处理文件时的典型方法,其中行的顺序很重要。在关系表中
订单未定义。您认为该表与 (A,B,C) 和 (C,B,A) 相同。
请参阅here 讨论如何使用XOR 将哈希码组合成与顺序无关的事项。
这里是两个字符串的哈希码组合的例子
select UTL_RAW.BIT_XOR(standard_hash('foo', 'MD5'), standard_hash('bar', 'MD5')) hash_code from dual;
HASH_CODE
--------------------------------
9B0805C206B7EBB8B6B9931D83E9F52A
这种方法有一个很大的优势,它可以使用 PL/SQL 来实现。请参阅此处的示例
PL/SQL 的实现aggregate function MD5_XOR 计算整个表的 MD5 哈希码。
select MD5_XOR(txt) hash_code, count(*) cnt
from MY_TABLE;
HASH_CODE CNT
-------------------------------- -------
173F1F8F85F1A154044B7629A23E949C 102
当然你也可以把参数串联起来计算整张表的哈希码
select MD5_XOR(to_char(id)||COL_TXT|| to_char(COL_DATE,'dd.mm.yyyy hh24:mi:ss')) md5 from MY_TABLE;
或者您可以对表格的某些部分使用GROUP BY,看看哪些组是相同的,哪些是不同的。
好多了,如果这个聚合函数由Oracle原生实现,性能会大放异彩,会好很多
使用基于集合操作的SQL比较(需要对表进行排序)。 XOR 组合不需要
sort 并具有O(N) 复杂性,但用户实现会受到上下文切换的影响。
请参阅here 使其成为 Oracle 本地实现的想法。