使用更改的 WHERE 子句访问直通查询

Posted

技术标签:

【中文标题】使用更改的 WHERE 子句访问直通查询【英文标题】:Access Passthrough Query with WHERE clause that Changes 【发布时间】:2015-05-22 22:42:56 【问题描述】:

这更具概念性。我有一个当前在 SQLServer 中运行的查询,我想在 Access 中将其转换为直通查询。但是,这是一个怪物查询,必须由带有我想要的 ID#s 的 WHERE 子句限制(有太多的 ID#s 没有 WHERE 子句;它会冻结)。我需要的 ID#s 每天都在变化,所以我无法设置这个 passthrough 一次就完成了。

所以我真的不知道如何获取它,因此用户要么 1. 导入带有当天 ID#s 的表,并且该表链接到直通,或者 2. 用户粘贴 ID#s进入一个输入框,这些成为 WHERE 子句条件。

据我所见,我无法使用 ID#s 将 Access 中的表加入 Passthrough,并且我不能在 WHERE 部分中使用 WHERE ID# = [table].[ID#]我的通行证。在 passthrough 中取出 WHERE,然后在它与访问表连接的地方进行简单的选择查询也不起作用,因为查询只需要很长时间就会超时。

这甚至可能吗,还是我应该探索完全不同的策略?

【问题讨论】:

为什么不把所有东西都放在 SQL Server 端呢?不要在本地导入 ID 表,而是将其保留在外部,然后使用两个外部表的连接运行传递查询。另外,回想一下 WHERE 是隐式 JOIN。因此,根据查询优化器,在 where 子句或连接表中设置 ID 是等效的过程。看到这个热闹discussion。 【参考方案1】:

当我遇到奇怪的直通查询时,我会使用另一种技术 首先,我创建了一个虚拟传递查询,其中所有主观的东西都由虚拟常量表示 例如,如果我改变了年份,我有一个 1900 年的虚拟年份,我使用 replace 将其更改为我需要的任何内容 然后将更改后的 SQL 传递到另一个传递路径,该传递路径用作 所以我的代码是这样的

Const DummyToReplace = "1900"
Dim strSql as String
Dim qdf as QueryDef
strsql = vbnullstring
set qdf = currentdb.QueryDefs(SourceDummyPassThroughQry)
strsql = qdf.SQL
set qdf = nothing
strsql = replace(strSql,DummyToReplace ,TheCriteriaYouwantToPass)
set qdf = currentdb.QueryDefs(ModifiedPassThrough)
qdf.SQL = strsql
set qdf=nothing

此时您可以执行 ModifiedPassThrough 或将其用作 RecordSource。 在 WHERE 的情况下,您可以使用字符串拆分将 SQL 拆分为 2 个部分 第一部分到 WHERE,例如

 strSql = SELECT * from my TABLE WHERE

第二部分只是把 Where Criteria

  WhereCriteria = " ID IN (Various IDs)"

然后你将它们连接起来并将它们提供给修改后的 Pass Through

qdf.SQL = strsql & " " & WhereCriteria

剩下的很简单

【讨论】:

我想试试这个,但我想知道,假设我的 ID 在表的列中,例如第 1 行 = 100、第 2 行 = 101、第 3 行 = 102 等。我如何将这些值转换为可以存储在变量中的字符串,然后在 where 条件字符串变量中使用? WhereCriteria会这样修改WhereCriteria = " ID IN (select IDs from IdTable)" 我在set qdf = currentdb.QueryDefs(SourceDummyPassThroughQry) 步骤中收到了Item not found in this collection。我将 SourceDummyPassThroughQry 更改为我原来的直通名称。我还想知道是否可以进行替换以将我的 WHERE 条件从“虚拟”替换为“(从 IDTable 中选择 ID)”,然后运行直通查询。我不明白吗? SourceDummyPassThroughQry 替换为您的直通名称....请记住,您将有 2 个直通 1 个源和 1 个每次都有 SQL 修改源的 SQL 我做到了,我写了Set qdf = CurrentDb.QueryDefs(qry_PT_Test_Before)【参考方案2】:

在 SqlServer 中将查询构建为返回数据并接受参数的存储过程。构建一个表单,您可以在其中向用户请求 ID,或者构建一个获取这些 ID 的函数(如果可能)。让存储过程中的参数成为您在 WHERE 子句中需要的 ID。

您可以使用 querydefs 来动态地重新定义查询的 SQL

CurrentDb.QueryDefs("myAccessQueryPassT").sql = 
     "EXEC mysqlServerStoredProc (" & par1 & ", " & par2 & ")"

其中 par1, par2, ... par(n) 是您要过滤的 ID。

然后你可以像往常一样运行 msAccess 查询:

SELECT * FROM myAccessQueryPassT

请注意,您也可以在 SqlServer (mySqlServerView) 中定义未过滤的视图,然后在 passthrough 中(在示例中我只包含一个参数,您当然可以包含更多):

CurrentDb.QueryDefs("myAccessQueryPassT").sql = 
"SELECT * 
FROM mySqlServerView 
WHERE ID = " & par1 & ")"

当然,您也可以随时动态构建整个查询,在这种情况下,它将是这样的:

CurrentDb.QueryDefs("myAccessQueryPassT").sql = "SELECT ... FROM ... WHERE..."

和之前一样可以查询直通:

SELECT * FROM myAccessQueryPassT

【讨论】:

以上是关于使用更改的 WHERE 子句访问直通查询的主要内容,如果未能解决你的问题,请参考以下文章

访问直通外部应用

访问 SQL 子查询 WHERE 子句不过滤结果 [关闭]

如何使用 where 子句插入

组合框的行源查询中的 where 子句

使用多个 WHERE 子句和 GROUP BY 销售人员访问 SQL、聚合总和

如何在 WHERE 子句中使用条件不同的列?