sql >> Database >  >> RDS >> SQLite

Vind schendingen van buitenlandse sleutels in SQLite

SQLite bevat een PRAGMA-instructie waarmee u kunt controleren op schendingen van buitenlandse sleutels in een hele database of een bepaalde tabel.

De verklaring is PRAGMA foreign_key_check , en het werkt als volgt.

Syntaxis

Je kunt het op twee manieren gebruiken:

PRAGMA schema.foreign_key_check;
PRAGMA schema.foreign_key_check(table-name);

De eerste regel controleert de hele database, terwijl de tweede regel slechts een specifieke tabel controleert.

Het optionele schema argument specificeert de naam van een gekoppelde database of main of temp voor de hoofd- en de TEMP-databases. Als schema is weggelaten, hoofd wordt verondersteld.

Voorbeeld

Laten we twee tabellen maken met een relatie ertussen.

In dit geval de Huisdieren tabel heeft een externe sleutel die verwijst naar de TypeId kolom op de Typen tafel.

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

CREATE TABLE Pets( 
    PetId INTEGER PRIMARY KEY, 
    PetName,
    TypeId,
    FOREIGN KEY(TypeId) REFERENCES Types(TypeId)
);

Laten we nu gegevens invoeren die de externe sleutelbeperking schenden.

PRAGMA foreign_keys = OFF;

INSERT INTO Types VALUES 
    ( 1, 'Dog' ),
    ( 2, 'Cat' );

INSERT INTO Pets VALUES 
    ( 1, 'Homer', 3 );

De tweede INSERT verklaring in strijd is met de beperking van de refererende sleutel. Dit komt omdat het een waarde van 3 invoegt in de Pets.TypeId kolom, wanneer er geen corresponderende waarde is in de Types.TypeId kolom.

Een belangrijk ding om op te merken is dat ik buitenlandse sleutels expliciet heb uitgeschakeld door PRAGMA foreign_keys = OFF te gebruiken . Dit is de standaardinstelling in SQLite, maar ik wilde het voor dit voorbeeld duidelijk maken.

Laten we nu de database controleren op schendingen van buitenlandse sleutels.

PRAGMA foreign_key_check;

Resultaat:

table       rowid       parent      fkid      
----------  ----------  ----------  ----------
Pets        1           Types       0         

Dit vertelt ons dat de Huisdieren tabel heeft een schending van een buitenlandse sleutel in de rij met een ROWID van 1. Het vertelt ons ook de naam van de bovenliggende tabel, evenals de ID van de buitenlandse sleutel.

Laten we meer gegevens toevoegen aan de Huisdieren tabel en voer de controle opnieuw uit. De eerste twee regels houden zich aan de externe sleutel, maar de laatste regel niet.

INSERT INTO Pets VALUES 
    ( NULL, 'Yelp', 1 ),
    ( NULL, 'Fluff', 2 ),
    ( NULL, 'Brush', 4 );

PRAGMA foreign_key_check;

Resultaat:

table       rowid       parent      fkid      
----------  ----------  ----------  ----------
Pets        1           Types       0         
Pets        4           Types       0         

We hebben nu twee rijen geretourneerd bij het controleren van de hele database op schendingen van buitenlandse sleutels.

Controleer een specifieke tabel

U kunt ook een tabel opgeven om de controle op uit te voeren.

Hier is een voorbeeld van het herschrijven van de vorige controle om alleen de Huisdieren te specificeren tafel.

PRAGMA foreign_key_check(Pets);

Resultaat:

table       rowid       parent      fkid      
----------  ----------  ----------  ----------
Pets        1           Types       0         
Pets        4           Types       0         

Zelfde resultaat.

Dit is het resultaat als ik de andere tabel specificeer.

PRAGMA foreign_key_check(Types);

Resultaat:

 

(Het is leeg omdat er geen resultaten zijn.)

Geef een schema op

Zoals vermeld, kunt u ook het schema specificeren.

PRAGMA main.foreign_key_check(Pets);

Resultaat:

table       rowid       parent      fkid      
----------  ----------  ----------  ----------
Pets        1           Types       0         
Pets        4           Types       0         

In mijn geval gebruikte ik de hoofddatabase, maar je zou main . kunnen vervangen met de naam van uw bijgevoegde database.

Hoe buitenlandse sleutels afdwingen

Zoals vermeld, dwingt SQLite geen externe sleutels af, tenzij u expliciet opgeeft dat ze moeten worden afgedwongen.

U kunt externe sleutels afdwingen met PRAGMA foreign_keys = ON .

Zie Ondersteuning voor externe sleutels inschakelen in SQLite voor meer informatie en voorbeelden.


  1. Vermijd duplicaten in INSERT INTO SELECT-query in SQL Server

  2. Robuuste sorteringen met ICU-ondersteuning in PostgreSQL 10

  3. SQL Server - Kortsluiting opvragen?

  4. Een tijdelijke oplossing voor DATEDIFF() SET DATEFIRST negeren in SQL Server (T-SQL-voorbeeld)