【问题标题】:For all records in a table how to guarantee at least one record on a foreign key related table?对于一个表中的所有记录,如何保证外键相关表上至少有一条记录?
【发布时间】:2012-12-16 13:20:44
【问题描述】:

假设数据库中有两个表。第一个是 X,第二个是 Y。Y 表在 X 表上有一个外键。因此,如果 Y 表上有记录,则它的外键相关列值必须存在于 X 表上。这是默认行为。

   X         Y
-------   -------
  ID        ID
            XID <--- Foreignkey to X table.

现在,对于 X 表中的所有记录,我想保证 Y 表上必须至少有一条记录。如果没有,它应该自动添加一个。我该怎么做?

【问题讨论】:

  • 嗯,你正在从 X 的 Y 表中设置一个外键。所以你输入到 Y 表的每条记录都会有XID 不是吗? (鉴于外键不能为空)那么问题是什么?我假设你的意思是说 “现在,对于 Y 表中的所有记录,我想保证 X 表上必须至少有一条记录。如果没有,它应该自动添加一条。”
  • 我想我无法解释我想要什么。认为有一本书,我想保证至少有一页。假设 book 和 page 是数据库中的表。

标签: sql stored-procedures triggers foreign-key-relationship


【解决方案1】:

这里有两个不同的问题。

  1. 管理声明性约束。
  2. 管理插入、更新和删除。

保证 x 中的每一行在 y 中都存在一行的“正常”方法是在 both 表中包含外键。每个表都引用另一个。

create table x (
  x_id integer primary key,
  y_id integer not null
);

create table y (
  y_id integer primary key,
  x_id integer not null references x (x_id)
);

alter table x
add constraint one_to_one
foreign key (y_id)
  references y (y_id) deferrable initially deferred;

begin transaction;
insert into x values (1, 100);
insert into y values (100, 1);
commit;

虽然这保证了每个“x”都有一个“y”,但可以这么说,它并不能保证每个“x”都有一个不同的“y”,或者每个“x” " 有自己的 "y"。我不确定这是否是您的要求。

这不是完全您要查找的内容,因为您的两个表之间存在 1:N 关系。你可以让它工作,但我认为你必须编写一个触发器来管理对表“y”的更改。例如,如果用户从“y”中删除“x”持有外键引用的行,则需要更新“x”以引用“y”中的不同行。

但这会导致第二个问题:管理插入、更新和删除。有几种方法可以做到这一点。

  • 客户端负责提供保持数据库一致所需的所有语句。 (上述外键问题可能例外,最好在“y”上的触发器中处理。)
  • 客户端无法直接访问基表。所有更改都通过存储过程。
  • 客户端无法直接访问基表。所有更改都通过可更新的视图进行。

存储过程和可更新视图可以让您在一定程度上自动在“y”中添加一行,但您必须编写过程代码才能做到这一点。

【讨论】:

  • 感谢您的回答。在我看来,Storedprocs 是最好的方法。
【解决方案2】:

要将丢失的记录插入Y 以获取现有数据,您可以运行类似

INSERT INTO Y(xid)
SELECT x.id 
FROM x 
WHERE NOT EXISTS(SELECT NULL FROM Y a WHERE a.xid = x.id);

为了以后防止这样的事情发生,写一个在2个表中插入数据的过程,防止大家直接往表中插入数据(只能通过这个过程)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-28
    • 1970-01-01
    • 1970-01-01
    • 2010-09-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多