如何进行可编辑的 UNION 查询?
Posted
技术标签:
【中文标题】如何进行可编辑的 UNION 查询?【英文标题】:How do I make an editable UNION query? 【发布时间】:2009-08-11 17:52:55 【问题描述】:在复杂的数据库结构过程中,我需要为用户提供一种编辑存储在一系列表中的数据的方法。尽管所有数据类型都相同,但它们的名称并没有 1:1 排列。为了缓解这种情况,我创建了一个查询,将原始名称(来自外部报告)映射到内部使用的名称;从这些查询中,所有内容都被输入到一个巨大的 UNION 查询中。
所有数据类型和字段大小都正确排列。
我还需要做什么才能使这个 UNION 查询正常工作?
这是查询背后的当前 SQL:
SELECT * FROM MappingQuery1 UNION SELECT * FROM MappingQuery2;
编辑:
下面的答案发布了指向KB article 的链接,该链接肯定地指出UNION
查询中的数据无法更新。有什么办法可以解决这个问题吗?例如:
SELECT * FROM MappingQuery1, MappingQuery2;
这行得通吗?请记住,所有字段的类型、大小和名称都是对齐的。
【问题讨论】:
是否有可能将您的各个表合并到一个具有相同结构的主表中,除了一个额外的字段用于每一行起源的表的名称? SELECT * FROM MappingQuery1, MappingQuery2;会给你一个笛卡尔查询(一个包含每行所有可能组合的结果集) - 它是不可编辑的。我同意 HansUp。 HansUp 暗示数据库结构不是最优的。作为一名经验丰富的诊断师(我承认,主要是诊断我自己的问题),我认为这很可能是真的。如果是这样,那么许多其他挑战将紧随其后。 【参考方案1】:我的偏好是将这些单独的表合并到一个主表中。将所有数据放在一个表中,这可能会容易得多。
但是,假设您必须将各个表分开,请更改映射查询以包含源表名称的字段表达式。并在 UNION 查询中包含该表名字段。
然后根据只读的 UNION 查询创建一个连续的表单。添加基于另一个查询的子表单,该查询从相应的表中返回单个可编辑记录。在主窗体的 On Current 事件中,为子窗体的查询重写 RowSource:
strSQL = "SELECT fields_to_edit FROM " & Me.txtTableSource & _
" WHERE pkfield =" & Me.txtPKeyField & ";"
Me.SubformName.Rowsource = strSQL
Me.SubformName.Requery
【讨论】:
我支持这个建议(事实上,这正是我要建议的)。事实上,我有一个标准做法,即我将所有连续/数据表表单设为只读(有一些值得注意的例外,例如发票明细项)。【参考方案2】:当查询是联合查询时,您 无法更新查询中的数据。
http://support.microsoft.com/kb/328828
当 Access 在联合查询中组合来自不同表的行时,各个行会丢失其基础表标识。当您尝试更改联合查询中的行时,Access 无法知道您要更新哪个表,因此它不允许所有更新。
以下问题编辑:
您可以使用 VBA 和 ADO 来更新相应的表格来解决这个问题。我解决这个问题的方法是确保您的联合表包含一个具有源表 id 的列以及另一个命名源表的列。
例如在你的工会中,你会有这样的事情:
SELECT 'Table1', id, ... FROM Table1
UNION
SELECT 'Table2', id, ... FROM Table2
然后通过数据输入表单和 VBA,您可以查看当前选定行的值并更新相关表。
编辑 2:当有一天
这会使用 Access VBA 将值插入到表中
Option Compare Database
Option Explicit
Public Sub InsertDataPunk(TargetTable As String, IdVal As Long, MyVal As String)
Dim conn As ADODB.Connection
Set conn = CurrentProject.Connection
Dim sql As String
'You could build something fancier here
sql = "INSERT INTO " & TargetTable & " VALUES (" & IdVal & ",'" & MyVal & "')"
Dim cmd As ADODB.Command
Set cmd = New ADODB.Command
Set cmd.ActiveConnection = conn
cmd.CommandText = sql
cmd.CommandType = adCmdText
cmd.Execute
End Sub
InsertDataPunk "Table2", 7, "DooDar"
【讨论】:
表中的记录具有唯一的主键(具体来说,每个表中的 PK 对数据库是完全唯一的,并且是数据集固有的,而不仅仅是一个自动编号)。 如果 id 不重叠,那么您可以重组您的表以拥有包含 id 的父表和包含数据的子表。结果查询可能是可更新的(但您必须先对其进行测试)。 SELECT * FROM IdTable 内连接 Table1 ON Table1.Id=IdTable.Id 内连接 Table2 ON Table2.Id=IdTable.Id 上面应该使用左外连接。唯一的问题是这些值最终会出现在不同的列中......结果是可更新的......也许最好坚持VBA解决方案 VBA 方法可以工作;然而,我只是一个暑期实习生,我将在一个半星期内通过这个项目,所以我试图让它尽可能易于维护;我想这样的解决方案在这个软件上是站不住脚的,我将不得不坚持当前的单独编辑界面模型。 “您可以使用 VBA 和 ADO 来更新相应的表来解决这个问题”——您尝试过吗?我无法让它工作。使用客户端游标和批处理乐观锁定时,我收到错误消息“用于更新或刷新的基表信息不足”。使用服务器端游标和乐观锁定我得到一个静默失败。你能发布一个工作示例吗?【参考方案3】:这是一个非常古老的线程,但我正在寻找解决同一问题的方法并遇到了它。我有一个通过多个联合查询推送的复选框值,当我尝试更新它时,我当然不能。
但是,我确实找到了解决方案,并认为我会分享它。在复选框的 OnEnter 事件中,我只是运行了一个 SQL 更新查询,该查询更新了我想要修改的基础表中的字段。如果是真我更新为假,如果是假我更新为真。瞧!
【讨论】:
以上是关于如何进行可编辑的 UNION 查询?的主要内容,如果未能解决你的问题,请参考以下文章