sql - PostgreSQL 中的可延迟检查约束

标签 sql postgresql deferred deferrable-constraint

我有函数检查强制参与如下:

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_detailsaddress 的简单延迟外键来代替当前的约束来检查。

更新:您需要创建 2 个外键。从 address(member_id)member_details(member_id) 的一个常规地址。另一个 - 从 member_details(member_id) 推迟到 address(member_id)

有了这两个外键,您将能够:

  1. member_details 中创建一个成员。
  2. address 中为第 1 步中的成员创建一个地址
  3. 提交(没有错误)

  1. member_details 中创建一个成员。
  2. 提交(并从延迟的外键中获取错误)。

关于sql - PostgreSQL 中的可延迟检查约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16323236/

相关文章:

SQL 字符串连接,仅当 column 不为 null 时才以 ',' 分隔

sql - 不支持表/列名称中的方括号?

sql - 使用数据库链接调用oracle函数

sql - 如何使 PostgresQL 优化器在绑定(bind)参数后构建执行计划?

javascript - 如何从延迟对象返回函数

sql - Oracle SQL 语句中条件的顺序重要吗?

java - jOOQ - 选择查询数组

postgresql - 带分区的 Postgres BRIN 索引

javascript - 我应该返回 deferred.resolve/reject 的结果吗?

go - 如何在延迟函数中延迟执行参数