访问VBA DAO | MakeTable查询上的ADO膨胀数据库

时间:2016-11-07 16:36:39

标签: vba ms-access access-vba dao

我有一个过程,每天三次从Oracle数据更新Access数据库以获取最新信息。目前的生产过程包括:

  • 创建最新数据的新访问表(t1)
  • 将以前版本的数据移至备份版本(t至t2)
  • 将当前数据移至主表(t1至t)

以这种方式完成的原因是当前数据失败,用户仍然可以访问早期版本的数据,直到我们可以对当前数据进行故障排除或直到下一次运行。

我们继承了许多进程,并且我正在重构该进程,因此我们可以捕获并警告错误,并在早期进程失败时阻止下游进程运行。

我使用DAO开发了以下函数,以便我可以利用Execute来捕获错误并优雅地退出整个过程。但是,这个过程使数据库大大膨胀,在我的所有搜索中,我无法找到解决方法。我所做的大部分研究都指向清除DAO.RecordsetsDAO.QueryDefs,我在DDL语句中都没有处理过。{1}}和DoCmd.RunSQL。我也用ADO创建了一个类似的函数,但同样的问题仍然存在。

有没有办法在执行后从这些语句中清除Access中创建的临时内存,这样代码可以继续而不会使DB增长超过2GB大小限制?或者也许最好使用GoTo运行查询并使用Function ExecuteSQL(db As DAO.Database, sQuery As String) As Boolean '******************************************************************* '** Sub: ExecuteSQL '** Purpose: Stores current copy of Daily Eff Date table from Daily Eff Table1 and backs up previous version in Daily Eff Date2 '** Notes: Requires reference to Microsoft DAO 3.6 Object Library (or equivalent) '******************************************************************* Dim wSpace As DAO.Workspace Set wSpace = DBEngine.Workspaces(0) On Error GoTo ErrHandler With wSpace .BeginTrans db.Execute sQuery, dbFailOnError .CommitTrans ExecuteSQL = True End With LeaveExecuteSQL: wSpace.Close Exit Function ErrHandler: wSpace.Rollback Resume LeaveExecuteSQL End Function 构建错误捕获。我想避免这种情况,但如果这是唯一的方法就会解决这个问题。

以下功能:

If Not ExecuteSQL(CurrentDb, "Daily Sub ALL") Then 'Bring Submission Data into Access

    strSubject = "ERROR in Creating The Daily Effective Date Table"
    GoTo LeaveRunProcess

End If

以下是如何调用Function的示例。

Daily Sub ALL

