SQLite zawiera instrukcję PRAGMA, która umożliwia sprawdzenie naruszeń kluczy obcych w całej bazie danych lub w danej tabeli.
Oświadczenie to PRAGMA foreign_key_check
i działa w następujący sposób.
Składnia
Możesz go użyć na dwa sposoby:
PRAGMA schema.foreign_key_check;
PRAGMA schema.foreign_key_check(table-name);
Pierwsza linia sprawdza całą bazę danych, a druga tylko konkretną tabelę.
Opcjonalny schema
argument określa nazwę dołączonej bazy danych lub głównej lub temp dla bazy głównej i bazy danych TEMP. Jeśli schema
jest pominięty, główny zakłada się.
Przykład
Stwórzmy dwie tabele z relacją między nimi.
W tym przypadku Zwierzęta tabela ma klucz obcy, który odwołuje się do TypeId kolumna na Typy tabela.
CREATE TABLE Types(
TypeId INTEGER PRIMARY KEY,
Type
);
CREATE TABLE Pets(
PetId INTEGER PRIMARY KEY,
PetName,
TypeId,
FOREIGN KEY(TypeId) REFERENCES Types(TypeId)
);
Teraz wprowadźmy dane, które naruszają ograniczenie klucza obcego.
PRAGMA foreign_keys = OFF;
INSERT INTO Types VALUES
( 1, 'Dog' ),
( 2, 'Cat' );
INSERT INTO Pets VALUES
( 1, 'Homer', 3 );
Drugi INSERT
oświadczenie narusza ograniczenie klucza obcego. Dzieje się tak, ponieważ wstawia wartość 3 do Pets.TypeId kolumna, gdy nie ma odpowiadającej wartości w Types.TypeId kolumna.
Ważną rzeczą do odnotowania jest to, że jawnie wyłączyłem klucze obce za pomocą PRAGMA foreign_keys = OFF
. To jest domyślne ustawienie w SQLite, ale chciałem to wyjaśnić w tym przykładzie.
Sprawdźmy teraz bazę danych pod kątem naruszeń kluczy obcych.
PRAGMA foreign_key_check;
Wynik:
table rowid parent fkid ---------- ---------- ---------- ---------- Pets 1 Types 0
To mówi nam, że Zwierzęta tabela zawiera naruszenie klucza obcego w wierszu z ROWID równym 1. Informuje również o nazwie tabeli nadrzędnej oraz identyfikatorze klucza obcego.
Dodajmy więcej danych do Zwierzaków tabeli i ponownie uruchom sprawdzanie. Pierwsze dwie linie są zgodne z kluczem obcym, ale ostatnia nie.
INSERT INTO Pets VALUES
( NULL, 'Yelp', 1 ),
( NULL, 'Fluff', 2 ),
( NULL, 'Brush', 4 );
PRAGMA foreign_key_check;
Wynik:
table rowid parent fkid ---------- ---------- ---------- ---------- Pets 1 Types 0 Pets 4 Types 0
Mamy teraz dwa wiersze zwrócone podczas sprawdzania całej bazy danych pod kątem naruszeń kluczy obcych.
Sprawdź konkretną tabelę
Możesz również określić tabelę, dla której ma zostać przeprowadzone sprawdzanie.
Oto przykład przepisywania poprzedniego czeku, aby określić tylko Zwierzęta tabela.
PRAGMA foreign_key_check(Pets);
Wynik:
table rowid parent fkid ---------- ---------- ---------- ---------- Pets 1 Types 0 Pets 4 Types 0
Ten sam wynik.
Oto wynik, jeśli określę drugą tabelę.
PRAGMA foreign_key_check(Types);
Wynik:
(Pole jest puste, ponieważ nie ma wyników).
Określ schemat
Jak wspomniano, możesz również określić schemat.
PRAGMA main.foreign_key_check(Pets);
Wynik:
table rowid parent fkid ---------- ---------- ---------- ---------- Pets 1 Types 0 Pets 4 Types 0
W moim przypadku użyłem głównej bazy danych, ale możesz zastąpić main
z nazwą dołączonej bazy danych.
Jak wymusić użycie kluczy obcych
Jak wspomniano, SQLite nie wymusza kluczy obcych, chyba że wyraźnie określisz, że powinny one być wymuszane.
Możesz wymusić klucze obce za pomocą PRAGMA foreign_keys = ON
.
Zobacz Jak włączyć obsługę kluczy obcych w SQLite, aby uzyskać więcej informacji i przykładów.