Normalement, si vous devez supprimer une clé étrangère dans SQL, vous utiliserez le ALTER TABLE
déclaration. Mais si vous utilisez SQLite, ce n'est pas une option.
SQLite prend en charge un sous-ensemble très limité de ALTER TABLE
déclaration. Les seules choses que vous pouvez faire avec ALTER TABLE
dans SQLite est de renommer une table, de renommer une colonne dans une table ou d'ajouter une nouvelle colonne à une table existante.
En d'autres termes, vous ne pouvez pas utiliser ALTER TABLE
pour déposer une clé étrangère comme vous pouvez le faire dans d'autres SGBDR
La méthode recommandée pour "supprimer" une clé étrangère dans SQLite consiste en fait à transférer les données vers une nouvelle table sans clé étrangère (ou avec une autre, si c'est ce dont vous avez besoin).
La méthode recommandée
La documentation SQLite recommande un processus en 12 étapes pour apporter des modifications de schéma à une table. Nous utiliserons ce processus pour "supprimer" une clé étrangère dans l'exemple suivant.
Créer une table avec une clé étrangère
Tout d'abord, créons une table avec la clé étrangère et remplissons-la avec des données.
CREATE TABLE Types(
TypeId INTEGER PRIMARY KEY,
Type
);
CREATE TABLE Pets(
PetId INTEGER PRIMARY KEY,
PetName,
TypeId,
FOREIGN KEY(TypeId) REFERENCES Types(TypeId)
);
INSERT INTO Types VALUES
( NULL, 'Dog' ),
( NULL, 'Cat' ),
( NULL, 'Parakeet' ),
( NULL, 'Hamster' );
INSERT INTO Pets VALUES
( NULL, 'Brush', 3 ),
( NULL, 'Tweet', 3 ),
( NULL, 'Yelp', 1 ),
( NULL, 'Woofer', 1 ),
( NULL, 'Fluff', 2 );
En fait, ici, j'ai créé deux tables et les ai remplies avec des données. Deux tableaux, car le premier (Types ) a la clé primaire et l'autre (Pets ) contient la clé étrangère. La clé étrangère a été ajoutée sur la dernière ligne de la deuxième table.
Nous pouvons vérifier que la clé étrangère a été créée en exécutant la commande suivante :
PRAGMA foreign_key_list(Pets);
Résultat :
id seq table from to on_update on_delete match -- --- ----- ------ ------ --------- -------- - ----- 0 0 Types TypeId TypeId AUCUNE ACTION AUCUNE ACTION AUCUNE
Nous pouvons voir les détails de la contrainte de clé étrangère.
Maintenant, "laissons tomber" la clé étrangère.
« Déposez » la clé étrangère
Le code suivant "supprime" la clé étrangère en créant une nouvelle table sans contrainte de clé étrangère, en transférant les données vers cette table, en supprimant la table d'origine, puis en renommant la nouvelle table avec le nom de la table d'origine.
PRAGMA foreign_keys = OFF;
BEGIN TRANSACTION;
CREATE TABLE Pets_new(
PetId INTEGER PRIMARY KEY,
PetName,
TypeId
);
INSERT INTO Pets_new SELECT * FROM Pets;
DROP TABLE Pets;
ALTER TABLE Pets_new RENAME TO Pets;
COMMIT;
PRAGMA foreign_keys = ON;
Terminé.
Si vous avez besoin de reconstruire des index, des déclencheurs ou des vues, faites-le après ALTER TABLE
instruction qui renomme la table (juste avant COMMIT
).
Maintenant, vérifions à nouveau la table pour les contraintes de clé étrangère.
PRAGMA foreign_key_list(Pets);
Résultat :
(Ceci est vide car il n'y a pas de contraintes de clé étrangère sur cette table.)
Vous pouvez utiliser la même méthode pour ajouter une clé étrangère à une table existante.
Une méthode alternative
En regardant l'exemple précédent, vous pensez peut-être qu'il existe un moyen plus efficace de le faire. Par exemple, vous pourriez le faire comme ceci :
PRAGMA foreign_keys = OFF; BEGIN TRANSACTION; ALTER TABLE Pets RENAME TO Pets_old; CREATE TABLE Pets( PetId INTEGER PRIMARY KEY, PetName, TypeId ); INSERT INTO Pets SELECT * FROM Pets_old; DROP TABLE Pets_old; COMMIT; PRAGMA foreign_keys = ON;
Et c'est vrai. Avec mon exemple, cette méthode fonctionne tout aussi bien.
Mais cette méthode a également le potentiel de corrompre les références à la table dans tous les déclencheurs, vues et contraintes de clé étrangère existants.
Ainsi, si votre table possède déjà des déclencheurs, des vues ou des contraintes de clé étrangère, il est probablement plus sûr d'utiliser la méthode recommandée.