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

Přidejte cizí klíč do existující tabulky v SQLite

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 přidat cizí klíč do existující tabulky, jako můžete v jiných systémech správy databází.

Jediný způsob, jak můžete „přidat“ cizí klíč do existující tabulky v SQLite, je vytvořit novou tabulku s cizím klíčem a poté přenést data do nové tabulky.

Existuje více než jeden způsob, jak to udělat, ale existuje doporučený způsob.

Doporučený způsob

Dokumentace SQLite doporučuje proces o 12 krocích pro provádění změn schématu v tabulce.

Pro účely tohoto článku se budeme zabývat pouze přidáním cizího klíče.

Aby to bylo trochu realistické, ujistíme se, že tabulka již obsahuje data.

Původní tabulka bez cizího klíče

Nejprve vytvořte tabulku bez cizí klíč a naplnit jej daty.

CREATE TABLE Types( 
    TypeId INTEGER PRIMARY KEY, 
    Type
);

CREATE TABLE Pets( 
    PetId INTEGER PRIMARY KEY, 
    PetName,
    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 jedna (Typy ) bude mít primární klíč a druhý (Domácí mazlíčci ) bude mít cizí klíč.

Všimněte si, že jsem nevytvořil cizí klíč.

Že neexistují žádné cizí klíče, můžeme ověřit spuštěním následujícího příkazu:

PRAGMA foreign_key_list(Pets);

V mém případě dostanu následující výsledek:

 

(To je prázdné, protože v této tabulce nejsou žádná omezení cizího klíče.)

Nyní „přidáme“ cizí klíč.

Přidat cizí klíč

Následující kód přidá cizí klíč do naší tabulky vytvořením nové tabulky s omezením 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,
    FOREIGN KEY(TypeId) REFERENCES Types(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.

.mode line
PRAGMA foreign_key_list(Pets);

Výsledek (při použití vertikálního výstupu):

       id = 0
      seq = 0
    table = Types
     from = TypeId
       to = TypeId
on_update = NO ACTION
on_delete = NO ACTION
    match = NONE

Tentokrát se můžeme podívat na podrobnosti o omezení cizího klíče.

Všimněte si, že první řádek mého příkazu (.mode line ) nemá nic společného s vytvořením cizího klíče. Vložil jsem to tam pouze proto, abych změnil způsob, jakým můj terminál vydává výsledek (abyste nemuseli posouvat do stran, abyste výsledek viděli).

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,
    FOREIGN KEY(TypeId) REFERENCES Types(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 mohu vložit více řádků do oracle s hodnotou sekvence?

  2. Export databáze PostgreSQL pomocí phpPgAdmin

  3. Žádné mapování dialektu pro typ JDBC:2003

  4. Profilování dat:Zjišťování podrobností o datech