Zwykle, jeśli chcesz usunąć klucz obcy w SQL, użyjesz ALTER TABLE
oświadczenie. Ale jeśli używasz SQLite, to nie jest opcja.
SQLite obsługuje bardzo ograniczony podzbiór ALTER TABLE
oświadczenie. Jedyne rzeczy, które możesz zrobić z ALTER TABLE
w SQLite to zmiana nazwy tabeli, zmiana nazwy kolumny w tabeli lub dodanie nowej kolumny do istniejącej tabeli.
Innymi słowy, nie możesz użyć ALTER TABLE
aby usunąć klucz obcy, tak jak w innych systemach RDBMS
Zalecanym sposobem „upuszczenia” klucza obcego w SQLite jest przeniesienie danych do nowej tabeli bez klucza obcego (lub z innym, jeśli tego potrzebujesz).
Zalecany sposób
Dokumentacja SQLite zaleca 12-etapowy proces wprowadzania zmian w schemacie do tabeli. Wykorzystamy ten proces do „upuszczenia” klucza obcego w poniższym przykładzie.
Utwórz tabelę z kluczem obcym
Najpierw utwórzmy tabelę z kluczem obcym i wypełnijmy ją danymi.
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 );
Właściwie tutaj stworzyłem dwie tabele i wypełniłem je danymi. Dwie tabele, ponieważ pierwsza (Typy ) ma klucz podstawowy, a drugi (Zwierzęta domowe ) ma klucz obcy. Klucz obcy został dodany w ostatnim wierszu drugiej tabeli.
Możemy sprawdzić, czy klucz obcy został utworzony, uruchamiając następujące polecenie:
PRAGMA foreign_key_list(Pets);
Wynik:
id seq table from to on_update on_delete match -- --- ----- ------ ------ --------- --------- ----- 0 0 Types TypeId TypeId NO ACTION NO ACTION NONE
Możemy zobaczyć szczegóły ograniczenia klucza obcego.
Teraz „upuśćmy” klucz obcy.
„Upuść” klucz obcy
Poniższy kod „upuszcza” klucz obcy, tworząc nową tabelę bez ograniczenia klucza obcego, przesyłając dane do tej tabeli, usuwając oryginalną tabelę, a następnie zmieniając nazwę nowej tabeli na nazwę oryginalnej tabeli.
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;
Gotowe.
Jeśli potrzebujesz zrekonstruować jakiekolwiek indeksy, wyzwalacze lub widoki, zrób to po ALTER TABLE
instrukcja zmieniająca nazwę tabeli (tuż przed COMMIT
).
Teraz ponownie sprawdźmy tabelę pod kątem ograniczeń kluczy obcych.
PRAGMA foreign_key_list(Pets);
Wynik:
(To pole jest puste, ponieważ w tej tabeli nie ma ograniczeń klucza obcego).
Możesz użyć tej samej metody, aby dodać klucz obcy do istniejącej tabeli.
Alternatywna metoda
Patrząc na poprzedni przykład, możesz pomyśleć, że jest na to bardziej efektywny sposób. Na przykład możesz to zrobić tak:
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;
I to prawda. W moim przykładzie ta metoda działa równie dobrze.
Ale ta metoda może również uszkodzić odniesienia do tabeli w dowolnych istniejących wyzwalaczach, widokach i ograniczeniach kluczy obcych.
Jeśli więc Twoja tabela ma już istniejące wyzwalacze, widoki lub ograniczenia klucza obcego, prawdopodobnie bezpieczniej jest użyć zalecanej metody.