访问表单 - Catch 22尝试将数据插入多个相关表

时间:2016-06-22 10:39:18

标签: ms-access ms-access-2010

我是Access的新手,但有多年使用“企业”数据库的经验。我在执行一项简单的任务时遇到了麻烦,并怀疑我的先入之见让我错过了这一点,所以我正在寻求帮助。

简单的任务是使用填充两个表的数据输入访问表单:客户和客户地址(每个客户可以是多个地址)。

Customer表具有主键CustomerID。 CustomerAddress表具有主键CustomerAddressID和CustomerID作为外键,在该关系上具有RI。

Form1绑定到Customer表。输入各种字段的信息后,用户可以单击按钮显示绑定到CustomerAddress的Form2,并为多个地址启用数据输入。

Form1将CustomerID(由Access分配)传递给Form2。由于大小,Form2不是一个子表单,但如果可以解决问题,那么它就可以了。

在一个完美的世界中,我希望将Form1和Form2中的所有新数据一起提交。据推测,我可以使用未绑定的表单执行此操作,并在单个事务中编写插入语句。

问题1:有没有办法使用绑定表单执行此操作?

如果我在没有单击“地址”按钮的情况下使用Form1,则会成功将一行添加到Customer表中。在将Customer行添加到表中之前尝试在Form2中添加CustomerAddress行时出现问题。

在Form2中,如果未使用CustomerID,则会出现插入错误,因为如果没有CustomerID,则无法添加CustomerAddress行。 如果使用CustomerID,则会出现插入错误,因为Customer表上尚不存在CustomerID(尽管ID似乎已“保留”)。

在打开Form2之前强制添加Customer行是不切实际的,因为工作流中的某些客户必需字段不存在。

问题2:有没有办法解决这个问题?这似乎是一个普遍的要求。

我可以通过删除RI来解决这个问题,以便可以先添加CustomerAddress行,但这似乎是糟糕的数据库设计,而且我还需要清理逻辑,以便随后取消客户添加。< / p>

如前所述,我可能忽略了这一点,并且有更好的方法。任何帮助非常感谢。

4 个答案:

答案 0 :(得分:2)

我认为如果您强制执行参照完整性,无论您使用哪种RDBMS,都会遇到同样的问题。在CustomerAddress表中存在记录之前,CustomerID需要存在于Customer表中。我猜客户ID是自动编号。可能令人困惑的是,Access会在新记录启动后立即“保留”自动编号。但是,它不存在于Customer表中。如果永远不保存该记录,则该自动编号值将丢失,下一条记录将获得下一个数字。要求在保存客户记录之前完成地址,听起来像是一个设计问题。这似乎不符合逻辑。就个人而言,我会重新考虑设计。也就是说,一种解决方案是为地址创建一个临时表,并将您的CustomerAddress表单绑定到该表。然后,当保存客户记录时,您将运行追加查询以将新地址添加到CustomerAddress表。但请记住,如果用户输入某些地址并且从未保存过客户记录,则所有数据条目都将丢失。

答案 1 :(得分:1)

关于你的陈述:

  

在打开Form2之前强制添加Customer行是不切实际的,因为工作流中的某些客户必需字段不存在。

如果“必需但尚未知道”字段的Required属性设置为Yes(即NOT NULL),则无法插入Customer行。但是,使用Access 2010及更高版本,您可以使用事件驱动的数据宏在Insert上“不需要”这些字段,但在Update上“必需”。在你的情况下,你可以

  • 允许在没有“最终需要”字段的情况下插入客户记录,
  • 允许添加CustomerAddress记录(启用RI),然后
  • 重新打开客户记录以进行更新,数据宏现在强制执行其他字段的“必需”状态。

Before Change数据宏可能如下所示:

BeforeChange.png

答案 2 :(得分:0)

我认为答案在于你的问题1.是的,有一种方法可以使用绑定表格来实现这一点,并且是我将使用的方法。

Form1绑定到Customer表。将表格2添加到表格1上作为子表格。选择/突出显示表单2,转到属性表。在“数据”选项卡上,将“链接主字段”设置为“客户ID”并将“子字段链接”设置为“客户ID”。

然后在对表格1采取任何行动后,重新查询表格2。

我认为这会让你开始,至少应该让你知道完成后如何继续。

答案 3 :(得分:0)

我不明白为什么两者都必须或者甚至想要同时从子表中提交客户和记录。

当你想添加一个额外的地址,然后添加地址按钮和代码时,必须检查+测试主客户是否已经存在,并使用单独的逻辑来处理客户记录是否存在,或者不存在。那么,如果用户输入了客户名称和信息,但由于手机上的客户可能刚刚移动并且必须使用新地址回拨,因此还没有地址。我可以想到另外六个案例,其中建立一个必须同时添加客户和客户地址记录的设计。

正如其他人所说,您将在任何关系数据库中遇到此问题,包括Access。我还应该指出,如果您使用Access作为SQL服务器或Oracle的前端,Access的工作方式完全相同。

因此,为添加客户和地址构建不同的UI和编码流程,然后使用一组不同的规则和UI来随时添加其他地址毫无意义。因此,构建一个表单来搜索+查找客户,并添加该客户并显示该客户。完成该过程后,您将添加流程(和UI部分)以允许用户查看或向该客户添加地址。我认为我没有看到过具有单独表单的UI来添加/编辑客户和单独的表单,以允许其他地址有一些要求它们同时一起提交。

如果用户因为他们意识到地址不可用,错误等而退出地址,这不应该表明到目前为止输入的客户信息被转储而不是添加。如果用户在通过添加地址(说关闭或取消该表单)后退出,则返回客户表单。如果用户由于某种奇怪的原因在那个时间点决定他们不再希望系统中的客户,那么提供删除按钮。

如果业务规则是在所有情况下必须始终至少有一个地址,那么在关闭客户表单后,您不允许关闭表单并请求该用户为该用户输入至少一个地址。也许他们撞到或敲错了钥匙退出地址输入部分 - 无需惩罚该用户并迫使他们重新输入客户信息。因此,在他们输入地址或提供地址(向用户建议)之前,不要让他们退出客户表格,他们可以删除/删除他们想要退出的客户。

如果使用表单+子表单设置,则关系部分需要零代码。并且选项卡控件可以使您的两种表单都可以接近全屏大小。 (无需启动单独的表格)。

当然,您可以编写一堆代码并将所有内容放入交易中,但这样做会浪费编码时间而不会带来任何好处,并且在不需要时会导致公司时间和时间被盗。