以下是SELECT PRODCT_EFF_DT, Left([DWCFEUL5_DEV_SUB_RPT_STATUS_SUBM_ALL_NM]![PRODUCT_SIC_CD],4) AS Expr1, Left([PRODUCT_SIC_CD],4) AS [SIC Short], INS_RQMT_PRODCT_NO, CMPNY_REGN_NM, PROCESSING_REGION, PROCESSING_RGN_NM, CMPNY_CD, CMPNY_NM, PUC_NAME, UW_REGION_NAME, PUC_NO, CLIENT_NAME, CLIENT_NUMBER, ACCOUNT_NUMBER, DUNS_NUMBER, DUNS_PARENT, PRODUCER_NUMBER, PRODUCER_NAME, PRODUCER_CONTACT, PRODCR_CNTCT_PRSN_NO, PRODUCT_TYPE, BRANCH_TYPE, BRANCH_NAME, DEPT_NO, NEW_DEPT_NO, DEPT_CD, DEPT_NM, NEW_DEPT_NM, NEW_PRFT_CENTR_NO, PROFT_CNTR_NM, NEW_PRFT_CENTR_NM, EXP_POLICY_NO, EXPPOLICYNO10, POLICY_NO, POLICYNO10, PRODCT_ATCHMT_PNT_AMT, DED_AMT, LMT_AMT, PRODCT_EXP_DT, QUOTE_BY_DT, PRODCT_DESIRBLTY, NEW_PRODCR_NM, PRODCT_SUCCESS_CHNC, WIN_CARR_NAME, INCUMBENT_INS_CARR, PRODCT_EFF_MONTH, LINE_OF_BUSINESS, PRODCT_NO, PROFIT_CENTER, EXP_PREMIUM, UNDERWRITER_NAME, EMPL_ID, STATE, LAST_UPDT_TS, PREM_AMT, DT_RECEIVED, DT_RESERVED, DT_ASSIGNED, DT_WORKING, DT_QUOTED, DT_BOUND, DT_ISSUED, DT_BOOKED, DT_MAILED, DT_DECLINED, DT_QUOTE_NOT_WRITTEN, CURR_STATUS, CURR_STATUS_CD, CURR_STATUS_CHG_USR, CURR_STATUS_EFF_DT, UW_ASISTANT_NAME, COMPANY_TYPE, CREATE_DT, CREATE_USR, PRM_FINCG_IND, BNKRPCY_STAT_CD, BRKR_MNSCRPT_FORMS_IND, UNDLYG_CNF_WRITN_IND, PRODUCT_SIC_CD, ACCT_SIC, ACCT_SIC_DESC, ACCT_SIC_PCT, PROG_TYP_CD, EXT_REPT_IND, MOT_TRK_LIAB_FIL, MOT_TRK_CRG_FIL, SUBJ_TO_AUDIT, COMP_RATED_IND, CONSENT_TO_RATE, IND_RISK_RATING, NY_FREE_TRD_ZONE, EPOL_DELIVERED, PAYDEX_SCORE, CREDIT_SCORE, FINANCIAL_STRESS_SCORE, YEARS_IN_BUSINESS, DNB_NO, DNB_NAME, DNB_PARENT_NO, DNB_HEADQUARTERS_NO, DNB_ADDRESS_LINE1, DNB_ADDRESS_LINE2, DNB_ZIPCODE, DNB_CITY, DNB_STATE, DNB_COUNTRY_CODE, COMMERCIAL_CREDIT_SCORE, START_YEAR, CURRENT_CONTROL_YEAR, NAICS_CODE, INSRD_NM, PRODCR_LONG_NAME, SIR_AMOUNT, EMAIL_ADDRS_TXT, SUB_PRODUCER_NO, SUB_PRODUCER_CODE, SUB_PRODUCER_NM, SUB_PRODUCER_ADDRESS_LINE1, SUB_PRODUCER_ADDRESS_LINE2, SUB_PRODUCER_ADDRESS_LINE3, SUB_PRODUCER_CITY, SUB_PRODUCER_STATE, SUB_PRODUCER_ZIPCODE, PRODUCER_PHONE_NO, SHOPPING, ASSOC_NO, VIABILITY_SCORE, POLICY_ISSUED_BY, ASSOCIATE_UW, FEIN_N0, PRODUCER_FEIN INTO [Daily Eff Date1] FROM DWCFEUL5_DEV_SUB_RPT_STATUS_SUBM_ALL_NM WHERE (((PRODCT_EFF_DT)>#1/1/2015#) AND ((NEW_PRFT_CENTR_NM) Not Like "Hawaii")); 的SQL:

Dictionary<string, Task<object>> router = new Dictionary<string, Task<object>();
router["xyz"] = functionToLaterExec

async Task<string> functionToLaterExec()
{
    return await Task.FromResult("Success!");
} 

3 个答案:

答案 0 :(得分:2)

不是对评论的回答

Option Compare Database

Private WithEvents conCUSTOM_CONNECTION As ADODB.CONNECTION

Public Event evtEXECUTEERROR(ByVal pError As ADODB.Error)
Public Event evtEXECUTESUCCESS()

Public Sub INITIALISE_CONNECTION(con As ADODB.CONNECTION)
    Set conCUSTOM_CONNECTION = con
End Sub

Private Sub conCUSTOM_CONNECTION_ExecuteComplete(ByVal RecordsAffected As Long, _
                    ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, _
                    ByVal pCommand As ADODB.Command, ByVal pRecordset As ADODB.Recordset, _
                    ByVal pConnection As ADODB.CONNECTION)
    If pError Is Nothing Then
        RaiseEvent evtEXECUTESUCCESS
    Else
        RaiseEvent evtEXECUTEERROR(pError)
    End If
End Sub

答案 1 :(得分:1)

我遇到了同样的问题,即我的数据库在原始数据导入时膨胀。 VBA不允许致电Compact&amp;修复非拆分数据库。我决定使用数据库对象(DAO)创建临时数据库,导入数据,从该临时数据库查询原始数据库,然后删除临时数据库,而不是分割数据库并压缩后端。基本代码如下所示:

Sub tempAccessDatabaseImport()
    Dim mySQL As String
    Dim tempDBPath As String
    Dim myWrk As DAO.Workspace
    Dim tempDB As DAO.Database
    Dim myObject

    'Define temp access database path
    tempPathArr = Split(Application.CurrentProject.Path, "\")
    For i = LBound(tempPathArr) To UBound(tempPathArr)
        tempDBPath = tempDBPath + tempPathArr(i) + "\"
    Next i
    tempDBPath = tempDBPath + "tempDB.accdb"

    'Delete temp access database if exists
    Set myObject = CreateObject("Scripting.FileSystemObject")
    If myObject.FileExists(tempDBPath) Then
        myObject.deleteFile (tempDBPath)
    End If

    'Open default workspace
    Set myWrk = DBEngine.Workspaces(0)

    'DAO Create database
    Set tempDB = myWrk.CreateDatabase(tempDBPath, dbLangGeneral)

    'DAO - Import temp xlsx into temp Access table
    mySQL = "SELECT * INTO tempTable FROM (SELECT vXLSX.*FROM [Excel 12.0;HDR=YES;DATABASE=" & RAWDATAPATH & "].[" & WORKSHEETNAME & "$] As vXLSX)"

    'DAO Execute SQL
    Debug.Print mySQL
    Debug.Print
    tempDB.Execute mySQL, dbSeeChanges

    'Do Something Else

    'Close DAO Database object
    tempDB.Close
    Set tempDB = Nothing

    myWrk.Close
    Set myWrk = Nothing

    'Delete temp access database if exists
    If myObject.FileExists(tempDBPath) Then
        'myObject.deleteFile (tempDBPath)
    End If
End Sub

答案 2 :(得分:0)

这可能只是一个评论,但我没有这方面的特权。

“压缩和修复”数据库将有助于解决尺寸问题。您可以使用Access可视化界面定期或以编程方式执行此操作: https://msdn.microsoft.com/en-us/library/office/bb220986(v=office.12).aspx

压缩文件(仅适用于NTFS)将减少占用的物理硬盘空间(与ZIP或RAR一样),同时提高硬盘访问的速度(硬盘更少旋转,读取的字节更少) )。您甚至可以将NTFS压缩应用于网络共享上的文件。

就在今天,我通过简单地将所有对象(它只包含表)复制到新的数据库文件来进一步减小Access数据库的大小。所以即使我已经压缩它,它也会变小几倍。

我说这只是一个评论,因为它只会有所帮助,而不是以各种方式解决问题的每一方面。

如果可以的话,使用追加查询而不是制作表格也可能值得尝试。