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

时间:2019-05-09 18:56:19

标签: sql function ms-access pass-through

我有一个带有Oracle SQL后端数据库的MS Access前端。

我正在尝试创建一个传递查询,该传递查询包含Access中的一个函数。该功能用于根据用户在登录屏幕中输入的内容来设置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;

运行上述命令时,我收到一条错误消息,提示:

  

ODBC –调用失败[Oracle] [ODBC] [Ora] ORA-00942:表或视图不正确   存在(#942)

2 个答案:

答案 0 :(得分:2)

好吧,由于sql是“原始”发送给Oracle的,所以服务器端数据库当然不知道如何使用VBA函数。

因此,一种可能的解决方案是重新创建VBA函数作为缩放器的oracle函数。

但是,由于该给定函数没有参数,因此我们可以假定该函数返回给定值-darn接近于静态值,或者是您希望/希望传递给oracle的值。

然后,该方法意味着我们必须先尝试解决客户端的功能,然后再尝试使用或执行该PT查询。

因此,我建议您采用上述PT查询并将其复制。 (访问侧)。现在,您有两个PT查询。

现在,在代码中,我们获取SQL,对其进行修改,将其推入第二个查询中,现在您可以自由启动+使用该直通查询(用于报表,记录集,表单或其他任何东西)

因此,您的代码将如下所示:

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

因此,我们使用了两个PT查询,因为第一个是上面的sql。然后,我们修改第二个PT查询,以将函数值替换为函数的实际值。

以上假设函数是数字(不是字符串)。如果CC_QAQC_SPEC_MASTER.JOBNUMBER列是一个字符串,则可以在第一个PT查询中将/将单引号放在函数名称周围。

我也注意到了一个错误/语法错误,就像您遇到的一样:

WHERE 
    CC_QAQC_SPEC_MASTER.JOBNUMBER)=GET_QAQC_JOB()

在上面,我在上面看到一个杂散的“)”-您想解决这个问题。

答案 1 :(得分:1)

假定该函数是用Access中的VBA编写的函数,则不能从查询中调用它。我相信查询中的DML会全部发送到源系统,在这种情况下是Oracle。 Oracle不知道它的功能和错误。

选项1 :在VBA中通过ADO.NET提交查询

放弃Access中的直通查询对象。从通过ADO或类似工具连接到Oracle的VBA执行查询。关于如何使用ADO从诸如How To Open ADO Connection and Recordset Objects之类的外部数据源中提取数据,有很多资源。 Here是使用DAO的示例。

选项2 :将通过查询包装在另一个查询中

访问使您可以创建调用其他查询的查询。创建不带WHERE谓词的直通查询。这是直通查询。创建另一个访问查询,该查询调用直通查询。这是包装查询。包装查询(由于其本机的Access SQL)应具有用于过滤结果集的参数。

完整披露。我没有在Oracle上尝试过这个。

现在,如果直通查询正在获取大量数据。此选项效果不佳。

选项3 :动态创建直通查询

您有一个事件(单击按钮或进行任何其他操作)调用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

然后您运行查询。

您在此Access查询对象中保留的SQL中的所有内容都必须存在于Oracle中,并且仅存在于Oracle中。