【问题标题】:System Resources Exceeded - Passthrough Query and VBA in Ms Access系统资源超出 - Ms Access 中的直通查询和 VBA
【发布时间】:2018-01-30 15:05:44
【问题描述】:

我编写了以下代码,它将一个 Excel 文件导入 Access 数据库,从中获取所有采购订单号,将它们放入查询条件中,将此条件传递给直通查询,然后执行查询.如果 PO 数量有限,则一切正常,但当 PO 数量很多时,系统在将条件传递给查询定义时会返回错误 System Resources Exceeded。有趣的是,实际的查询条件(无论有多少 PO)确实会传递给查询,但脚本执行会暂停。

考虑到我无法在底层 Oracle 数据库中创建表(理想情况下,我可以使用 PO 编号创建一个表并进行连接),有什么想法可以改进我的脚本并避免此错误吗?

谢谢。

Public Function ImportGoodPOs()
On Error GoTo ImportGoodPOs_Err

'This function imports the spreadsheet with te POs
Dim tbl As String, fd As FileDialog, fn As String, qry As String, tbl1 As String, tbl2 As String, db As DAO.Database, rst As DAO.Recordset, qString As String, qdExtData As QueryDef, qry2 As String, pos As String, sql As String
tbl = "tbl_TempPos"
tbl2 = "tbl_PoNumbers"
qry = "qry_GoodPosWithVendorDetails"
qry2 = "qry_GoodsPosWithVendorDetailsPQ"
tbl1 = "tbl_GoodPosWithVendorDetails"
Set fd = Application.FileDialog(msoFileDialogFilePicker)

fd.AllowMultiSelect = False

MsgBox "Browse for the PO file to import...", vbOKOnly, "Attention!"

If fd.Show = True Then
    If fd.SelectedItems(1) <> vbNullString Then
        fn = fd.SelectedItems(1)
    End If
Else
    'Exit code if no file is selected
    End
End If

DoCmd.SetWarnings False
DoCmd.DeleteObject acTable, tbl
DoCmd.TransferSpreadsheet acImport, , tbl, fn, -1

' setting a dummy query definition to avoid future errors
sql = "SELECT APPS.PO_HEADERS_ALL.SEGMENT1 FROM APPS.PO_HEADERS_ALL WHERE APPS.PO_HEADERS_ALL.SEGMENT1 = '201410377'"
CurrentDb.QueryDefs(qry2).sql = sql

Set rst = CurrentDb.OpenRecordset(tbl)
sql = "SELECT DISTINCT " & tbl & ".[PO Number]"
sql = sql & "INTO " & tbl2 & " "
sql = sql & "FROM " & tbl

DoCmd.RunSQL sql

Set rst = CurrentDb.OpenRecordset(tbl2)

rst.MoveFirst
pos = rst("PO Number")
qString = "(APPS.PO_HEADERS_ALL.SEGMENT1 = '" & pos & "')"

For X = 2 To rst.RecordCount
    rst.MoveNext
    pos = rst("PO Number")
    qString = qString & " OR (APPS.PO_HEADERS_ALL.SEGMENT1 = '" & pos & "')"
Next X

