什么时候评估检查约束?

When are check constraints evaluated?

我有 table 条记录

ID
EntityID 
Value
Status

和 table 个实体

ID
Col1
Col2
CurrentRecordID

CurrentRecordID 应该是与 Entity 相关联的 RecordStatus 为 0

我有两个检查约束 一个在 table Entity 上检查以确保 CurrentRecordID 实际上是当前记录,另一个在 Record 上检查以确保它的状态是否为0,其 EntityID 具有与其 ID 匹配的 CurrentRecordID

所以本质上,两个检查约束做同样的事情,但分别在每个 table

在事务的最后检查约束 运行 还是在 table 上的每个 insert/update 之后它们 运行 喜欢触发器?

如果它们 运行 在每次修改后,这两个约束是否会相互冲突(意思是,约束将在下一个 table 有机会更新其值之前抛出错误)。

这是一个查询示例,运行s 插入新记录,并将其设置为给定实体的当前记录

UPDATE Record SET Status = 1 WHERE Status = 0 AND EntityID = @EntityID
INSERT INTO Record(EntityID, Value, Status) VALUES(@EntityID, 100, 0)
DECLARE @RecordID INT = @@IDENTITY
UPDATE Entity SET CurrentRecordID = RecordID WHERE ID = @EntityID

约束不像触发器那样运行。他们在更改数据之前评估规则。

约束检查在尝试更改数据时发生。如果对 Table1 的尝试更改未通过检查约束,它将通过异常。

为了完成 Sean Lange 给出的解释,请允许我留下一个 ready-to-run 示例,以便您亲眼看到在任何数据修改之前如何执行 table check

CREATE TABLE pepe (
    id serial,
    state text NOT NULL
);
ALTER TABLE pepe ADD CONSTRAINT pepe_pk PRIMARY KEY (id);


CREATE OR REPLACE FUNCTION pepe_check_func() RETURNS boolean AS
$BODY$
  DECLARE
    temp_row record;
  BEGIN
    RAISE INFO 'Displaying existing pepe records';
    FOR temp_row IN
        SELECT id,state
        FROM pepe
    LOOP
        RAISE INFO '(id,state) = (%,%)',temp_row.id, temp_row.state;
    END LOOP;
    RETURN TRUE;
  END;
$BODY$ LANGUAGE plpgsql IMMUTABLE;

ALTER TABLE pepe ADD CONSTRAINT pepe_check
CHECK (pepe_check_func());


insert into pepe (state) values ('go');

update pepe
set state = 'active';

select *
from pepe;