sql >> Databáze >  >> RDS >> SQLite

Jak zahodit cizí klíč v SQLite

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.


  1. Jak BIN() funguje v MariaDB

  2. Jak generovat data testu DB

  3. SQLite INSERT – PŘI AKTUALIZACI DUPLIKÁTNÍHO KLÍČE (UPSERT)

  4. Plně rozumím PDO ATTR_PERSISTENT