sql = "SELECT APPS.PO_HEADERS_ALL.PO_HEADER_ID, APPS.PO_HEADERS_ALL.SEGMENT1, APPS.AP_SUPPLIER_SITES_ALL.ADDRESS_LINE1, APPS.AP_SUPPLIER_SITES_ALL.ADDRESS_LINES_ALT, APPS.AP_SUPPLIER_SITES_ALL.ADDRESS_LINE2, APPS.AP_SUPPLIER_SITES_ALL.ADDRESS_LINE3, APPS.AP_SUPPLIER_SITES_ALL.CITY, APPS.AP_SUPPLIER_SITES_ALL.STATE, APPS.AP_SUPPLIER_SITES_ALL.ZIP, APPS.AP_SUPPLIER_SITES_ALL.PROVINCE, APPS.AP_SUPPLIER_SITES_ALL.COUNTRY, APPS.AP_SUPPLIER_SITES_ALL.AREA_CODE, APPS.AP_SUPPLIER_SITES_ALL.PHONE, APPS.AP_SUPPLIER_SITES_ALL.FAX, APPS.AP_SUPPLIER_SITES_ALL.FAX_AREA_CODE, APPS.AP_SUPPLIER_SITES_ALL.TELEX, APPS.AP_SUPPLIER_SITES_ALL.PAYMENT_METHOD_LOOKUP_CODE, APPS.AP_SUPPLIER_SITES_ALL.BANK_ACCOUNT_NAME, APPS.AP_SUPPLIER_SITES_ALL.BANK_ACCOUNT_NUM, APPS.AP_SUPPLIER_SITES_ALL.BANK_NUM, APPS.AP_SUPPLIER_SITES_ALL.BANK_ACCOUNT_TYPE, APPS.AP_SUPPLIER_SITES_ALL.TERMS_DATE_BASIS, APPS.AP_SUPPLIER_SITES_ALL.CURRENT_CATALOG_NUM, APPS.AP_SUPPLIER_SITES_ALL.VAT_CODE, "
sql = sql & "APPS.AP_SUPPLIER_SITES_ALL.INVOICE_AMOUNT_LIMIT, APPS.AP_SUPPLIER_SITES_ALL.PAY_DATE_BASIS_LOOKUP_CODE, APPS.AP_SUPPLIER_SITES_ALL.ALWAYS_TAKE_DISC_FLAG, APPS.AP_SUPPLIER_SITES_ALL.INVOICE_CURRENCY_CODE, APPS.AP_SUPPLIER_SITES_ALL.PAYMENT_CURRENCY_CODE, APPS.AP_SUPPLIER_SITES_ALL.HOLD_ALL_PAYMENTS_FLAG, APPS.AP_SUPPLIER_SITES_ALL.HOLD_FUTURE_PAYMENTS_FLAG, APPS.AP_SUPPLIER_SITES_ALL.HOLD_REASON, APPS.AP_SUPPLIER_SITES_ALL.HOLD_UNMATCHED_INVOICES_FLAG, APPS.AP_SUPPLIER_SITES_ALL.AP_TAX_ROUNDING_RULE, APPS.AP_SUPPLIER_SITES_ALL.AUTO_TAX_CALC_FLAG, APPS.AP_SUPPLIER_SITES_ALL.AUTO_TAX_CALC_OVERRIDE, APPS.AP_SUPPLIER_SITES_ALL.AMOUNT_INCLUDES_TAX_FLAG, APPS.AP_SUPPLIER_SITES_ALL.EXCLUSIVE_PAYMENT_FLAG, APPS.AP_SUPPLIER_SITES_ALL.TAX_REPORTING_SITE_FLAG, APPS.AP_SUPPLIER_SITES_ALL.VAT_REGISTRATION_NUM, APPS.AP_SUPPLIER_SITES_ALL.OFFSET_VAT_CODE, APPS.AP_SUPPLIER_SITES_ALL.CHECK_DIGITS, APPS.AP_SUPPLIER_SITES_ALL.BANK_NUMBER, APPS.AP_SUPPLIER_SITES_ALL.ADDRESS_LINE4, "
sql = sql & "APPS.AP_SUPPLIER_SITES_ALL.COUNTY, APPS.AP_SUPPLIER_SITES_ALL.ADDRESS_STYLE, APPS.AP_SUPPLIER_SITES_ALL.EDI_TRANSACTION_HANDLING, APPS.AP_SUPPLIER_SITES_ALL.EDI_ID_NUMBER, APPS.AP_SUPPLIER_SITES_ALL.EDI_PAYMENT_METHOD, APPS.AP_SUPPLIER_SITES_ALL.EDI_PAYMENT_FORMAT, APPS.AP_SUPPLIER_SITES_ALL.EDI_REMITTANCE_METHOD, APPS.AP_SUPPLIER_SITES_ALL.BANK_CHARGE_BEARER, APPS.AP_SUPPLIER_SITES_ALL.EDI_REMITTANCE_INSTRUCTION, APPS.AP_SUPPLIER_SITES_ALL.BANK_BRANCH_TYPE, APPS.AP_SUPPLIER_SITES_ALL.PAY_ON_CODE, APPS.AP_SUPPLIER_SITES_ALL.DEFAULT_PAY_SITE_ID, APPS.AP_SUPPLIER_SITES_ALL.PAY_ON_RECEIPT_SUMMARY_CODE, APPS.AP_SUPPLIER_SITES_ALL.PCARD_SITE_FLAG, APPS.AP_SUPPLIER_SITES_ALL.MATCH_OPTION, APPS.AP_SUPPLIER_SITES_ALL.COUNTRY_OF_ORIGIN_CODE, APPS.AP_SUPPLIER_SITES_ALL.FUTURE_DATED_PAYMENT_CCID, APPS.AP_SUPPLIER_SITES_ALL.CREATE_DEBIT_MEMO_FLAG, APPS.AP_SUPPLIER_SITES_ALL.OFFSET_TAX_FLAG, APPS.AP_SUPPLIER_SITES_ALL.SUPPLIER_NOTIF_METHOD, APPS.AP_SUPPLIER_SITES_ALL.EMAIL_ADDRESS, "
sql = sql & "APPS.AP_SUPPLIER_SITES_ALL.REMITTANCE_EMAIL, APPS.AP_SUPPLIER_SITES_ALL.PRIMARY_PAY_SITE_FLAG, APPS.AP_SUPPLIER_SITES_ALL.SHIPPING_CONTROL, APPS.AP_SUPPLIER_SITES_ALL.SELLING_COMPANY_IDENTIFIER, APPS.AP_SUPPLIER_SITES_ALL.GAPLESS_INV_NUM_FLAG, APPS.AP_SUPPLIER_SITES_ALL.DUNS_NUMBER, APPS.AP_SUPPLIER_SITES_ALL.RETAINAGE_RATE, APPS.AP_SUPPLIER_SITES_ALL.TCA_SYNC_STATE, APPS.AP_SUPPLIER_SITES_ALL.TCA_SYNC_PROVINCE, APPS.AP_SUPPLIER_SITES_ALL.TCA_SYNC_COUNTY, APPS.AP_SUPPLIER_SITES_ALL.TCA_SYNC_CITY, APPS.AP_SUPPLIER_SITES_ALL.TCA_SYNC_ZIP, APPS.AP_SUPPLIER_SITES_ALL.TCA_SYNC_COUNTRY, APPS.AP_SUPPLIER_SITES_ALL.PAY_AWT_GROUP_ID, APPS.AP_SUPPLIER_SITES_ALL.CAGE_CODE, APPS.AP_SUPPLIER_SITES_ALL.LEGAL_BUSINESS_NAME, APPS.AP_SUPPLIER_SITES_ALL.DOING_BUS_AS_NAME, APPS.AP_SUPPLIER_SITES_ALL.DIVISION_NAME, APPS.AP_SUPPLIER_SITES_ALL.SMALL_BUSINESS_CODE, APPS.AP_SUPPLIER_SITES_ALL.CCR_COMMENTS, APPS.AP_SUPPLIER_SITES_ALL.DEBARMENT_START_DATE, APPS.AP_SUPPLIER_SITES_ALL.DEBARMENT_END_DATE "
sql = sql & "FROM APPS.PO_HEADERS_ALL INNER JOIN APPS.AP_SUPPLIER_SITES_ALL ON (APPS.PO_HEADERS_ALL.VENDOR_ID = APPS.AP_SUPPLIER_SITES_ALL.VENDOR_ID AND APPS.PO_HEADERS_ALL.VENDOR_SITE_ID = APPS.AP_SUPPLIER_SITES_ALL.VENDOR_SITE_ID) "
sql = sql & "WHERE " & qString

