简体   繁体   English

在SQL传递查询中使用Access函数

[英]Use Access function in SQL pass-through query

I have an MS Access front-end with an Oracle SQL back-end database. 我有一个带有Oracle SQL后端数据库的MS Access前端。

I'm trying to create a pass-through query that contains a function within Access. 我正在尝试创建一个传递查询,该传递查询包含Access中的一个函数。 The function is for setting the jobnumber based on what the user types into the login screen. 该功能用于根据用户在登录屏幕上jobnumber的内容来设置jobnumber

SELECT 
    CC_QAQC_SPEC_MASTER.JOBNUMBER, 
    CC_QAQC_SPEC_MASTER.SPECSECTION,
    CC_QAQC_SPEC_MASTER.SPECDESCRIPTION,
    CC_QAQC_SPEC_MASTER.ID
FROM 
    CC_QAQC_SPEC_MASTER
WHERE 
    CC_QAQC_SPEC_MASTER.JOBNUMBER=GET_QAQC_JOB()
ORDER BY 
    CC_QAQC_SPEC_MASTER.SPECSECTION, 
    CC_QAQC_SPEC_MASTER.SPECDESCRIPTION;

When I run the above I receive an error message that says: 当我运行以上命令时,我收到一条错误消息,内容为:

ODBC--call failed [Oracle][ODBC][Ora]ORA-00942:table or view does not exist(#942) ODBC-调用失败[Oracle] [ODBC] [Ora] ORA-00942:表或视图不存在(#942)

Well, since the sql is sent "raw" to Oracle, then of course the server side database has no idea what to do with a VBA function. 好吧,由于sql是“原始”发送给Oracle的,因此服务器端数据库当然不知道如何使用VBA函数。

So, one possible solution would be to re-create the VBA function as a scaler oracle function. 因此,一种可能的解决方案是将VBA函数重新创建为定标器oracle函数。

However, because that given function has no paramters, then we can assume that the function returns a given value - darn near close to a static, or a value that you wish/want to pass to oracle. 但是,由于该给定函数没有参数,因此我们可以假定该函数返回给定值-darn接近于静态值,或者是您希望/希望传递给oracle的值。

The approach then means we have to resolve the function client side BEFORE we attempt to use or execute that PT query. 然后,该方法意味着我们必须在尝试使用或执行该PT查询之前先解析客户端的功能。

So, I recommend that you take the above PT query, and copy it. 因此,我建议您采用上述PT查询并将其复制。 (access side). (访问侧)。 You now have two PT queries. 现在,您有两个PT查询。

Now, in code, we grab the sql, modify it, shove it into the 2nd query, and now you are free to launch + use that pass-though query (for a report, recordsets, forms or whatever) 现在,在代码中,我们获取SQL,对其进行修改,将其推入第二个查询中,现在您可以自由启动+使用该直通查询(用于报表,记录集,表单等)

So, your code will look like this: 因此,您的代码将如下所示:

Sub MyOraclePT()

  Dim strSQL     As String

  strSQL = CurrentDb.QueryDefs("PT1").SQL    ' <-- this change

  strSQL = Replace(strSQL, "GET_QAQC_JOB()", GET_QAQC_JOB())

  CurrentDb.QueryDefs("PT2").SQL = strSQL

  ' now you can open or use this query.

  '
  Dim rst     As DAO.Recordset
  Set rst = CurrentDb.OpenRecordset("PT2")

  ' or open a report/form based on that PT2 query
  ' such as
  DoCmd.OpenReport "MyReport", acViewPreview


End Sub

So, we used two PT query, because the first one is the sql you have as a above. 因此,我们使用了两个PT查询,因为第一个是上面的sql。 We then modify the 2nd PT query to replace the function value with the actual value of the function. 然后,我们修改第二个PT查询,以将函数值替换为函数的实际值。

The above assumes the function is a number (not a string). 上面假设函数是数字(不是字符串)。 If the column CC_QAQC_SPEC_MASTER.JOBNUMBER was a string, then you would could/would place single quotes around the function name in the first PT query. 如果CC_QAQC_SPEC_MASTER.JOBNUMBER列是一个字符串,则可以在第一个PT查询中将/将单引号放在函数名称周围。

I also note a bug/syntax error, as you have: 我还注意到一个错误/语法错误,因为您有:

WHERE 
    CC_QAQC_SPEC_MASTER.JOBNUMBER)=GET_QAQC_JOB()

