SQLite
 sql >> Baza danych >  >> RDS >> SQLite

Dodaj klucz obcy do istniejącej tabeli w SQLite

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 dodać klucz obcy do istniejącej tabeli, tak jak w innych systemach zarządzania bazami danych.

Dlatego jedynym sposobem na „dodanie” klucza obcego do istniejącej tabeli w SQLite jest utworzenie nowej tabeli z kluczem obcym, a następnie przeniesienie danych do nowej tabeli.

Można to zrobić na więcej niż jeden sposób, ale jest sposób zalecany.

Zalecany sposób

Dokumentacja SQLite zaleca 12-etapowy proces wprowadzania zmian w schemacie do tabeli.

Na potrzeby tego artykułu zajmiemy się tylko dodawaniem klucza obcego.

Aby było to trochę realistyczne, upewnimy się, że tabela zawiera już dane.

Oryginalna tabela bez klucza obcego

Najpierw utwórzmy stół bez klucz obcy i wypełnij go danymi.

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 );

Właściwie tutaj stworzyłem dwie tabele i wypełniłem je danymi. Dwie tabele, bo jedna (Typy ) będzie miał klucz podstawowy, a drugi (Zwierzęta ) będzie miał klucz obcy.

Zauważ, że nie utworzyłem klucza obcego.

Możemy sprawdzić, czy nie ma kluczy obcych, uruchamiając następujące polecenie:

PRAGMA foreign_key_list(Pets);

W moim przypadku otrzymuję następujący wynik:

 

(To pole jest puste, ponieważ w tej tabeli nie ma ograniczeń klucza obcego).

Teraz „dodajmy” klucz obcy.

Dodaj klucz obcy

Poniższy kod dodaje klucz obcy do naszej tabeli, tworząc nową tabelę z ograniczeniem klucza obcego, przesyłając dane do tej tabeli, upuszczają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,
    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;

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.

.mode line
PRAGMA foreign_key_list(Pets);

Wynik (przy użyciu wyjścia pionowego):

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

Tym razem możemy zobaczyć szczegóły ograniczenia klucza obcego.

Zauważ, że pierwsza linia mojego polecenia (.mode line ) nie ma nic wspólnego z tworzeniem klucza obcego. Umieściłem go tam wyłącznie po to, aby zmienić sposób, w jaki mój terminal wyświetla wynik (abyś nie musiał przewijać na boki, aby wyświetlić wynik).

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,
    FOREIGN KEY(TypeId) REFERENCES Types(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.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Indeks SQLite

  2. SQLite - Eksportuj dane do pliku CSV

  3. Android:Wstawianie zbiorcze, gdy funkcja InsertHelper jest przestarzała

  4. Android — jak przekazać dane dotyczące dwóch tabel do metody wstawiania dostawcy treści?

  5. Przechowywanie bazy danych SQLite za pomocą Androida i Phonegap