[英]Use Access function in SQL pass-through query
我有一个带有Oracle SQL后端数据库的MS Access前端。
我正在尝试创建一个传递查询,该传递查询包含Access中的一个函数。 该功能用于根据用户在登录屏幕上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;
当我运行以上命令时,我收到一条错误消息,内容为:
ODBC-调用失败[Oracle] [ODBC] [Ora] ORA-00942:表或视图不存在(#942)
好吧,由于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()
在上方,我在上方看到一个流浪“)”-您想解决该问题。
假设该函数是用Access中的VBA编写的函数,则不能从查询中调用它。 我相信查询中的DML会全部发送到源系统,在这种情况下是Oracle。 Oracle不知道该功能是什么以及错误。
选项1 :在VBA中通过ADO.NET提交查询
放弃Access中的直通查询对象。 从通过ADO或类似工具连接到Oracle的VBA执行查询。 关于如何使用ADO从外部数据源中提取数据的资源很多,例如如何打开ADO连接和记录集对象 。 这是使用DAO的示例。
选项2 :将通过查询包装到另一个查询中
使用Access,您可以创建调用其他查询的查询。 创建不带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中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.