In above, I see a stray ")" in above - you want to fix that. 在上方,我在上方看到一个流浪“)”-您想解决该问题。

Assuming the function is a function written in VBA in Access, you can't call it from the query. 假设该函数是用Access中的VBA编写的函数,则不能从查询中调用它。 I believe the DML in the query is sent in its entirety to the source system, Oracle in this case. 我相信查询中的DML会全部发送到源系统,在这种情况下是Oracle。 Oracle has no idea what the function is and errors. Oracle不知道该功能是什么以及错误。

Option-1 : Submit the Query via ADO.NET in VBA 选项1 :在VBA中通过ADO.NET提交查询

Abandon the pass-thru query objects in Access. 放弃Access中的直通查询对象。 Execute the query from VBA connecting to Oracle via ADO or something like it. 从通过ADO或类似工具连接到Oracle的VBA执行查询。 There are lots of resources on how to use ADO to pull data from external data sources such as How To Open ADO Connection and Recordset Objects . 关于如何使用ADO从外部数据源中提取数据的资源很多,例如如何打开ADO连接和记录集对象 Here is an example using DAO. 是使用DAO的示例。

Option-2 : Wrap the Pass-thru Query in Another Query 选项2 :将通过查询包装到另一个查询中

Access lets you create queries that call other queries. 使用Access,您可以创建调用其他查询的查询。 Create the pass-thru query without the WHERE predicate. 创建不带WHERE谓词的直通查询。 This is the pass-thru query. 这是直通查询。 Create another access query that calls the pass-thru query. 创建另一个访问查询,该查询调用直通查询。 This is the wrapping query. 这是包装查询。 The wrapping query (since its native Access SQL) should have the parameter you use to filter the result set. 包装查询(由于其本地Access SQL)应具有用于过滤结果集的参数。

Complete disclosure. 完整披露。 I didn't try this with Oracle. 我没有尝试使用Oracle。

Now, if the pass-thru query is grabbing a lot of data. 现在,如果直通查询正在获取大量数据。 This option won't perform well. 此选项效果不佳。

Option-3 : Dynamically Create the Pass-Thru Query 选项3 :动态创建直通查询

You have an event (button click or whatever) call a VBA sub-procedure, which dynamically creates and assigns the SQL for the query: 您有一个事件(单击按钮或进行任何其他操作)调用VBA子过程,该子过程动态创建并为查询分配SQL:

Public Sub foo()
    Let qaqc_job_number = GET_QAQC_JOB()
    Set Query = CurrentDb.QueryDefs("<your-pass-thru-function-name>")

    Let sql_job_data = "SELECT" & _
                       "CC_QAQC_SPEC_MASTER.JOBNUMBER, " & _
                       "CC_QAQC_SPEC_MASTER.SPECSECTION, " & _
                       "CC_QAQC_SPEC_MASTER.SPECDESCRIPTION, " & _
                       "CC_QAQC_SPEC_MASTER.ID " & _
                       "FROM " & _
                       "CC_QAQC_SPEC_MASTER " & _
                       "WHERE " & _
                       "CC_QAQC_SPEC_MASTER.JOBNUMBER)= " & qaqc_job_number & " " & _
                       "Order BY " & _
                       "CC_QAQC_SPEC_MASTER.SPECSECTION, " & _
                       "CC_QAQC_SPEC_MASTER.SPECDESCRIPTION; "

    Let Query.Sql = sql_job_data

End Sub

Then you run the query. 然后,您运行查询。

Everything in the SQL you stick in this Access query object has to exist in Oracle and ONLY in Oracle. 您在此Access查询对象中保留的SQL中的所有内容都必须存在于Oracle中,并且只能存在于Oracle中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM