Wenn Sie normalerweise einen Fremdschlüssel in SQL löschen müssen, verwenden Sie ALTER TABLE
Erklärung. Aber wenn Sie SQLite verwenden, ist das keine Option.
SQLite unterstützt eine sehr begrenzte Teilmenge von ALTER TABLE
Erklärung. Das Einzige, was Sie mit ALTER TABLE
tun können in SQLite ist das Umbenennen einer Tabelle, das Umbenennen einer Spalte innerhalb einer Tabelle oder das Hinzufügen einer neuen Spalte zu einer bestehenden Tabelle.
Mit anderen Worten, Sie können ALTER TABLE
nicht verwenden um einen Fremdschlüssel zu löschen, wie Sie es in anderen RDBMSs können
Die empfohlene Methode zum „Löschen“ eines Fremdschlüssels in SQLite besteht darin, die Daten in eine neue Tabelle ohne Fremdschlüssel (oder mit einem anderen, falls erforderlich) zu übertragen.
Der empfohlene Weg
Die SQLite-Dokumentation empfiehlt einen 12-Schritte-Prozess zum Vornehmen von Schemaänderungen an einer Tabelle. Wir werden diesen Prozess verwenden, um im folgenden Beispiel einen Fremdschlüssel zu „löschen“.
Erstellen Sie eine Tabelle mit einem Fremdschlüssel
Lassen Sie uns zunächst eine Tabelle mit dem Fremdschlüssel erstellen und mit Daten füllen.
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 );
Eigentlich habe ich hier zwei Tabellen erstellt und mit Daten gefüllt. Zwei Tabellen, denn die erste (Types ) hat den Primärschlüssel und der andere (Haustiere ) hat den Fremdschlüssel. Der Fremdschlüssel wurde in der letzten Zeile der zweiten Tabelle hinzugefügt.
Wir können überprüfen, ob der Fremdschlüssel erstellt wurde, indem wir den folgenden Befehl ausführen:
PRAGMA foreign_key_list(Pets);
Ergebnis:
id seq table from to on_update on_delete match -- --- ----- ------ ------ --------- --------- ----- 0 0 Types TypeId TypeId NO ACTION NO ACTION NONE
Wir können die Details der Fremdschlüsseleinschränkung sehen.
Lassen Sie uns nun den Fremdschlüssel „fallen“ lassen.
Den Fremdschlüssel „löschen“
Der folgende Code „löscht“ den Fremdschlüssel, indem er eine neue Tabelle ohne Fremdschlüsseleinschränkung erstellt, die Daten in diese Tabelle überträgt, die ursprüngliche Tabelle löscht und dann die neue Tabelle in den Namen der ursprünglichen Tabelle umbenennt.
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;
Fertig.
Wenn Sie Indizes, Trigger oder Ansichten rekonstruieren müssen, tun Sie dies nach ALTER TABLE
Anweisung, die die Tabelle umbenennt (kurz vor COMMIT
).
Lassen Sie uns nun die Tabelle erneut auf Fremdschlüsseleinschränkungen überprüfen.
PRAGMA foreign_key_list(Pets);
Ergebnis:
(Das ist leer, weil es für diese Tabelle keine Fremdschlüsseleinschränkungen gibt.)
Sie können dieselbe Methode verwenden, um einer vorhandenen Tabelle einen Fremdschlüssel hinzuzufügen.
Eine alternative Methode
Wenn Sie sich das vorherige Beispiel ansehen, denken Sie vielleicht, dass es einen effizienteren Weg gibt, dies zu tun. Sie könnten es zum Beispiel so machen:
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;
Und es ist wahr. Bei meinem Beispiel funktioniert diese Methode genauso gut.
Aber diese Methode hat auch das Potenzial, Verweise auf die Tabelle in allen vorhandenen Triggern, Ansichten und Fremdschlüsseleinschränkungen zu beschädigen.
Wenn Ihre Tabelle also bereits über vorhandene Auslöser, Ansichten oder Fremdschlüsseleinschränkungen verfügt, ist es wahrscheinlich sicherer, die empfohlene Methode zu verwenden.