我有一个带有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)
答案 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中。