获取 sql table 的哈希 (sha)

Get a hash (sha) of a sql table

我有时会从一个非常旧的数据库 (MS Access) 中提取大量数据。序列化输出存储为 YAML 文件,这些文件在本地由其他脚本使用以加速该过程。

有时我们通过从数据库中提取(可能的)新数据来更新本地文件。这次提取很长,如果相关 table 的内容与上次提取相同,我想避免它。

是否可以获得 table 或 table 的一部分状态的某种签名?

换句话说,这将有助于理解我的问题:

signature = db.GetSignature('SELECT * FROM foo where bar = 1')
if local_foo.signature != signature:
    local_foo = db.Extract('SELECT * FROM foo where bar = 1')

我可以使用哪些解决方案?

使用触发器

如果 您可以控制原始 Access 数据库的 insert/update/delete 功能,best/safest 解决方案是实施数据库触发器以启用追踪。这样,您至少可以轻松地存储一个 "last modified" 值或保留一个 table 来负责存储大量跟踪信息。

不幸的是,Access 不支持触​​发器(除非您使用的是 2010+,见下文),但您可以在数据库中使用 VBA 实现触发器。

引入了 Access 2010 data macros,但我认为这不是一个选项!

使用脚本语言

如果您不能使用数据库触发器,也许您可​​以使用这样的工作流程:

  1. 执行查询并获得完整结果(单个集合)
  2. 将查询 result/collection 转换为 JSON 字符串(例如 Python 中的 json.dumps()
  3. 获取 JSON 字符串的哈希值(例如 Python 中的 hashlib.sha1() & hashObject.hexdigest()
  4. 将哈希与查询结果的最后存储的哈希进行比较。

使用VBA

为了保持数据库端(避免传输数据),尝试在 Access 数据库中使用 VBA 生成散列可能很有用。

您可以使用此 SO post 中提到的哈希算法代码:

示例:

使用此 SHA1 代码:https://gist.github.com/anonymous/573a875dac68a4af560d

Dim d As DAO.Database
Dim r As DAO.Recordset
Dim s As String
Set d = CurrentDb()
Set r = d.OpenRecordset("SELECT foo, bar, baz FROM foobar")
s = ""
While Not r.EOF
    s = s & r!foo & "," & r!bar & "," & r!baz & ";"
    r.MoveNext
Wend
r.Close
Set r = Nothing
Set d = Nothing
s = SHA1TRUNC(s)