我有函数检查强制参与如下:
CREATE FUNCTION member_in_has_address()
RETURNS BOOLEAN AS $$
BEGIN
RETURN EXISTS (SELECT *
FROM address a, member_details b
WHERE b.member_id = a.member_id);
END;
$$ LANGUAGE plpgsql;
然后从 CHECK 约束中调用
ALTER TABLE member_details
ADD CONSTRAINT member_in_has_address_check
CHECK (member_in_has_address());
要在标准 SQL 中创建可延迟约束,它将是:
ALTER TABLE member_details
ADD CONSTRAINT member_in_has_address_check
INITIALLY DEFERRED
CHECK (member_in_has_address());
我如何在 PostgreSQL 中做同样的事情?
最佳答案
您可以在 PostgreSQL 中以与在其他 RDBMS 中相同的方式延迟约束,但对于当前版本 (9.2),您只能延迟 UNIQUE、PRIMARY KEY、EXCLUDE 和 REFERENCES。摘自 this page
手册:
DEFERRABLE
NOT DEFERRABLE
This controls whether the constraint can be deferred. A constraint that is not deferrable will be checked immediately after every command. Checking of constraints that are deferrable can be postponed until the end of the transaction (using the SET CONSTRAINTS command). NOT DEFERRABLE is the default. Currently, only UNIQUE, PRIMARY KEY, EXCLUDE, and REFERENCES (foreign key) constraints accept this clause. NOT NULL and CHECK constraints are not deferrable.
INITIALLY IMMEDIATE
INITIALLY DEFERRED
If a constraint is deferrable, this clause specifies the default time to check the constraint. If the constraint is INITIALLY IMMEDIATE, it is checked after each statement. This is the default. If the constraint is INITIALLY DEFERRED, it is checked only at the end of the transaction. The constraint check time can be altered with the SET CONSTRAINTS command.
如果每个成员都有一个地址,您可以创建一个从 member_details
到 address
的简单延迟外键来代替当前的约束来检查。
更新:您需要创建 2 个外键。从 address(member_id)
到 member_details(member_id)
的一个常规地址。另一个 - 从 member_details(member_id)
推迟到 address(member_id)
。
有了这两个外键,您将能够:
- 在
member_details
中创建一个成员。 - 在
address
中为第 1 步中的成员创建一个地址 - 提交(没有错误)
或
- 在
member_details
中创建一个成员。 - 提交(并从延迟的外键中获取错误)。
关于sql - PostgreSQL 中的可延迟检查约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16323236/