Access Forms - Catch 22 试图将数据插入多个相关表
Access Forms - Catch 22 trying to insert data to multiple related tables
我是 Access 新手,但有多年使用 "enterprise" 数据库的经验。我在执行一个简单的任务时遇到了问题,我怀疑我的先入之见导致我错过了要点,所以我寻求帮助。
简单的任务是使用填充两个 table 的数据输入访问表单:Customer 和 CustomerAddress(每个客户可以是多个地址)。
客户 table 有主键 CustomerID。 CustomerAddress table 具有主键 CustomerAddressID 和 CustomerID 作为与 RI 在该关系上的外键。
Form1 绑定到客户 table。在各个字段输入信息后,用户可以单击一个按钮来显示绑定到 CustomerAddress 的 Form2,并启用多个地址的数据输入。
Form1 将 CustomerID(由 Access 分配)传递给 Form2。由于大小原因,Form2 不是子窗体,但如果这样可以解决问题,它可能是子窗体。
在理想情况下,我希望将 Form1 和 Form2 中的所有新数据一起提交。大概我可以使用未绑定的表单来做到这一点,并在单个事务中对插入语句进行编码。
问题 1:有没有办法使用绑定表单来做到这一点?
如果我在没有单击 "Address" 按钮的情况下使用 Form1,则会成功向客户 table 添加一行。在 Customer 行添加到 table.
之前尝试在 Form2 中添加 CustomerAddress 行时出现问题
在 Form2 中,如果没有使用 CustomerID,则会出现插入错误,因为没有 CustomerID 无法添加 CustomerAddress 行。
如果使用 CustomerID,则会出现插入错误,因为 CustomerID 在 Customer table 上尚不存在(尽管 ID 似乎是 "reserved")。
在打开 Form2 之前强制添加 Customer 行是不切实际的,因为此时工作流中不存在某些 Customer 必填字段。
问题 2:有办法解决这个问题吗?这似乎是一个普遍的要求。
我可以通过删除 RI 来解决这个问题,以便可以首先添加 CustomerAddress 行,但这似乎是糟糕的数据库设计,我还需要清理逻辑以应对随后取消 Customer 添加的情况.
如前所述,我可能没有抓住要点,还有更好的方法。非常感谢任何帮助。
我认为,如果您实施参照完整性,那么无论您使用哪种 RDBMS,您都会遇到同样的问题。在 CustomerAddress table 中存在记录之前,CustomerID 需要存在于 Customer table 中。我猜 CustomerID 是一个自动编号。可能令人困惑的是,一旦开始新记录,Access 就会立即 'reserve' 自动编号。但是,它不存在于客户 table 中。如果从未保存该记录,则该自动编号值将丢失,下一条记录将获得下一个编号。在保存客户记录之前要求填写地址,这听起来像是一个设计问题。这似乎不合逻辑。就个人而言,我会重新考虑设计。也就是说,一种解决方案是为地址创建一个临时 table 并将您的 CustomerAddress 表单绑定到该地址。然后,当保存客户记录时,您将 运行 追加查询以将新地址添加到 CustomerAddress table。但请记住,如果用户输入了一些地址而客户记录从未保存,则所有数据输入都会丢失。
我认为答案就在你的问题 1 中。是的,有一种方法可以使用绑定表单来做到这一点,我会使用这种方法。
Form1 绑定到客户 table。将 Form 2 作为子表单添加到 Form 1 上。 Select / 突出显示 Form 2,转到属性 sheet。在“数据”选项卡上,将 Link 主字段设置为 CustomerID,将 Link 子字段设置为 CustomerID。
然后在对表格 1 执行任何操作后,重新查询表格 2。
我认为这会让您入门,至少应该让您了解完成后如何继续。
我不明白为什么必须同时提交客户和来自 child table 的记录。
当你想添加一个额外的地址时,那么添加地址按钮和代码现在必须检查+测试主要客户是否已经存在,如果客户记录存在则使用单独的逻辑来处理,或者才不是。如果用户输入了客户姓名和信息,但还没有地址,因为 phone 上的客户可能刚刚搬家,必须用新地址回拨。我可以想到另外六个案例,在这些案例中构建必须同时添加客户和客户地址记录的设计。
正如其他人指出的那样,任何关系数据库(包括 Access)都会遇到此问题。我还应该指出,如果您使用 Access 作为 SQL 服务器或 Oracle 的前端,Access 在这里的工作方式完全相同。
因此,构建一个不同的 UI 和编码过程来添加客户和地址,然后构建不同的规则集和 UI 来随着时间的推移添加额外的地址是没有意义的。所以构建一个表单来搜索+查找客户,然后添加该客户并显示该客户。完成该过程后,您可以添加该过程(和 UI 部分)以允许用户查看或向该客户添加地址。我不认为我见过 UI 有单独的表格给 add/edit 客户和单独的表格允许额外的地址有一些要求他们同时提交。
如果用户因为地址不可用、错误等原因退出地址,这不应该暗示到目前为止输入的客户信息被丢弃而不添加。如果用户在添加地址后放弃(例如关闭或取消该表格),那么您 return 到客户表格。如果用户出于某种奇怪的原因在那个时间点决定不再希望该客户出现在系统中,则提供一个删除按钮。
如果业务规则是在所有情况下都必须始终至少有一个地址,那么在关闭客户表单时您不允许关闭该表单并要求该用户至少输入一个地址这个用户。也许他们按错了键以退出地址输入部分——无需惩罚该用户并强迫他们 re-enter 客户信息。因此,在他们输入地址或向他们提供(向用户建议)之前,不要让他们退出客户表单,他们可以 delete/remove 他们想要退出的客户。
如果您使用表单 + 子表单设置,则关系部分需要零代码。选项卡控件让您可以将两种形式都接近全屏大小。 (无需启动单独的表单)。
当然,您可以编写一堆代码并将所有内容都放在事务中,但这是在浪费编码时间,没有任何好处,并且在不需要时相当于盗用公司时间和时间。
关于您的陈述:
It's not practical to force the Customer row to be added before opening Form2 as some Customer required fields are not present at that point in the workflow.
如果 "required but not yet known" 字段的 Required
属性 设置为 Yes
(即,不为空)。但是,对于 Access 2010 及更高版本,您可以使用事件驱动的数据宏来使此类字段在插入时 "not required" 但在更新时 "required"。在你的情况下,你可以
- 允许在没有 "eventually required" 字段的情况下插入客户记录,
- 允许添加 CustomerAddress 记录(启用 RI),然后
- 重新打开客户记录进行更新,数据宏现在强制其他字段的 "required" 状态。
更改前的数据宏可能如下所示:
我是 Access 新手,但有多年使用 "enterprise" 数据库的经验。我在执行一个简单的任务时遇到了问题,我怀疑我的先入之见导致我错过了要点,所以我寻求帮助。
简单的任务是使用填充两个 table 的数据输入访问表单:Customer 和 CustomerAddress(每个客户可以是多个地址)。
客户 table 有主键 CustomerID。 CustomerAddress table 具有主键 CustomerAddressID 和 CustomerID 作为与 RI 在该关系上的外键。
Form1 绑定到客户 table。在各个字段输入信息后,用户可以单击一个按钮来显示绑定到 CustomerAddress 的 Form2,并启用多个地址的数据输入。
Form1 将 CustomerID(由 Access 分配)传递给 Form2。由于大小原因,Form2 不是子窗体,但如果这样可以解决问题,它可能是子窗体。
在理想情况下,我希望将 Form1 和 Form2 中的所有新数据一起提交。大概我可以使用未绑定的表单来做到这一点,并在单个事务中对插入语句进行编码。
问题 1:有没有办法使用绑定表单来做到这一点?
如果我在没有单击 "Address" 按钮的情况下使用 Form1,则会成功向客户 table 添加一行。在 Customer 行添加到 table.
之前尝试在 Form2 中添加 CustomerAddress 行时出现问题在 Form2 中,如果没有使用 CustomerID,则会出现插入错误,因为没有 CustomerID 无法添加 CustomerAddress 行。 如果使用 CustomerID,则会出现插入错误,因为 CustomerID 在 Customer table 上尚不存在(尽管 ID 似乎是 "reserved")。
在打开 Form2 之前强制添加 Customer 行是不切实际的,因为此时工作流中不存在某些 Customer 必填字段。
问题 2:有办法解决这个问题吗?这似乎是一个普遍的要求。
我可以通过删除 RI 来解决这个问题,以便可以首先添加 CustomerAddress 行,但这似乎是糟糕的数据库设计,我还需要清理逻辑以应对随后取消 Customer 添加的情况.
如前所述,我可能没有抓住要点,还有更好的方法。非常感谢任何帮助。
我认为,如果您实施参照完整性,那么无论您使用哪种 RDBMS,您都会遇到同样的问题。在 CustomerAddress table 中存在记录之前,CustomerID 需要存在于 Customer table 中。我猜 CustomerID 是一个自动编号。可能令人困惑的是,一旦开始新记录,Access 就会立即 'reserve' 自动编号。但是,它不存在于客户 table 中。如果从未保存该记录,则该自动编号值将丢失,下一条记录将获得下一个编号。在保存客户记录之前要求填写地址,这听起来像是一个设计问题。这似乎不合逻辑。就个人而言,我会重新考虑设计。也就是说,一种解决方案是为地址创建一个临时 table 并将您的 CustomerAddress 表单绑定到该地址。然后,当保存客户记录时,您将 运行 追加查询以将新地址添加到 CustomerAddress table。但请记住,如果用户输入了一些地址而客户记录从未保存,则所有数据输入都会丢失。
我认为答案就在你的问题 1 中。是的,有一种方法可以使用绑定表单来做到这一点,我会使用这种方法。
Form1 绑定到客户 table。将 Form 2 作为子表单添加到 Form 1 上。 Select / 突出显示 Form 2,转到属性 sheet。在“数据”选项卡上,将 Link 主字段设置为 CustomerID,将 Link 子字段设置为 CustomerID。
然后在对表格 1 执行任何操作后,重新查询表格 2。
我认为这会让您入门,至少应该让您了解完成后如何继续。
我不明白为什么必须同时提交客户和来自 child table 的记录。
当你想添加一个额外的地址时,那么添加地址按钮和代码现在必须检查+测试主要客户是否已经存在,如果客户记录存在则使用单独的逻辑来处理,或者才不是。如果用户输入了客户姓名和信息,但还没有地址,因为 phone 上的客户可能刚刚搬家,必须用新地址回拨。我可以想到另外六个案例,在这些案例中构建必须同时添加客户和客户地址记录的设计。
正如其他人指出的那样,任何关系数据库(包括 Access)都会遇到此问题。我还应该指出,如果您使用 Access 作为 SQL 服务器或 Oracle 的前端,Access 在这里的工作方式完全相同。
因此,构建一个不同的 UI 和编码过程来添加客户和地址,然后构建不同的规则集和 UI 来随着时间的推移添加额外的地址是没有意义的。所以构建一个表单来搜索+查找客户,然后添加该客户并显示该客户。完成该过程后,您可以添加该过程(和 UI 部分)以允许用户查看或向该客户添加地址。我不认为我见过 UI 有单独的表格给 add/edit 客户和单独的表格允许额外的地址有一些要求他们同时提交。
如果用户因为地址不可用、错误等原因退出地址,这不应该暗示到目前为止输入的客户信息被丢弃而不添加。如果用户在添加地址后放弃(例如关闭或取消该表格),那么您 return 到客户表格。如果用户出于某种奇怪的原因在那个时间点决定不再希望该客户出现在系统中,则提供一个删除按钮。
如果业务规则是在所有情况下都必须始终至少有一个地址,那么在关闭客户表单时您不允许关闭该表单并要求该用户至少输入一个地址这个用户。也许他们按错了键以退出地址输入部分——无需惩罚该用户并强迫他们 re-enter 客户信息。因此,在他们输入地址或向他们提供(向用户建议)之前,不要让他们退出客户表单,他们可以 delete/remove 他们想要退出的客户。
如果您使用表单 + 子表单设置,则关系部分需要零代码。选项卡控件让您可以将两种形式都接近全屏大小。 (无需启动单独的表单)。
当然,您可以编写一堆代码并将所有内容都放在事务中,但这是在浪费编码时间,没有任何好处,并且在不需要时相当于盗用公司时间和时间。
关于您的陈述:
It's not practical to force the Customer row to be added before opening Form2 as some Customer required fields are not present at that point in the workflow.
如果 "required but not yet known" 字段的 Required
属性 设置为 Yes
(即,不为空)。但是,对于 Access 2010 及更高版本,您可以使用事件驱动的数据宏来使此类字段在插入时 "not required" 但在更新时 "required"。在你的情况下,你可以
- 允许在没有 "eventually required" 字段的情况下插入客户记录,
- 允许添加 CustomerAddress 记录(启用 RI),然后
- 重新打开客户记录进行更新,数据宏现在强制其他字段的 "required" 状态。
更改前的数据宏可能如下所示: