Marco Balestra
asked on
System Resource Exceeded
I have written the below code, which works fine until it has to pass the sql code to the query definition (CurrentDb.QueryDefs(qry2) .sql = sql), as then I get a "System Resource Exceeded" error. In the example I am testing, the number of OR clauses in qString will be 131. Any ideas?
Thank you.
-------------------------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
Public Function ImportServicePOs()
On Error GoTo ImportServicePOs_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_ServicePosWithVendorD etails"
qry2 = "qry_ServicePosWithVendorD etailsPQ"
tbl1 = "tbl_ServicePosWithVendorD etails"
Set fd = Application.FileDialog(mso FileDialog FilePicker )
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
Set rst = CurrentDb.OpenRecordset(tb l)
sql = "SELECT DISTINCT " & tbl & ".[PO Number]"
sql = sql & "INTO " & tbl2 & " "
sql = sql & "FROM " & tbl
DoCmd.RunSQL sql
Set rst = CurrentDb.OpenRecordset(tb l2)
rst.MoveFirst
pos = rst("PO Number")
qString = "(APPS.PO_HEADERS_ALL.SEGM ENT1 = '" & pos & "')"
For X = 2 To rst.RecordCount
rst.MoveNext
pos = rst("PO Number")
qString = qString & " OR (APPS.PO_HEADERS_ALL.SEGME NT1 = '" & pos & "')"
Next X
sql = "SELECT APPS.PO_HEADERS_ALL.PO_HEA DER_ID, APPS.PO_HEADERS_ALL.SEGMEN T1, APPS.AP_SUPPLIER_SITES_ALL .ADDRESS_L INE1, APPS.AP_SUPPLIER_SITES_ALL .ADDRESS_L INES_ALT, APPS.AP_SUPPLIER_SITES_ALL .ADDRESS_L INE2, APPS.AP_SUPPLIER_SITES_ALL .ADDRESS_L INE3, 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_M ETHOD_LOOK UP_CODE, APPS.AP_SUPPLIER_SITES_ALL .BANK_ACCO UNT_NAME, APPS.AP_SUPPLIER_SITES_ALL .BANK_ACCO UNT_NUM, APPS.AP_SUPPLIER_SITES_ALL .BANK_NUM, APPS.AP_SUPPLIER_SITES_ALL .BANK_ACCO UNT_TYPE, APPS.AP_SUPPLIER_SITES_ALL .TERMS_DAT E_BASIS, APPS.AP_SUPPLIER_SITES_ALL .CURRENT_C ATALOG_NUM , APPS.AP_SUPPLIER_SITES_ALL .VAT_CODE, "
sql = sql & "APPS.AP_SUPPLIER_SITES_AL L.INVOICE_ AMOUNT_LIM IT, APPS.AP_SUPPLIER_SITES_ALL .PAY_DATE_ BASIS_LOOK UP_CODE, APPS.AP_SUPPLIER_SITES_ALL .ALWAYS_TA KE_DISC_FL AG, APPS.AP_SUPPLIER_SITES_ALL .INVOICE_C URRENCY_CO DE, APPS.AP_SUPPLIER_SITES_ALL .PAYMENT_C URRENCY_CO DE, APPS.AP_SUPPLIER_SITES_ALL .HOLD_ALL_ PAYMENTS_F LAG, APPS.AP_SUPPLIER_SITES_ALL .HOLD_FUTU RE_PAYMENT S_FLAG, APPS.AP_SUPPLIER_SITES_ALL .HOLD_REAS ON, APPS.AP_SUPPLIER_SITES_ALL .HOLD_UNMA TCHED_INVO ICES_FLAG, APPS.AP_SUPPLIER_SITES_ALL .AP_TAX_RO UNDING_RUL E, APPS.AP_SUPPLIER_SITES_ALL .AUTO_TAX_ CALC_FLAG, APPS.AP_SUPPLIER_SITES_ALL .AUTO_TAX_ CALC_OVERR IDE, APPS.AP_SUPPLIER_SITES_ALL .AMOUNT_IN CLUDES_TAX _FLAG, APPS.AP_SUPPLIER_SITES_ALL .EXCLUSIVE _PAYMENT_F LAG, APPS.AP_SUPPLIER_SITES_ALL .TAX_REPOR TING_SITE_ FLAG, APPS.AP_SUPPLIER_SITES_ALL .VAT_REGIS TRATION_NU M, APPS.AP_SUPPLIER_SITES_ALL .OFFSET_VA T_CODE, APPS.AP_SUPPLIER_SITES_ALL .CHECK_DIG ITS, APPS.AP_SUPPLIER_SITES_ALL .BANK_NUMB ER, APPS.AP_SUPPLIER_SITES_ALL .ADDRESS_L INE4, "
sql = sql & "APPS.AP_SUPPLIER_SITES_AL L.COUNTY, APPS.AP_SUPPLIER_SITES_ALL .ADDRESS_S TYLE, APPS.AP_SUPPLIER_SITES_ALL .EDI_TRANS ACTION_HAN DLING, APPS.AP_SUPPLIER_SITES_ALL .EDI_ID_NU MBER, APPS.AP_SUPPLIER_SITES_ALL .EDI_PAYME NT_METHOD, APPS.AP_SUPPLIER_SITES_ALL .EDI_PAYME NT_FORMAT, APPS.AP_SUPPLIER_SITES_ALL .EDI_REMIT TANCE_METH OD, APPS.AP_SUPPLIER_SITES_ALL .BANK_CHAR GE_BEARER, APPS.AP_SUPPLIER_SITES_ALL .EDI_REMIT TANCE_INST RUCTION, APPS.AP_SUPPLIER_SITES_ALL .BANK_BRAN CH_TYPE, APPS.AP_SUPPLIER_SITES_ALL .PAY_ON_CO DE, APPS.AP_SUPPLIER_SITES_ALL .DEFAULT_P AY_SITE_ID , APPS.AP_SUPPLIER_SITES_ALL .PAY_ON_RE CEIPT_SUMM ARY_CODE, APPS.AP_SUPPLIER_SITES_ALL .PCARD_SIT E_FLAG, APPS.AP_SUPPLIER_SITES_ALL .MATCH_OPT ION, APPS.AP_SUPPLIER_SITES_ALL .COUNTRY_O F_ORIGIN_C ODE, APPS.AP_SUPPLIER_SITES_ALL .FUTURE_DA TED_PAYMEN T_CCID, APPS.AP_SUPPLIER_SITES_ALL .CREATE_DE BIT_MEMO_F LAG, APPS.AP_SUPPLIER_SITES_ALL .OFFSET_TA X_FLAG, APPS.AP_SUPPLIER_SITES_ALL .SUPPLIER_ NOTIF_METH OD, APPS.AP_SUPPLIER_SITES_ALL .EMAIL_ADD RESS, "
sql = sql & "APPS.AP_SUPPLIER_SITES_AL L.REMITTAN CE_EMAIL, APPS.AP_SUPPLIER_SITES_ALL .PRIMARY_P AY_SITE_FL AG, APPS.AP_SUPPLIER_SITES_ALL .SHIPPING_ CONTROL, APPS.AP_SUPPLIER_SITES_ALL .SELLING_C OMPANY_IDE NTIFIER, APPS.AP_SUPPLIER_SITES_ALL .GAPLESS_I NV_NUM_FLA G, APPS.AP_SUPPLIER_SITES_ALL .DUNS_NUMB ER, 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_G ROUP_ID, APPS.AP_SUPPLIER_SITES_ALL .CAGE_CODE , APPS.AP_SUPPLIER_SITES_ALL .LEGAL_BUS INESS_NAME , APPS.AP_SUPPLIER_SITES_ALL .DOING_BUS _AS_NAME, APPS.AP_SUPPLIER_SITES_ALL .DIVISION_ NAME, APPS.AP_SUPPLIER_SITES_ALL .SMALL_BUS INESS_CODE , APPS.AP_SUPPLIER_SITES_ALL .CCR_COMME NTS, APPS.AP_SUPPLIER_SITES_ALL .DEBARMENT _START_DAT E, 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.VENDO R_ID = APPS.AP_SUPPLIER_SITES_ALL .VENDOR_ID AND APPS.PO_HEADERS_ALL.VENDOR _SITE_ID = APPS.AP_SUPPLIER_SITES_ALL .VENDOR_SI TE_ID) "
sql = sql & "WHERE " & qString & ";"
CurrentDb.QueryDefs(qry2). 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
ImportServicePOs_Exit:
Exit Function
ImportServicePOs_Err:
MsgBox Error$
Resume ImportServicePOs_Exit
End Function
Thank you.
--------------------------
Public Function ImportServicePOs()
On Error GoTo ImportServicePOs_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_ServicePosWithVendorD
qry2 = "qry_ServicePosWithVendorD
tbl1 = "tbl_ServicePosWithVendorD
Set fd = Application.FileDialog(mso
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
Set rst = CurrentDb.OpenRecordset(tb
sql = "SELECT DISTINCT " & tbl & ".[PO Number]"
sql = sql & "INTO " & tbl2 & " "
sql = sql & "FROM " & tbl
DoCmd.RunSQL sql
Set rst = CurrentDb.OpenRecordset(tb
rst.MoveFirst
pos = rst("PO Number")
qString = "(APPS.PO_HEADERS_ALL.SEGM
For X = 2 To rst.RecordCount
rst.MoveNext
pos = rst("PO Number")
qString = qString & " OR (APPS.PO_HEADERS_ALL.SEGME
Next X
sql = "SELECT APPS.PO_HEADERS_ALL.PO_HEA
sql = sql & "APPS.AP_SUPPLIER_SITES_AL
sql = sql & "APPS.AP_SUPPLIER_SITES_AL
sql = sql & "APPS.AP_SUPPLIER_SITES_AL
sql = sql & "FROM APPS.PO_HEADERS_ALL INNER JOIN APPS.AP_SUPPLIER_SITES_ALL
sql = sql & "WHERE " & qString & ";"
CurrentDb.QueryDefs(qry2).
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
ImportServicePOs_Exit:
Exit Function
ImportServicePOs_Err:
MsgBox Error$
Resume ImportServicePOs_Exit
End Function
So, instead of all those OR statements, why not create a query with a join to tbl2.
Add tbl2 to the query grid and insert a join line between
PPS.PO_HEADERS_ALL.SEGMENT 1 and tbl2.[PO Number]
This will eliminate the need for the criteria testing all of the possible [PO Number] values.
Add tbl2 to the query grid and insert a join line between
PPS.PO_HEADERS_ALL.SEGMENT
This will eliminate the need for the criteria testing all of the possible [PO Number] values.
ASKER
Hi Dale:
Thank you for the reply. The problem is that this is a passthrough query, while tbl2 is a locally generated table.
Thank you for the reply. The problem is that this is a passthrough query, while tbl2 is a locally generated table.
can you not generate tbl2 on the server side, or is it being generated based upon an Access table?
Instead of a pass-through query, run a stored procedure, generate tbl2 as a temp table on the server and simply return the recordset to Access.
Instead of a pass-through query, run a stored procedure, generate tbl2 as a temp table on the server and simply return the recordset to Access.
ASKER
Unfortunately, I do not have access to generating anything on the server side. I only have a read-only access.
Then create your query without the WHERE clause as a pass-through query. Then create a new query that uses this query and tbl2
SELECT savedQueryName.*
FROM savedQueryName INNER JOIN tbl2 on SavedQueryName.SEGMENT1 = tbl2.[PO Number]
I'm going to try something else and will get back to you.
SELECT savedQueryName.*
FROM savedQueryName INNER JOIN tbl2 on SavedQueryName.SEGMENT1 = tbl2.[PO Number]
I'm going to try something else and will get back to you.
ASKER
Thank you. I will try, although this would mean downloading all the purchase orders in the system with no filters.
"... although this would mean ..."
Yeah, I know, that's why I was looking into something else.
You could also construct your where clause with a syntax:
strWHERE = "WHERE APPS.PO_HEADERS_ALL.SEGMEN T1 IN ('PO1', 'PO2', 'PO3') instead of all the OR clauses.
Yeah, I know, that's why I was looking into something else.
You could also construct your where clause with a syntax:
strWHERE = "WHERE APPS.PO_HEADERS_ALL.SEGMEN
ASKER
Good catch! I will try this one tomorrow, and let you know.
ASKER
Thanks.
I also noticed that your FROM clause includes the parenthesis that Access (Jet) throws in. These will cause problems as SQL Server will not recognize those. The FROM clause should read:
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_SI TE_ID"
I would try this fix before making any other changes. Then if this doesn't resolve the problem, modify the WHERE clause with the IN ( ) syntax.
I've also stumbled on another way to do this that might be even more efficient, but lets see if these fixes don't resolve your problem first.
Dale
sql = sql & "FROM APPS.PO_HEADERS_ALL INNER JOIN APPS.AP_SUPPLIER_SITES_ALL
& "ON APPS.PO_HEADERS_ALL.VENDOR
& "AND APPS.PO_HEADERS_ALL.VENDOR
I would try this fix before making any other changes. Then if this doesn't resolve the problem, modify the WHERE clause with the IN ( ) syntax.
I've also stumbled on another way to do this that might be even more efficient, but lets see if these fixes don't resolve your problem first.
Dale
Lets try the other syntax first, but I stumbled on an idea which also might work for you. Don't know whether this query will run quicker than what you have or not. It involves actually creating a temp table on SQL Server as part of the pass-through query. Syntax of the PT query would look like:
SET NOCOUNT ON
declare @TempData as table (PO_Number nvarchar(10))
insert into @TempData values ('abc123'), ('xyz456'), ('mno789')
SELECT *
FROM yourTable INNER JOIN @TempData ON yourTable.FieldName = @TempDate.PO_Number
So instead of creating all of the OR statements for the current query, or the IN ( ) clause for my previous recommendation, you would create the top part of the query. The only down side of this is that pass-through queries are limited to 32K characters, so you could end up bumping into a character limit (but this applies to all of the recommendations above).
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thank you Dale for your time and assistance.
Marco,
Glad to help.
Did you try the @TempData code?
Glad to help.
Did you try the @TempData code?
ASKER
Yes, and it worked. The only problem is that I do not know how to pass the PO numbers to the PQ query you suggested.
it would start out with something like:
If that works, you would:
1. remove the last line of that code and append the SELECT statement from your original query
2. add an additional JOIN in the FROM clause that joins on
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_SI TE_ID
INNER JOIN @TempData ON APPS.PO_HEADERS_ALL.SEGMEN T1 = @TempData.PO_Number
3. Remove the WHERE clause, because the INNER JOIN to @TempData would have the same effect as the OR clauses.
However, my concern at this point is you made a comment in one of your previous posts that you could have over a thousand PO Numbers in tbl2. Those PO numbers are strings, how long are they? Your SQL string is limited to a total of 32K (32,768) characters, so you could bump into the character limit. Even with a 10 character PO number, 1000 records is only going to be 10,000, and your select clause can't be more than a couple K, so I think you should be OK with this.
I wouldn't replace your original code, if it is working, but I would test this to see if it runs more efficiently.
Dim strCreate as string
Dim strPONumbers as strring
strCreate = "SET NOCOUNT ON " & vbcrlf & vbcrlf _
& "declare @TempData as table (PO_Number nvarchar(10) primary key)" & vbcrlf _
& "insert into @TempData values "
Set rst = CurrentDb.OpenRecordset(tbl2)
While not rst.EOF
strPONumbers = strPONumbers & ", ('" & rst![PO Number] & "')"
rst.MoveNext
Wend
strPONumbers = Mid(strPONumbers,3) 'This strips out the leading ", " values
qd.SQL = strCreate & strPONumbers & vbcrlf _
& "SELECT * FROM @TempData"
If you build the querydef with this code, and run it, you should get a list of the PO Numbers in tbl2.If that works, you would:
1. remove the last line of that code and append the SELECT statement from your original query
2. add an additional JOIN in the FROM clause that joins on
FROM APPS.PO_HEADERS_ALL INNER JOIN APPS.AP_SUPPLIER_SITES_ALL
ON APPS.PO_HEADERS_ALL.VENDOR
AND APPS.PO_HEADERS_ALL.VENDOR
INNER JOIN @TempData ON APPS.PO_HEADERS_ALL.SEGMEN
3. Remove the WHERE clause, because the INNER JOIN to @TempData would have the same effect as the OR clauses.
However, my concern at this point is you made a comment in one of your previous posts that you could have over a thousand PO Numbers in tbl2. Those PO numbers are strings, how long are they? Your SQL string is limited to a total of 32K (32,768) characters, so you could bump into the character limit. Even with a 10 character PO number, 1000 records is only going to be 10,000, and your select clause can't be more than a couple K, so I think you should be OK with this.
I wouldn't replace your original code, if it is working, but I would test this to see if it runs more efficiently.
Marco,
I just read an article on using table variables versus temp tables, and the author of the article explained that he would recommend use to temp tables for this type of thing over the table variable because of the way SQL Server will optimize the query plan. So instead of the syntax I mentioned above, you would be better off with a syntax like:
I just read an article on using table variables versus temp tables, and the author of the article explained that he would recommend use to temp tables for this type of thing over the table variable because of the way SQL Server will optimize the query plan. So instead of the syntax I mentioned above, you would be better off with a syntax like:
SET NOCOUNT ON
declare #TempData as table (PO_Number nvarchar(10) primary key)
insert into #TempData values ('abc123'), ('xyz456'), ('mno789')
SELECT * FROM #TempData
DROP TABLE #TempData
You will note that in this code, I added the DROP TABLE command to drop the temp table at the end of the process. Not many changes to the code I provided above.
ASKER