Jet 数据库和传递查询、参数

发布于 2024-09-12 14:11:15 字数 1002 浏览 7 评论 0原文

我正在通过 ODBC 连接到 Jet 4 DB。 Jet DB 使用对 Oracle DB 的直通查询。到目前为止,这是有效的(无法直接访问 pt 查询,但在查询上创建视图可以解决问题)。

我需要 p-ts 返回的数据的一些子集。参数最好,但不支持。

有两个问题:

1)Jet 似乎确实能够将一些 where 子句推送给 Oracle。例如,我有一个返回 100k 行的直通查询。具有单个过滤子句(例如“district = '1010'”)的 pt 视图非常快,因此处理似乎发生在 Oracle 上。添加更多子句可能会使查询速度变慢,在 CPU 利用率很高的情况下循环几分钟。是否有关于 Jet 方面传递的内容和完成的内容的任何文档?

2) 有很多关于如何使用 VBA/Access 创建动态直通查询的教程。是否可以使用通过 ODBC 访问的 Jet 来执行此操作(或任何具有此效果的操作)?

谢谢 马丁

编辑: 抱歉这么不清楚。

我有一个通过 ODBC 访问 Jet 数据库的报告工具。 Jet 数据库包含一些数据和对 Oracle 数据库的多个直通查询。典型的用例是使用 Jet 和 Oracle 的数据为给定部门和给定日期生成报告。从原理上讲,这非常有效。

问题是直通查询不能包含任何参数。直通查询的工作方式类似于视图,因此我可以简单地执行“select * from pt_query where dep = 'a' and date = somedate”。然而,Jet 从 pt 加载所有行并在客户端执行完整扫描。对于 100k 行视图来说,这太慢了,我需要找到一种方法来避免这种情况。

对于一些简单的选择,Jet 似乎确实让 Oracle 完成了艰苦的工作,并且不会加载所有行,因此我的问题 1。

如果这不起作用,我需要找到一种方法来强制 Jet只加载 Oracle 针对给定请求所需的数据。

我知道我可以通过Access VBA修改pts,但我只能通过ODBC连接,所以我只能将SQL传递给Jet,而不能调用vb api(除非可以在SQL语句中内联VB)。

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).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

初见 2024-09-19 14:11:15

构造查询来引起表扫描并非不可能,这就是导致问题的原因。

您似乎正在使用 VBA 工作。可以在 VBA 中构建相当多有趣的查询作为 SQL 字符串,并将它们保存到新查询、更新现有查询、将它们用作表单的记录源或打开记录集。您可以使用 DAO 或 ADO,具体取决于您想要执行的操作。我有Oracle,所以我所能做的就是使用SQL Server提出想法,方括号中的连接可以通过查看链接表的连接来获得(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

或者

''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

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
心是晴朗的。 2024-09-19 14:11:15

您可以在自己的数据库中复制 PT 查询,而不是在另一个数据库中链接到它吗?

PT 查询中的所有 sql 都应该在链接服务器上执行,而 Jet 不会尝试解析或执行它。从杰特的角度来看,这是一种外语。

我将在 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];

在 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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文