Home > pgsql > 参照制約の遅延

参照制約の遅延

外部参照制約はデフォルトでは NOT DEFERREABLE つまり遅延評価できない。 トランザクション内であっても、データが挿入された時点でエラーになる。 DEFERREABLE にしておくと、SET CONSTRAINTS で遅延評価するよう設定できる。 INITIALLY DEFERRED にしておくと、最初から遅延評価するようになる。
test=> create table a(i int primary key);
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "a_pkey" for table "a"
CREATE TABLE
test=> create table b (i int references a);
CREATE TABLE
test=> begin;
BEGIN
test=> insert into b values (1);
ERROR:  insert or update on table "b" violates foreign key constraint "b_i_fkey"
DETAIL:  Key (i)=(1) is not present in table "a".

-- デフォルトでは NOT DEFERREABLE なので
-- トランザクションをCOMMITする前に参照制約エラーになる

test=> abort;
ROLLBACK
test=> set constraints b_i_fkey deferred;
ERROR:  constraint "b_i_fkey" is not deferrable

-- set constraints で deferred にすることもできない。

test=> drop table b;
DROP TABLE
test=> create table b (i int references a deferrable);
CREATE TABLE

-- 遅延可能にする
test=> begin;
BEGIN
test=> set constraints b_i_fkey deferred;
SET CONSTRAINTS
test=> insert into b values (20);
INSERT 257966 1
test=> commit;
ERROR:  insert or update on table "b" violates foreign key constraint "b_i_fkey"
DETAIL:  Key (i)=(20) is not present in table "a".

-- コミットされる時にはじめて制約チェックする

-- 最初から deferred にする
test=> drop table b;
DROP TABLE
test=> create table b (i int references a initially deferred);
CREATE TABLE
test=> begin;
BEGIN
test=> insert into b values (1);
INSERT 257945 1
test=> insert into a values (1);
INSERT 257946 1
test=> commit;
COMMIT

Writeback:0

Comment Form

writeback message: Ready to post a comment.

TrackBack ping me at
http://www.mono-space.net/blog/pgsql/050214deferred.trackback

Page Top