使用 ADODB 记录集执行联合更新​​查询

Posted

技术标签:

【中文标题】使用 ADODB 记录集执行联合更新​​查询【英文标题】:Using an ADODB record set to perform a joined update query 【发布时间】:2015-01-16 05:07:31 【问题描述】:

在以下代码中,我想将 ADODB 记录集 'rs3' 加入表 'tblValueChain10' 并根据从 ADODB 记录集 'rs3' 中提取的值更新 3 个不同的列。目前,更新查询没有返回任何内容。

Dim st_Sql3 As String
Dim rs3 As ADODB.Recordset
Set rs3 = New ADODB.Recordset
Dim Max3 As Integer

rs3.Open "SELECT tblRisk05Holding.IDMacroProcesso01, tblRisk05Holding.Level01Risk, Max(tblRisk05Holding.ManualityStatus) AS MaxDiManualityStatus, Max(tblRisk05Holding.RiskProbabilityStatus) AS MaxDiRiskProbabilityStatus, Max(tblRisk05Holding.RiskExposureStatus) AS MaxDiRiskExposureStatus FROM tblRisk05Holding GROUP BY tblRisk05Holding.IDMacroProcesso01, tblRisk05Holding.Level01Risk", CurrentProject.Connection


st_Sql3 = "UPDATE tblValueChain10 INNER JOIN rs3 ON (tblValueChain10.IDMacroProcesso01 = tblRisk05Holding.IDMacroProcesso01) SET L1RiskManuality = " & rs3.Fields(2) & ", L1RiskProbability = " & rs3.Fields(3) & ", L1RiskGravity = " & rs3.Fields(4) & ""
Application.DoCmd.RunSQL (st_Sql2)

rs3.Close
Set rs3 = Nothing

【问题讨论】:

虽然这与答案不同,但我想解释一下,根据我的经验,这种情况最好通过使用Do...Loop 结构来处理记录集的每一行来解决。与纯 SQL 相比,它是惰性的,但它允许控制并使故障排除更加容易。 【参考方案1】:

Access 绝不允许您将记录集对象用作另一个查询中的数据源。无论您有 ADO 还是 DAO 记录集,都无关紧要。你不能这样做。并且查询类型(SELECTUPDATEINSERT 等)也无关紧要;您不能在任何查询类型中使用记录集对象作为数据源。

首先将您的SELECT 语句保存为命名查询qryRS3,您可能会得到一个可行的UPDATE。然后将UPDATE 修改为INNER JOIN tblValueChain10qryRS3。但我不确定 Access 是否会认为该查询是可更新的。 GROUP BY 可能会导致 Access 将其视为不可更新。你必须测试才能看到。

【讨论】:

【参考方案2】:

虽然您尝试以所呈现的方式使用 ADO Recordset 实现的目标无法实现(正如用户 @HansUp 所写),但您可以尝试使用从 rs3 获取的子查询更新表 tblValueChain10 的方法记录集公开通话。

希望如下查询:

UPDATE 
  tblValueChain10 
  INNER JOIN 
  (
    SELECT 
       tblRisk05Holding.IDMacroProcesso01, 
       tblRisk05Holding.Level01Risk, 
       Max(tblRisk05Holding.ManualityStatus) AS MaxDiManualityStatus, 
       Max(tblRisk05Holding.RiskProbabilityStatus) AS MaxDiRiskProbabilityStatus, 
       Max(tblRisk05Holding.RiskExposureStatus) AS MaxDiRiskExposureStatus 
    FROM 
       tblRisk05Holding 
    GROUP BY 
       tblRisk05Holding.IDMacroProcesso01, 
       tblRisk05Holding.Level01Risk
  ) AS qry_Risk05Holding
  ON (tblValueChain10.IDMacroProcesso01 = qry_Risk05Holding.IDMacroProcesso01) 
SET 
  tblValueChain10.L1RiskManuality = qry_Risk05Holding.MaxDiManualityStatus, 
  tblValueChain10.L1RiskProbability = qry_Risk05Holding.MaxDiRiskProbabilityStatus, 
  tblValueChain10.L1RiskGravity = qry_Risk05Holding.MaxDiRiskExposureStatus

