SELECT version();
version
------------------------------------------------------------------------------------------
PostgreSQL 9.6.0 on x86_64-pc-linux-gnu, compiled by gcc (Debian 4.9.2-10) 4.9.2, 64-bit
(1 ligne)
CREATE TABLE t1(c11 SERIAL PRIMARY KEY, C12 INTEGER);
CREATE TABLE
CREATE TABLE t2(c21 SERIAL PRIMARY KEY, C22 INTEGER REFERENCES t1(c11));
CREATE TABLE
postgres=# INSERT INTO t1(c12) VALUES(generate_series(1,999));
INSERT 0 999
postgres=# INSERT INTO t2(c22) VALUES(generate_series(1,999));
INSERT 0 999
INSERT INTO t2(c22) VALUES(NULL);
INSERT 0 1
postgres=# DELETE FROM t1;
ERREUR: UPDATE ou DELETE sur la table t1 viole la contrainte de clé étrangère
t2_c22_fkey de la table t2
DÉTAIL : La clé (c11)=(1) est toujours référencée à partir de la table t2.
postgres=# DELETE FROM t1 CASCADE;
ERREUR: UPDATE ou DELETE sur la table t1 viole la contrainte de clé étrangère
t2_c22_fkey de la table t2
DÉTAIL : La clé (c11)=(1) est toujours référencée à partir de la table t2.
TRUNCATE TABLE t1;
ERREUR: ne peut pas tronquer une table référencée dans une contrainte de clé étrangère
DÉTAIL : La table t2 référence t1.
ASTUCE : Tronquez la table t2 en même temps, ou utilisez TRUNCATE ... CASCADE.
TRUNCATE TABLE t1 CASCADE;
NOTICE: TRUNCATE cascade sur la table t2
TRUNCATE TABLE
postgres=# SELECT * FROM t1;
c11 | c12
-----+-----
(0 ligne)
postgres=# SELECT * FROM t2;
c21 | c22
-----+-----
(0 ligne)
Il est bien possible de tronquer en cascade et il nest pas nécessaire que la contrainte soit créée avec loption ON DELETE CASCADE pour que cela fonctionne avec PostgreSQL. Par ailleurs attention, contrairement à ce qui se passe avec un DELETE, les lignes pour lesquelles la clé étrangère est NULLE sont supprimées.
Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
CREATE TABLE t1(c11 INTEGER GENERATED AS IDENTITY PRIMARY KEY, C12 INTEGER);
Table created.
CREATE TABLE t2(c21 INTEGER GENERATED AS IDENTITY PRIMARY KEY, C22 INTEGER REFERENCES t1(c11) ON DELETE CASCADE);
Table created.
INSERT INTO t1(c12) SELECT ROWNUM FROM all_objects WHERE ROWNUM < 1000;
999 rows created.
INSERT INTO t2(c22) SELECT ROWNUM FROM all_objects WHERE ROWNUM < 1000;
999 rows created.
INSERT INTO t2(c22) VALUES(NULL);
1 row created.
COMMIT;
Commit complete.
TRUNCATE TABLE t1;
TRUNCATE TABLE t1
*
ERROR at line 1:
ORA-02266: unique/primary keys in table referenced by enabled foreign keys
TRUNCATE TABLE t1 CASCADE;
TRUNCATE TABLE t1 CASCADE
*
ERROR at line 1:
ORA-14705: unique or primary keys referenced by enabled foreign keys in table "PHIL"."T2"
DROP TABLE t2;
Table dropped.
CREATE TABLE t2(c21 INTEGER GENERATED AS IDENTITY PRIMARY KEY, C22 INTEGER REFERENCES t1(c11) ON DELETE CASCADE);
Table created.
INSERT INTO t2(c22) SELECT ROWNUM FROM all_objects WHERE ROWNUM < 1000;
999 rows created.
INSERT INTO t2(c22) VALUES(NULL);
1 row created.
COMMIT;
TRUNCATE TABLE t1;
TRUNCATE TABLE t1
*
ERROR at line 1:
ORA-02266: unique/primary keys in table referenced by enabled foreign keys
TRUNCATE TABLE t1 CASCADE;
Table truncated.
SELECT * FROM t1;
no rows selected
SELECT * FROM t2;
no rows selected
Oracle et PostgreSQL se comportent de la même façon lors dun TRUNCATE .. CASCADE en ce qui concerne les valeurs nulles au niveau des clés étrangères. Les lignes sont TOUTES supprimées au niveau de la table fille. En revanche, au contraire de ce qui se passe avec PostgreSQL, Oracle ne réalisera le TRUNCATE .. CASCADE que si ON DELETE CASCADE est positionnée au niveau de la contrainte de clé étrangère.