qString = ""

CurrentDb.QueryDefs(qry2).sql = sql

sql = ""

DoCmd.OpenQuery qry2, acViewNormal, acEdit
DoCmd.OpenQuery qry, acViewNormal, acEdit
DoCmd.Close acQuery, qry2, acSaveYes
DoCmd.Close acQuery, qry, acSaveYes
DoCmd.OpenTable tbl1, acViewNormal, acEdit
DoCmd.SetWarnings True

【问题讨论】:

  • 您真的需要返回所有这些字段吗?你试过APPS.PO_HEADERS_ALL.SEGMENT1 IN (&lt;your first query&gt;)吗? (而不是读取一个查询的结果来编写一个可能很大的第二个查询?)
  • 像 matBailie 说的那样尝试 IN (1,2,..)。此行也没有任何意义: Set rst = CurrentDb.OpenRecordset(tbl)
  • 感谢两位的回复。我已经尝试过 IN,当 PO 的数量很大时它不起作用。 IN 子句对字符数有限制。不幸的是,我确实需要返回所有这些字段。
  • 要尝试的事情:(1)只是为了限制查询SQL:使用表别名。在 SELECT 和 WHERE 子句中使用它们。 qString = qString &amp; " OR (h.SEGMENT1 = '" &amp; pos &amp; "')"
  • (3) 向 $Manager$ 解释您需要在 Oracle 中为 PO 编号创建一个新表。