可以帮助您解决问题。

您应该能够使用以下代码运行上述 SQL:

Dim st_Sql3 As String

st_Sql3 = " UPDATE tblValueChain10 INNER JOIN ( "

st_Sql3 = st_Sql3 & " SELECT  " _
    & " tblRisk05Holding.IDMacroProcesso01,  " _
    & " tblRisk05Holding.Level01Risk,  " _
    & " Max(tblRisk05Holding.ManualityStatus) AS MaxDiManualityStatus,  " _
    & " Max(tblRisk05Holding.RiskProbabilityStatus) AS MaxDiRiskProbabilityStatus,  " _
    & " Max(tblRisk05Holding.RiskExposureStatus) AS MaxDiRiskExposureStatus  "

st_Sql3 = st_Sql3 & " FROM  " _
    & " tblRisk05Holding  " _
    & " GROUP BY  " _
    & " tblRisk05Holding.IDMacroProcesso01,  " _
    & " tblRisk05Holding.Level01Risk "

st_Sql3 = st_Sql3 & " ) AS qry_Risk05Holding " _
  & " ON (tblValueChain10.IDMacroProcesso01 = qry_Risk05Holding.IDMacroProcesso01) " _
  & " SET " _
  & " tblValueChain10.L1RiskManuality = qry_Risk05Holding.MaxDiManualityStatus,  " _
  & " tblValueChain10.L1RiskProbability = qry_Risk05Holding.MaxDiRiskProbabilityStatus, " _
  & " tblValueChain10.L1RiskGravity = qry_Risk05Holding.MaxDiRiskExposureStatus "

Application.DoCmd.RunSQL (st_Sql3)

查询分四个阶段构建,因为据我所知,VBA 中有一个限制,即不能有太多换行符_

另请注意,更新查询中使用的JOIN 假定通过IDMacroProcesso01 连接两个表将确保记录以正确的方式更新。

我现在无法检查 Acces 中的解决方案,但也许它可以以某种方式帮助您,至少是一个概念。如有错误,请写。

【讨论】:

我不确定他为什么不使用您在上面发布的 sql 创建新查询,而不是在运行时构建 sql。 @Beth 感谢您的评论。好点子。我没有考虑过,但对于问题作者来说,这可能是一个不错的选择。问候。【参考方案3】:

您需要遍历记录集以按每条记录迭代更新:

Do While NOT rs3.EOF

       st_Sql3 = "UPDATE tblValueChain10"_
                 & " INNER JOIN rs3 ON (tblValueChain10.IDMacroProcesso01 = tblRisk05Holding.IDMacroProcesso01)" _
                 & " SET L1RiskManuality = " & rs3.Fields(2) & ", L1RiskProbability = " & rs3.Fields(3) & "," _
                 & " L1RiskGravity = " & rs3.Fields(4) & "" 
       DoCmd.RunSQL (st_Sql3)

rs3.MoveNext
Loop

另外请注意,您的 RunSQL () 命令调用了错误的 SQL 字符串。

【讨论】:

【参考方案4】:

如果没有出现错误,则尝试放置此代码:

Set rs3 = New ADODB.Recordset

form_load中,如在,

private sub Form_load()
Set rs3 = New ADODB.Recordset
End Sub

注意:此示例在 vb6.0 中。这就是我能做的。另外,查看参考文献中的版本

【讨论】:

以上是关于使用 ADODB 记录集执行联合更新​​查询的主要内容,如果未能解决你的问题,请参考以下文章

从ADODB记录集复制数据时,Excel表丢失数字格式

将 ADODB 记录集拆分为 Excel 工作表?

在 VBA 中对断开连接的 ADODB 记录集应用过滤器

如何从具有命名参数的表值函数创建 ADODB 记录集

ADODB 记录集不会在 MS SQL 的临时表中添加新记录

带有 ADODB 记录集的 MS Access ListBox 列属性创建错误 424 需要对象