Pokud potřebujete v SQL zahodit cizí klíč, normálně byste použili ALTER TABLE
prohlášení. Ale pokud používáte SQLite, není to možné.
SQLite podporuje velmi omezenou podmnožinu ALTER TABLE
prohlášení. Jediné, co můžete dělat s ALTER TABLE
v SQLite je přejmenování tabulky, přejmenování sloupce v tabulce nebo přidání nového sloupce do existující tabulky.
Jinými slovy, nemůžete použít ALTER TABLE
zahodit cizí klíč, jako můžete v jiných RDBMS
Doporučený způsob, jak „upustit“ cizí klíč v SQLite, je ve skutečnosti přenést data do nové tabulky bez cizího klíče (nebo s jiným, pokud to potřebujete).
Doporučený způsob
Dokumentace SQLite doporučuje proces o 12 krocích pro provádění změn schématu v tabulce. Tento proces použijeme k „vypuštění“ cizího klíče v následujícím příkladu.
Vytvořte tabulku s cizím klíčem
Nejprve vytvořte tabulku s cizím klíčem a naplňte ji daty.
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 );
Ve skutečnosti jsem zde vytvořil dvě tabulky a naplnil je daty. Dvě tabulky, protože první (Typy ) má primární klíč a druhý (Domácí mazlíčci ) má cizí klíč. Cizí klíč byl přidán na poslední řádek druhé tabulky.
Že byl cizí klíč vytvořen, můžeme ověřit spuštěním následujícího příkazu:
PRAGMA foreign_key_list(Pets);
Výsledek:
id seq table from to on_update on_delete match -- --- ----- ------ ------ --------- --------- ----- 0 0 Types TypeId TypeId NO ACTION NO ACTION NONE
Můžeme vidět podrobnosti o omezení cizího klíče.
Nyní „zahodíme“ cizí klíč.
Zahoďte cizí klíč
Následující kód „zahodí“ cizí klíč vytvořením nové tabulky bez omezení cizího klíče, přenesením dat do této tabulky, zrušením původní tabulky a poté přejmenováním nové tabulky na název původní tabulky.
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;
Hotovo.
Pokud potřebujete rekonstruovat nějaké indexy, spouštěče nebo pohledy, udělejte to za ALTER TABLE
příkaz, který přejmenuje tabulku (těsně před COMMIT
).
Nyní znovu zkontrolujte tabulku pro omezení cizího klíče.
PRAGMA foreign_key_list(Pets);
Výsledek:
(To je prázdné, protože v této tabulce nejsou žádná omezení cizího klíče.)
Stejnou metodu můžete použít k přidání cizího klíče do existující tabulky.
Alternativní metoda
Když se podíváte na předchozí příklad, možná vás napadne, že existuje efektivnější způsob, jak to udělat. Můžete to udělat například takto:
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;
a je to pravda. S mým příkladem tato metoda funguje stejně dobře.
Ale tato metoda má také potenciál poškodit odkazy na tabulku ve všech existujících spouštěčích, pohledech a omezeních cizích klíčů.
Pokud tedy vaše tabulka již obsahuje spouštěče, pohledy nebo omezení cizích klíčů, je pravděpodobně bezpečnější použít doporučenou metodu.