使用 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 记录集,都无关紧要。你不能这样做。并且查询类型(SELECT
、UPDATE
、INSERT
等)也无关紧要;您不能在任何查询类型中使用记录集对象作为数据源。
首先将您的SELECT
语句保存为命名查询qryRS3,您可能会得到一个可行的UPDATE
。然后将UPDATE
修改为INNER JOIN
tblValueChain10 为 qryRS3。但我不确定 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 记录集执行联合更新查询的主要内容,如果未能解决你的问题,请参考以下文章