在SQL编码中可以在TRIGGER中使用DEFERRABLE吗? DEFERRABLE如何工作?

时间:2015-04-18 19:55:21

标签: sql oracle triggers

可以在触发器中使用DEFERRABLE吗?

DEFERRABLE的概念是如何运作的?

在整个交易期间,它会在所有操作结束时检查约束吗?

1 个答案:

答案 0 :(得分:6)

看起来你的意思是PostgresSql。 DEFERRABLE CONSTRAINT的概念是在事务过程中可能暂时失效的概念(使用SET CONSTRAINTS ... DEFERRED;命令),但约束必须在事务提交时再次有效。

例如,下面有一个FOREIGN KEY约束强制执行从Table2.Table1IDTable1.ID的参照完整性:

CREATE TABLE Table1
(
  ID INT NOT NULL,
  Name VARCHAR(50),
  CONSTRAINT PK_Table1 PRIMARY KEY(ID)
);

CREATE TABLE Table2
(
  ID INT NOT NULL,
  Table1ID INT NOT NULL,
  Name VARCHAR(50),
  CONSTRAINT PK_Table2 PRIMARY KEY(ID),
  CONSTRAINT FK_Table2_Table1 FOREIGN KEY(Table1ID) REFERENCES Table1(ID) DEFERRABLE
);

通常情况下,如果没有Table1.ID = 2

,则下面的插入会失败
INSERT INTO TABLE2(ID, Table1Id, Name) VALUES (2, 2, 'Foreign Key Violation');

但是,因为CONSTRAINT被定义为DEFERRABLE(并且我们在下面的事务中允许延迟约束),这意味着我们可能会暂时违反约束,前提是约束在时间满足时交易已提交。在下面的示例中,我们通过在表1中插入一个额外的行来解决外键冲突,以安抚参照完整性约束。

BEGIN TRANSACTION;
SET CONSTRAINTS ALL DEFERRED;
INSERT INTO Table2(ID, Table1Id, Name) VALUES (2, 2, 'Foreign Key Violation Allowed');
INSERT INTO Table1(ID, Name) VALUES (2, 'Fix the Violation');
COMMIT TRANSACTION;

SqlFiddle of a DEFERRED RI insert here

关于触发器,DEFERRED只能与CONSTRAINT TRIGGERS一起使用,但上述相同的原则适用。