在 SQL 传递查询中使用 Access 函数
Use Access function in SQL pass-through query
我有一个带有 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--call failed [Oracle][ODBC][Ora]ORA-00942:table or view does not
exist(#942)
假设该函数是在Access中用VBA编写的函数,您不能从查询中调用它。我相信查询中的 DML 已完整发送到源系统,在本例中为 Oracle。 Oracle 不知道该函数是什么,并且有错误。
Option-1: 在VBA
中通过ADO.NET提交查询
放弃 Access 中的 pass-thru 查询对象。从 VBA 通过 ADO 或类似的东西连接到 Oracle 执行查询。有很多关于如何使用 ADO 从外部数据源提取数据的资源,例如 How To Open ADO Connection and Recordset Objects. Here 是一个使用 DAO 的示例。
Option-2:将 Pass-thru 查询包装在另一个查询
中
Access 允许您创建调用其他查询的查询。创建不带 WHERE 谓词的 pass-thru 查询。这是 pass-thru 查询。创建另一个调用 pass-thru 查询的访问查询。这是包装查询。包装查询(自其本机 Access SQL)应该具有用于过滤结果集的参数。
完全披露。我没有在 Oracle 上尝试过。
现在,如果 pass-thru 查询正在抓取大量数据。此选项效果不佳。
Option-3:动态创建 Pass-Thru 查询
您有一个事件(单击按钮或其他)调用 VBA sub-procedure,它动态创建并分配查询的 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 中。
好吧,既然 sql 被发送 "raw" 到 Oracle,那么服务器端数据库当然不知道如何处理 VBA 函数。
因此,一种可能的解决方案是 re-create VBA 函数作为缩放器 oracle 函数。
但是,因为给定的函数没有参数,所以我们可以假设函数 returns 给定的值 - 该死的接近静态值,或者你 wish/want 传递的值到甲骨文。
该方法意味着我们必须在尝试使用或执行该 PT 查询之前解析函数客户端。
因此,我建议您采用上述 PT 查询,并将其复制。 (接入端)。您现在有两个 PT 查询。
现在,在代码中,我们抓取 sql,对其进行修改,将其推入第二个查询,现在您可以自由启动 + 使用 pass-though 查询(对于报告,记录集、表格或其他)
因此,您的代码将如下所示:
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 是一个字符串,那么您将 could/would 在第一个 PT 查询中将函数名称放在单引号内。
我还注意到一个 bug/syntax 错误,正如您所遇到的那样:
WHERE
CC_QAQC_SPEC_MASTER.JOBNUMBER)=GET_QAQC_JOB()
在上面,我看到上面有一个乱七八糟的“)” - 你想修复它。
我有一个带有 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--call failed [Oracle][ODBC][Ora]ORA-00942:table or view does not exist(#942)
假设该函数是在Access中用VBA编写的函数,您不能从查询中调用它。我相信查询中的 DML 已完整发送到源系统,在本例中为 Oracle。 Oracle 不知道该函数是什么,并且有错误。
Option-1: 在VBA
中通过ADO.NET提交查询放弃 Access 中的 pass-thru 查询对象。从 VBA 通过 ADO 或类似的东西连接到 Oracle 执行查询。有很多关于如何使用 ADO 从外部数据源提取数据的资源,例如 How To Open ADO Connection and Recordset Objects. Here 是一个使用 DAO 的示例。
Option-2:将 Pass-thru 查询包装在另一个查询
中Access 允许您创建调用其他查询的查询。创建不带 WHERE 谓词的 pass-thru 查询。这是 pass-thru 查询。创建另一个调用 pass-thru 查询的访问查询。这是包装查询。包装查询(自其本机 Access SQL)应该具有用于过滤结果集的参数。
完全披露。我没有在 Oracle 上尝试过。
现在,如果 pass-thru 查询正在抓取大量数据。此选项效果不佳。
Option-3:动态创建 Pass-Thru 查询
您有一个事件(单击按钮或其他)调用 VBA sub-procedure,它动态创建并分配查询的 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 中。
好吧,既然 sql 被发送 "raw" 到 Oracle,那么服务器端数据库当然不知道如何处理 VBA 函数。
因此,一种可能的解决方案是 re-create VBA 函数作为缩放器 oracle 函数。
但是,因为给定的函数没有参数,所以我们可以假设函数 returns 给定的值 - 该死的接近静态值,或者你 wish/want 传递的值到甲骨文。
该方法意味着我们必须在尝试使用或执行该 PT 查询之前解析函数客户端。
因此,我建议您采用上述 PT 查询,并将其复制。 (接入端)。您现在有两个 PT 查询。
现在,在代码中,我们抓取 sql,对其进行修改,将其推入第二个查询,现在您可以自由启动 + 使用 pass-though 查询(对于报告,记录集、表格或其他)
因此,您的代码将如下所示:
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 是一个字符串,那么您将 could/would 在第一个 PT 查询中将函数名称放在单引号内。
我还注意到一个 bug/syntax 错误,正如您所遇到的那样:
WHERE
CC_QAQC_SPEC_MASTER.JOBNUMBER)=GET_QAQC_JOB()
在上面,我看到上面有一个乱七八糟的“)” - 你想修复它。