views:

50

answers:

2

Hi,

I'm connecting to a Jet 4 DB through ODBC. The Jet DB uses pass-through queries to an Oracle DB. This works so far (can't access the p-t queries directly, but creating a view on the query does the trick).

I need some subset of the data returned by the p-ts. Parameters would be best, but are not supported.

Two questions:

1) Jet does seem to be able to push some where-clauses to Oracle. Eg I have a passthrough query that returns 100k rows. A view on the p-t with a single flitering clause (eg "district = '1010'") is very fast, so the processing seems to happen on Oracle. Adding more clauses can slow the query down to a crawl, looping for minutes with high CPU utilization. Is there any documentation on what is passed on and what is done on in the Jet side?

2) There are lots of tutorials on how to create dynamic passthrough queries with VBA/Access. Is it possible to do this (or anything to that effect) with Jet accessed through ODBC?

Thanks Martin

Edit: Sorry for being so unclear.

I have a reporting tool that accesses a Jet db through ODBC. The Jet db contains some data and several passthrough queries to an Oracle db. A typical use case would be a generating report for a given department and a given date, using data from Jet and Oracle. This works very well in principle.

The problem is that passthrough queries cannot contain any parameters. A passthrough query works like a view, so I can simply execute "select * from pt_query where dep = 'a' and date = somedate". Jet, however, loads all rows from the pt and does a full scan on the client side. This is unusably slow for a 100k-rows view and I need to find a way to avoid that.

For some simple selects, Jet does seem to let Oracle do the hard work and does not load all rows, hence my question 1.

If that doesn't work, I need to find a way to force Jet to load only the data I need from Oracle for a given request.

I know that I can modify pts through Access VBA, but I only connect through ODBC, so I can only pass SQL to Jet, not call the vb api (unless its possible to inline VB in the SQL statement).

A: 

It is not impossible that the query is constructed to cause a table scan, and this is causing the problem.

You seem to be working in VBA. It is possible to construct quite a few interesting queries as SQL strings in VBA and save them to new queries, update existing queries, use them for record sources for forms, or open recordsets. You can use DAO or ADO, depending on what you want to do. I have Oracle, so all I can do is suggest ideas using SQL Server, the connection in square brackets can be got by looking at the connection of a linked table (CurrentDb.TableDefs("NameOfTable").Connect):

Dim cn As New ADODB.Connection

''You can use Microsoft.ACE.OLEDB.12.0 or Microsoft.Jet.OLEDB.4.0
scn = "Provider=Microsoft.ACE.OLEDB.12.0;User ID=Admin;Data Source=" _
    & CurrentProject.FullName
cn.Open scn

''An insert query, but you can see that is would be easy enough to 
''select from two different databases
s = "INSERT into [ODBC;Description=TEST;DRIVER=SQL Server;" _
& "SERVER=ServerName\SQLEXPRESS;Trusted_Connection=Yes;" _
& "DATABASE=test].Table2 (id, atext) select id, atext from table1"

cn.Execute s

Or

''http://www.carlprothman.net/Default.aspx?tabid=87
strConnect = _
    "Provider=sqloledb;" & _
    "Data Source=myServerName;" & _
    "Initial Catalog=Test;" & _
    "Integrated Security=SSPI"
With cmd
    .ActiveConnection = strConnect
    .CommandType = adCmdText
    .CommandText = "SELECT ID, aText FROM table2 " _
                 & "WHERE ID=?"
    .Parameters.Append .CreateParameter _
        ("ID", adInteger, adParamInput, , 1)
    .CommandTimeout = 0
    Set rs = .Execute
End With
Remou
I'm not sure I understand what you are doing here. Does that mean that you can open arbitrary connections to other databases inline in Jet SQL queries by including the Connection string? If thats the case, can I inline pass-through queries too?
Martin
Yes, you can. The answer is somewhat wandering as I am not sure what you want to do, for example, I am by no means sure what you want to happen with the pass-through query, or why you need it.
Remou
If you pass a connection string inline in a passthrough, it will be processed by the remote server. That may or may not work.
David-W-Fenton
Inline connection strings work fine with Jet, AFAIK. I believe the OP wishes to run from Jet, not to pass inline string to some other database.
Remou
(I updated the question for more clarity.) Thanks, this looks promising. The passthrough query does some moderately complex stuff, I simply need to filter the result for two criteria. So, is it possible to inline an sql statement to be passed on to a specified connection, eg (pseudocode) "select * from ([connectionString].['select bla from table2 where ...']) as pt"?
Martin
A: 

Can you duplicate the PT query in your own db instead of linking to it in another db?

All the sql in the PT query should get executed on the linked server without Jet attempting to parse or execute it. It's in a foreign language from Jet's point of view.

I'll use code like this in the PT:

SELECT * FROM DHSVIEWS.ClaimHeaderV    WHERE
DHSViews.claimheaderV.ClaimType = 'p'    AND
DHSViews.claimheaderV.FinalVersionInd = 'y'    AND
DHSViews.claimheaderV.ReimbursementAmount > 0    AND
DHSViews.claimheaderV.majorProgram = 'HH'    AND
DHSViews.claimheaderV.ServiceDateFrom >= [qStart]    AND
DHSViews.claimheaderV.ServiceDateFrom <=  [qEnd];

and this in VBA:

Set qdef = db.QueryDefs(qryPT)
sqlOld = qdef.sql
iPosStart = InStr(sqlOld, "[")
sqlNew = sqlOld
Do While iPosStart > 0
    iPosEnd = InStr(iPosStart, sqlNew, "]")
    param = Mid(sqlNew, iPosStart + 1, iPosEnd - iPosStart - 1)
    Select Case param
        Case "qStart"
            paramVal = "'" & rsQuarter("quarterStart") & "'"
        Case "qEnd"
            paramVal = "'" & rsQuarter("quarterEnd") & "'"
    End Select
    sqlNew = Mid(sqlNew, 1, iPosStart - 1) & paramVal & Mid(sqlNew, iPosEnd + 1)
    iPosStart = InStr(iPosEnd, sqlNew, "[")
Loop
If sqlNew <> sqlOld Then
    qdef.sql = sqlNew
End If
db.QueryDefs(rsPTAppend("append")).Execute
If sqlNew <> sqlOld Then
    qdef.sql = sqlOld
End If
Beth