TRUNCATE, cascade

Tronquer en cascade

      La commande TRUNCATE peut être utilisée en CASCADE au sens des contraintes d’intégrité relationnelle (les clés étrangères). PostgreSQL intègre cette fonctionnalité depuis la version 8.2 tandis qu’Oracle l’intègre depuis la version 12.1 mais quelles sont les différences dans l’implémentation ?
      Tout d’abord un test sous PostgreSQL 9.6 :

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 n’est pas nécessaire que la contrainte soit créée avec l’option 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.
      Test avec Oracle Database dans sa version 12.1.0.2 :

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 d’un 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.

Mise à jour : 22/10/2016