使用“Where”类似的注意事项删除另一个表中的相关记录

时间:2012-11-08 22:30:36

标签: sql-server database database-design

我有一个名为OptDefID的主键的数据表。当删除此表中的记录时,我需要删除Permissions表中OptDefID字段defIDPermissions的所有记录。对我来说棘手的部分是Permissions表没有主键并且拥有许多不同类型的权限,并且具有permissiontype字段。我需要删除OptDefIDpermissiontype OptDef的行。

因为我需要考虑权限类型,我不相信外键约束在这里是适当的(或者是吗?)。

我也考虑过创建一个触发器,但我不确定如何将OptDefID传递给触发器。

我可以通过应用程序本身来做到这一点,但我觉得这应该是一个数据库级别的解决方案。

什么是最好的解决方案?

3 个答案:

答案 0 :(得分:0)

如果仅在有问题的记录引用OptDefId表时填充Permissions列,则外键应该是合适的。即你有另一列MemberId,它可以是Members表上的外键。

只有当你有一个列时 - 让我们称之为ObjectId - 当type列的内容发生变化时,它会带来其他含义,即你不能使用外键。 在这种情况下,触发器可能是最好的方法,正如您已经猜到的那样。我只知道Oracle PL / SQL中的触发器,它们作为表示旧状态和新状态的单独完整行传递。我想它在MS-SQL-Server中类似。

答案 1 :(得分:0)

除了使用SELECT语句加入,您还可以加入DELETE&中的多个表格。 UPDATE语句也是如此。

根据我的理解问题,您应该可以使用Permissions列&列加入OptDefID表格。添加类似于此的WHERE子句:

DELETE MyTable
...
WHERE [Permissions].permissiontype = 'OptDef'

此外,这些链接也可能是有意义的:

答案 2 :(得分:0)

  

假设我要从权限中删除,其中defID为20,权限类型为“OptDef”。权限中可能有另一行的defID为20,但权限类型为“Member”。不应删除该节目,因为它与会员有关,而非选择数据。

在字段中存储表名可以防止外键正常工作,如您所发现的那样。

我建议你修复root问题并分开这两个外键,这样每个外键都可以单独执行。例如:

CREATE TABLE Permissions (
    ...
    OptDefId int,
    MemberId int,
    FOREIGN KEY (OptDefId) REFERENCES OptDef ON DELETE CASCADE,
    FOREIGN KEY (MemberId) REFERENCES Members ON DELETE CASCADE,
    CHECK (
        (OptDefId IS NOT NULL AND MemberId IS NULL)
        OR (OptDefId IS NULL AND MemberId IS NOT NULL)
    )
)

CHECK确保只有一个FK非NULL,并且只强制执行非NULL FK。

或者,您可以避免更改当前设计并通过触发器强制执行此“特殊”FK,但在可能的情况下,声明性约束应优先于触发器 - 声明性约束往往会留下更少的错误空间并且更加“自我记录” ”