I have the following test case:
DROP SCHEMA IF EXISTS test CASCADE;
CREATE SCHEMA test;
CREATE TABLE test.quz (
foo int,
bar int,
PRIMARY KEY ( foo, bar )
);
CREATE TABLE test.quuz (
foo int,
bar int,
baz int,
PRIMARY KEY ( foo, bar ),
FOREIGN KEY ( foo, bar ) REFERENCES test.quz MATCH FULL
);
INSERT INTO test.quz VALUES ( 1, 2 );
INSERT INTO test.quuz VALUES ( 1, 2, 3 );
However, even when deferred
this doesn't seem to work.
BEGIN;
SET CONSTRAINTS ALL DEFERRED;
UPDATE test.quz SET bar = 100 where bar = 2;
UPDATE test.quuz SET bar = 100 where bar = 2;
COMMIT;
END;
Is there any reason? Can this task be done without the terseness of manually deleteing and re-inserting ro开发者_C百科ws?
DEFERRABLE
means that constraints are checked at the end of each statement. DEFERRABLE INITIALLY DEFERRED
, means that constraints are checked at the end of the transaction.
This should work in your case:
CREATE TABLE test.quuz (
foo int,
bar int,
baz int,
PRIMARY KEY ( foo, bar ),
FOREIGN KEY ( foo, bar ) REFERENCES test.quz MATCH FULL DEFERRABLE INITIALLY DEFERRED
);
...
BEGIN;
UPDATE test.quz SET bar = 100 where bar = 2;
UPDATE test.quuz SET bar = 100 where bar = 2;
COMMIT;
This will probably work too:
CREATE TABLE test.quuz (
foo int,
bar int,
baz int,
PRIMARY KEY ( foo, bar ),
FOREIGN KEY ( foo, bar ) REFERENCES test.quz MATCH FULL DEFERRABLE
);
...
BEGIN;
SET CONSTRAINTS ALL DEFERRED;
UPDATE test.quz SET bar = 100 where bar = 2;
UPDATE test.quuz SET bar = 100 where bar = 2;
COMMIT;
Unless I am mistaking, the issue in your definitions is that you don't mark your constraints as deferrable. So Postgres treats them as NOT DEFERRABLE INITIALLY IMMEDIATE
(i.e. the default in Postgres in spite of the SQL standard, the rational being that it is fastest) irrespective of SET CONSTRAINTS
(which only affects deferrable constraints).
精彩评论