Normalt om du behöver släppa en främmande nyckel i SQL, skulle du använda ALTER TABLE
påstående. Men om du använder SQLite är det inte ett alternativ.
SQLite stöder en mycket begränsad delmängd av ALTER TABLE
påstående. Det enda du kan göra med ALTER TABLE
i SQLite byter man namn på en tabell, byter namn på en kolumn i en tabell eller lägger till en ny kolumn i en befintlig tabell.
Med andra ord kan du inte använda ALTER TABLE
att släppa en främmande nyckel som du kan i andra RDBMS:er
Det rekommenderade sättet att "släppa" en främmande nyckel i SQLite är faktiskt att överföra data till en ny tabell utan en främmande nyckel (eller med en annan, om det är vad du behöver).
Det rekommenderade sättet
SQLite-dokumentationen rekommenderar en 12-stegsprocess för att göra schemaändringar i en tabell. Vi kommer att använda den processen för att "släppa" en främmande nyckel i följande exempel.
Skapa en tabell med en främmande nyckel
Låt oss först skapa en tabell med den främmande nyckeln och fylla i den med data.
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 );
Här skapade jag faktiskt två tabeller och fyllde i dem med data. Två tabeller, eftersom den första (Typer ) har den primära nyckeln och den andra (Husdjur ) har den främmande nyckeln. Den främmande nyckeln lades till på den sista raden i den andra tabellen.
Vi kan verifiera att den främmande nyckeln skapades genom att köra följande kommando:
PRAGMA foreign_key_list(Pets);
Resultat:
id seq table from to on_update on_delete match -- --- ----- ------ ------ --------- --------- ----- 0 0 Types TypeId TypeId NO ACTION NO ACTION NONE
Vi kan se detaljerna för den främmande nyckeln.
Låt oss nu "släppa" den främmande nyckeln.
”Släpp” den främmande nyckeln
Följande kod "släpper" den främmande nyckeln genom att skapa en ny tabell utan en främmande nyckel-begränsning, överföra data till den tabellen, släppa den ursprungliga tabellen och sedan byta namn på den nya tabellen till namnet på den ursprungliga tabellen.
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;
Klart.
Om du behöver rekonstruera några index, utlösare eller vyer, gör det efter ALTER TABLE
uttalande som byter namn på tabellen (strax före COMMIT
).
Låt oss nu kontrollera tabellen för främmande nyckelbegränsningar igen.
PRAGMA foreign_key_list(Pets);
Resultat:
(Det är tomt eftersom det inte finns några begränsningar för främmande nyckel i den här tabellen.)
Du kan använda samma metod för att lägga till en främmande nyckel till en befintlig tabell.
En alternativ metod
När du tittar på det föregående exemplet kanske du tänker att det finns ett mer effektivt sätt att göra det. Du kan till exempel göra så här:
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;
Och det är sant. Med mitt exempel fungerar den här metoden lika bra.
Men den här metoden har också potential att korrumpera referenser till tabellen i alla befintliga triggers, vyer och främmande nyckelbegränsningar.
Så om din tabell redan har befintliga utlösare, vyer eller begränsningar för främmande nyckel, är det förmodligen säkrare att använda den rekommenderade metoden.