标签: sql ms-access vba


【解决方案1】:

您是否尝试过使用 ODBC 链接到 Oracle APPS.PO_HEADERS_ALLAPPS.AP_SUPPLIER_SITES_ALL 表?您应该有权执行此操作。这将绕过与直通查询相关的问题。只需将 ODBC 链接表连接到您从 Excel 导出的采购订单编号表。

(原答案) 我认为 Andre 解决了这个问题:Barattolo_67 报告查询的长度为 335,229 个字符。访问规范说最大查询大小约为 64,000 个字符。所以 Barattolo_67 显然超过了这个限制,这很可能是 System Resources Exceeded 错误的原因。

请注意,查询只返回 89 个字段,所以这不是问题。查询的 SELECT 部分只有 4,000 个字符长。最大的问题是WHERE 子句,它又增加了 300,000 个字符。

【讨论】:

  • MatBailie,感谢您的澄清。现在我得到了你的建议。我明天在办公室试试。
  • MatBailie,我已经尝试过 IN 建议,但我遇到了问题,因为第二个查询是直通查询,而第一个查询是本地查询。当我将第一个查询放入第二个查询时,Access 告诉我我的表名无效,因为它正在服务器上查找本地表。或者至少,这是我的结论。
  • 我无法对其进行测试,但我怀疑您无法将 Access 本地表连接到直通查询。您的选择包括: 1) 获得创建包含您需要的 PO 的 Oracle 本地表的权限。创建一个返回所需 89 列的视图。 2)回到你原来的本地表函数,全部在Access中完成
  • kismer,谢谢您的回复。我已经对其进行了测试,并且可以确认您无法将 Access 表加入到直通查询中。在 Access 中完成这一切会使整个事情变得太慢,因此我会避免。
  • 当然,您可以将 Access 表连接到 Pass-Through 查询。创建一个新查询,添加表和 Pass-Through 查询,创建联接。完毕。您不能做的是使用 Access inside Pass-Through 查询中的任何本地内容。它的 SQL 按原样发送到 DB 服务器,显然不知道任何本地 Access 对象。
猜你喜欢
  • 2021-10-03
  • 1970-01-01
  • 2013-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-11
相关资源
最近更新 更多