绕过日志记录事务
Bypass transaction for logging
我正在将数据从 Excel 导入到 Access。在导入过程中,我对其进行了验证,并且只插入了正常的行。错误记录到另一个 table 中,稍后由报告使用。导入是使用 VBA 宏手动完成的。我用CurentDb.OpenRecordset
写字
当前解决方案:仅有效数据+保留日志
- 我从Excel逐行导入数据,导入后保存在数据库中。即使我在其他行中发现错误。
- 同时我将错误记录到另一个table。
期望的解决方案:全有或全无 + 保留日志
- 仅当所有数据都有效时才提交导入的数据。
- 当导入的数据回滚以显示报告时,也保留错误日志。
问题
当我回滚导入的数据时,日志也被回滚,所以我不能用它来报告。
问题
有没有办法绕过导入事务,让日志一直写?
您可以创建多个工作区和相应的数据库对象,它们具有单独的事务,即使在当前打开的数据库上也是如此。请注意,如果您对数据库有独占锁,这将不起作用。
Dim wsLog As DAO.Workspace
Dim wsImport As DAO.Workspace
Dim dbImport As DAO.Database
Dim dbLog As DAO.Database
Dim dbe As DAO.DBEngine
Set dbe = DBEngine
Set wsLog = dbe.CreateWorkspace("wsLog", "Admin", "")
Set wsImport = dbe.CreateWorkspace("wsImport", "Admin", "")
Set dbLog = wsLog.OpenDatabase(CurrentProject.FullName)
Set dbImport = wsImport.OpenDatabase(CurrentProject.FullName)
wsImport.BeginTrans
dbImport.Execute "INSERT INTO Table1(Field1) VALUES(1)" 'Do your imports/processing in this workspace
wsLog.BeginTrans
dbLog.Execute "INSERT INTO Table2(Field1) VALUES(1)" 'And logging here
wsLog.CommitTrans 'Commit log
wsImport.Rollback 'Rollback import afterwards
'Result: Table2 is changed, Table1 isn't
请注意,虽然不需要使用单独的日志数据库,但如果您使用 Access 进行存储,我建议您这样做。
而且,如评论中所述,您也可以使用临时 table。
您使用 CreateTableDef
和 dbHiddenObject
常量创建了一个永久不可见的 table 供临时使用:
CreateTableDef("TableName", dbHiddenObject)
它不会自动删除,所以从这个意义上说它不是临时的。请记住,删除+重新创建临时 tables 会增加数据库大小,可能需要更紧凑的操作。
我正在将数据从 Excel 导入到 Access。在导入过程中,我对其进行了验证,并且只插入了正常的行。错误记录到另一个 table 中,稍后由报告使用。导入是使用 VBA 宏手动完成的。我用CurentDb.OpenRecordset
写字
当前解决方案:仅有效数据+保留日志
- 我从Excel逐行导入数据,导入后保存在数据库中。即使我在其他行中发现错误。
- 同时我将错误记录到另一个table。
期望的解决方案:全有或全无 + 保留日志
- 仅当所有数据都有效时才提交导入的数据。
- 当导入的数据回滚以显示报告时,也保留错误日志。
问题
当我回滚导入的数据时,日志也被回滚,所以我不能用它来报告。
问题
有没有办法绕过导入事务,让日志一直写?
您可以创建多个工作区和相应的数据库对象,它们具有单独的事务,即使在当前打开的数据库上也是如此。请注意,如果您对数据库有独占锁,这将不起作用。
Dim wsLog As DAO.Workspace
Dim wsImport As DAO.Workspace
Dim dbImport As DAO.Database
Dim dbLog As DAO.Database
Dim dbe As DAO.DBEngine
Set dbe = DBEngine
Set wsLog = dbe.CreateWorkspace("wsLog", "Admin", "")
Set wsImport = dbe.CreateWorkspace("wsImport", "Admin", "")
Set dbLog = wsLog.OpenDatabase(CurrentProject.FullName)
Set dbImport = wsImport.OpenDatabase(CurrentProject.FullName)
wsImport.BeginTrans
dbImport.Execute "INSERT INTO Table1(Field1) VALUES(1)" 'Do your imports/processing in this workspace
wsLog.BeginTrans
dbLog.Execute "INSERT INTO Table2(Field1) VALUES(1)" 'And logging here
wsLog.CommitTrans 'Commit log
wsImport.Rollback 'Rollback import afterwards
'Result: Table2 is changed, Table1 isn't
请注意,虽然不需要使用单独的日志数据库,但如果您使用 Access 进行存储,我建议您这样做。
而且,如评论中所述,您也可以使用临时 table。
您使用 CreateTableDef
和 dbHiddenObject
常量创建了一个永久不可见的 table 供临时使用:
CreateTableDef("TableName", dbHiddenObject)
它不会自动删除,所以从这个意义上说它不是临时的。请记住,删除+重新创建临时 tables 会增加数据库大小,可能需要更紧凑的操作。