更新SQL'关系'表的有效方法

时间:2010-06-15 05:06:47

标签: sql mysql web-applications normalization

假设我有三个正确规范化的表。其中一个人,一个资格证书和一个人员资格证书:

人:

id | Name
----------
1  | Alice
2  | Bob

度:

id | Name
---------
1  | PhD
2  | MA

人到度:

person_id | degree_id
---------------------
1         | 2         # Alice has an MA
2         | 1         # Bob has a PhD

那么我必须通过我的网络界面更新这个映射。 (我犯了一个错误。鲍勃有一个学士学位,而不是博士学位,爱丽丝刚拿到她的B英雄。)

这些一对多关系映射有四种可能的状态:

  • 以前是真的,现在应该是假的
  • 以前是假的,现在应该是真的
  • 之前是真的,应该保持真实
  • 之前是假的,应该保持虚假

我不想做的是从四个复选框中读取值,然后点击数据库四次说“Bob之前有过BA吗?他现在做了。” “Bob之前是否拥有博士学位?因为他不再拥有博士学位”等等。

其他人如何解决此问题?

我很想知道其他人是否达到了我所做的相同解决方案。

UPDATE 1 :onedaywhen建议我发生同样的事情 - 只需删除所有旧条目,无论是否正确,并插入新条目。

更新2 :potatopeelings建议在表单中添加一些代码,用于存储字段的原始值,可以与提交时的新值进行比较。

2 个答案:

答案 0 :(得分:2)

逻辑上,UPDATEDELETE后跟INSERT(考虑到SQL Server触发器可以访问名为inserteddeleted的逻辑表但是那里不是updated表。所以你应该能够只打两次数据库,即Bob的所有行(正确或其他)的第一个DELETE,Bob的第二个INSERT所有正确的行。

如果您只想访问数据库一次,请考虑使用标准SQL的MERGE,假设您的DBMS支持它(SQL Server于2008年推出)。

答案 1 :(得分:0)

假设UI是一个复选框网格(问题中的Ismail评论中的1.)

           MA      PhD    
Alice      x 
Bob                 x

其中x代表复选框。我会使用前端脚本仅将更改发送回服务器。然后在单个事务下的People-to-degrees中执行INSERT和DELETE,或者使用MERGE(如Ismail链接中所指出的那样)

BEGIN TRAN
INSERT query
DELETE query
COMMIT

您可以通过INSERT(和DELETE)查询人员ID列表,学位ID对等。对于您的示例,INSERT查询将是单对(2,2),对于DELETE查询将是单对(2,1)。