SQLite innehåller en PRAGMA-sats som låter dig kontrollera om det finns överträdelser av främmande nyckel på en hel databas eller en given tabell.
Uttrycket är PRAGMA foreign_key_check
, och det fungerar enligt följande.
Syntax
Du kan använda den på ett av två sätt:
PRAGMA schema.foreign_key_check;
PRAGMA schema.foreign_key_check(table-name);
Den första raden kontrollerar hela databasen, medan den andra bara kontrollerar en specifik tabell.
Det valfria schema
argument anger namnet på en bifogad databas eller huvud eller temp för huvud- och TEMP-databaserna. Om schema
är utelämnad, huvud är antaget.
Exempel
Låt oss skapa två tabeller med en relation mellan dem.
I det här fallet, Husdjur tabellen har en främmande nyckel som refererar till TypeId kolumnen i Typer bord.
CREATE TABLE Types(
TypeId INTEGER PRIMARY KEY,
Type
);
CREATE TABLE Pets(
PetId INTEGER PRIMARY KEY,
PetName,
TypeId,
FOREIGN KEY(TypeId) REFERENCES Types(TypeId)
);
Låt oss nu ange data som bryter mot begränsningen för främmande nyckel.
PRAGMA foreign_keys = OFF;
INSERT INTO Types VALUES
( 1, 'Dog' ),
( 2, 'Cat' );
INSERT INTO Pets VALUES
( 1, 'Homer', 3 );
Den andra INSERT
uttalandet bryter mot begränsningen för främmande nyckel. Detta beror på att det infogar värdet 3 i Pets.TypeId kolumnen, när det inte finns ett motsvarande värde i Types.TypeId kolumn.
En viktig sak att notera här är att jag uttryckligen inaktiverade främmande nycklar genom att använda PRAGMA foreign_keys = OFF
. Detta är standardinställningen i SQLite, men jag ville göra det tydligt för det här exemplet.
Låt oss nu kontrollera databasen efter kränkningar av främmande nyckel.
PRAGMA foreign_key_check;
Resultat:
table rowid parent fkid ---------- ---------- ---------- ---------- Pets 1 Types 0
Detta berättar för oss att Husdjur tabellen har ett brott mot främmande nyckel på raden med ROWID på 1. Den talar om för oss även namnet på den överordnade tabellen, såväl som ID för den främmande nyckeln.
Låt oss lägga till mer data till husdjur tabell och kör kontrollen igen. De två första raderna hänger ihop med den främmande nyckeln, men den sista raden gör det inte.
INSERT INTO Pets VALUES
( NULL, 'Yelp', 1 ),
( NULL, 'Fluff', 2 ),
( NULL, 'Brush', 4 );
PRAGMA foreign_key_check;
Resultat:
table rowid parent fkid ---------- ---------- ---------- ---------- Pets 1 Types 0 Pets 4 Types 0
Vi har nu två rader som returneras när vi kontrollerar hela databasen för brott mot främmande nyckel.
Kontrollera en specifik tabell
Du kan också ange en tabell att köra kontrollen mot.
Här är ett exempel på hur du skriver om den tidigare kontrollen för att bara ange husdjur bord.
PRAGMA foreign_key_check(Pets);
Resultat:
table rowid parent fkid ---------- ---------- ---------- ---------- Pets 1 Types 0 Pets 4 Types 0
Samma resultat.
Här är resultatet om jag anger den andra tabellen.
PRAGMA foreign_key_check(Types);
Resultat:
(Det är tomt eftersom det inte finns några resultat.)
Ange ett schema
Som nämnts kan du också specificera schemat.
PRAGMA main.foreign_key_check(Pets);
Resultat:
table rowid parent fkid ---------- ---------- ---------- ---------- Pets 1 Types 0 Pets 4 Types 0
I mitt fall använde jag huvuddatabasen, men du kan ersätta main
med namnet på din bifogade databas.
Hur man upprätthåller främmande nycklar
Som nämnts upprätthåller inte SQLite främmande nycklar om du inte uttryckligen anger att de ska tillämpas.
Du kan tvinga fram främmande nycklar med PRAGMA foreign_keys = ON
.
Se Hur man aktiverar stöd för främmande nyckel i SQLite för mer information och exempel.