PostgreSQL中的延迟检查约束

Rad*_*tak 12 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;
Run Code Online (Sandbox Code Playgroud)

然后从CHECK约束调用

ALTER TABLE member_details
 ADD CONSTRAINT member_in_has_address_check
  CHECK (member_in_has_address());
Run Code Online (Sandbox Code Playgroud)

要在标准SQL中创建deferred约束,它将是:

ALTER TABLE member_details
 ADD CONSTRAINT member_in_has_address_check
  INITIALLY DEFERRED
  CHECK (member_in_has_address()); 
Run Code Online (Sandbox Code Playgroud)

我怎么能在PostgreSQL中做同样的事情?

Igo*_*nko 16

您可以像在其他RDBMS中一样在Postgresql中设置约束,但对于当前版本(9.2),您只能使用UNIQUE,PRIMARY KEY,EXCLUDE和REFERENCES.摘自this page手册:

DEFERRABLE
NOT DEFERRABLE

这可以控制是否可以延迟约束.在每个命令之后立即检查不可延迟的约束.检查可延迟的约束可以推迟到事务结束(使用SET CONSTRAINTS命令).NOT DEFERRABLE是默认值.目前,只有UNIQUE,PRIMARY KEY,EXCLUDE和REFERENCES(外键)约束接受此子句.NOT NULL和CHECK约束不可延迟.

INITIALLY IMMEDIATE
INITIALLY DEFERRED

如果约束是可延迟的,则此子句指定检查约束的默认时间.如果约束是INITIALLY IMMEDIATE,则在每个语句后检查它.这是默认值.如果约束是INITIALLY DEFERRED,则仅在事务结束时检查.可以使用SET CONSTRAINTS命令更改约束检查时间.

如果每个成员都有一个地址,您可以创建一个简单的延迟外键member_details,address而不是当前约束来检查.

更新:您需要创建2个外键.一个经常从一个address(member_id)member_details(member_id).另一种-从defferred member_details(member_id)address(member_id).

使用这两个外键,您将能够:

  1. 在中创建成员member_details.
  2. address步骤1 中为成员创建地址
  3. 提交(没有错误)

要么

  1. 在中创建成员member_details.
  2. 提交(并从defferred外键获取错误).