sql >> Database >  >> RDS >> SQLite

SQLite buitenlandse sleutel

Samenvatting :in deze zelfstudie leert u hoe u de SQLite-externe-sleutelbeperking kunt gebruiken om de relaties tussen gerelateerde tabellen af ​​te dwingen.

SQLite-ondersteuning voor externe sleutelbeperkingen

SQLite ondersteunt sinds versie 3.6.19 de beperking van externe sleutels. De SQLite-bibliotheek moet ook worden gecompileerd met noch SQLITE_OMIT_FOREIGN_KEY noch SQLITE_OMIT_TRIGGER.

Om te controleren of uw huidige versie van SQLite externe-sleutelbeperkingen ondersteunt of niet, gebruikt u de volgende opdracht.

PRAGMA foreign_keys;Code language: SQL (Structured Query Language) (sql)

De opdracht retourneert een geheel getal:1:inschakelen, 0:uitgeschakeld. Als de opdracht niets retourneert, betekent dit dat uw SQLite-versie geen beperkingen voor externe sleutels ondersteunt.

Als de SQLite-bibliotheek is gecompileerd met ondersteuning voor externe-sleutelbeperkingen, kan de toepassing de PRAGMA foreign_keys gebruiken commando om beperkingen voor externe sleutels tijdens runtime in of uit te schakelen.

Beperking van externe sleutels uitschakelen:

PRAGMA foreign_keys = OFF;Code language: SQL (Structured Query Language) (sql)

Beperking van externe sleutels inschakelen:

PRAGMA foreign_keys = ON;Code language: SQL (Structured Query Language) (sql)

Inleiding tot de SQLite externe sleutelbeperkingen

Laten we beginnen met twee tabellen:suppliers en supplier_groups :

CREATE TABLE suppliers (
	supplier_id integer PRIMARY KEY,
	supplier_name text NOT NULL,
	group_id integer NOT NULL
);

CREATE TABLE supplier_groups (
	group_id integer PRIMARY KEY,
	group_name text NOT NULL
);Code language: SQL (Structured Query Language) (sql)

Ervan uitgaande dat elke leverancier tot één en slechts één leveranciersgroep behoort. En elke leveranciersgroep kan nul of veel leveranciers hebben. De relatie tussen supplier_groups en suppliers tabellen is een-op-veel. Met andere woorden, voor elke rij in de suppliers tabel, is er een overeenkomstige rij in de supplier_groups tafel.

Momenteel is er geen manier om te voorkomen dat u een rij toevoegt aan de suppliers tabel zonder een bijbehorende rij in de supplier_groups tafel.

Daarnaast kunt u een rij verwijderen in de supplier_groups tabel zonder de corresponderende rijen in de suppliers . te verwijderen of bij te werken tafel. Dit kan verweesde rijen achterlaten in de suppliers tafel.

Om de relatie tussen rijen in de suppliers af te dwingen en supplier_groups tabel, gebruik je de buitenlandse sleutelbeperkingen .

De beperking van de refererende sleutel toevoegen aan de suppliers tabel, wijzigt u de definitie van de CREATE TABLE verklaring hierboven als volgt:

DROP TABLE suppliers;

CREATE TABLE suppliers (
    supplier_id   INTEGER PRIMARY KEY,
    supplier_name TEXT    NOT NULL,
    group_id      INTEGER NOT NULL,
    FOREIGN KEY (group_id)
       REFERENCES supplier_groups (group_id) 
);
Code language: SQL (Structured Query Language) (sql)

De supplier_groups tabel heet een bovenliggende tabel , wat de tabel is waarnaar een refererende sleutel verwijst. De suppliers tafel staat bekend als een kindertafel , de tabel waarop de beperking van de refererende sleutel van toepassing is.

De group_id kolom in de supplier_groups tabel heet de oudersleutel , wat een kolom of een reeks kolommen in de bovenliggende tabel is waarnaar de refererende-sleutelbeperking verwijst. Meestal is de bovenliggende sleutel de primaire sleutel van de bovenliggende tabel.

De group_id kolom in de suppliers tabel wordt de onderliggende sleutel genoemd. Over het algemeen verwijst de onderliggende sleutel naar de primaire sleutel van de bovenliggende tabel.

Voorbeeld van beperking van SQLite externe sleutel

Voeg eerst drie rijen toe aan de supplier_groups tafel.

INSERT INTO supplier_groups (group_name)
VALUES
   ('Domestic'),
   ('Global'),
   ('One-Time');Code language: SQL (Structured Query Language) (sql)

Ten tweede, voeg een nieuwe leverancier toe aan de suppliers tabel met de leveranciersgroep die bestaat in de supplier_groups tafel.

INSERT INTO suppliers (supplier_name, group_id)
VALUES ('HP', 2);Code language: SQL (Structured Query Language) (sql)

Deze verklaring werkt prima.

Ten derde, probeer een nieuwe leverancier in te voegen in de suppliers tabel met de leveranciersgroep die niet bestaat in de supplier_groups tafel.

INSERT INTO suppliers (supplier_name, group_id)
VALUES('ABC Inc.', 4);Code language: SQL (Structured Query Language) (sql)

SQLite controleerde de externe sleutelbeperking, verwierp de wijziging en gaf de volgende foutmelding:

[SQLITE_CONSTRAINT]  Abort due to constraint violation (FOREIGN KEY constraint failed)Code language: CSS (css)

SQLite-beperkingsacties voor externe sleutels

Wat zou er gebeuren als u een rij in de supplier_groups . verwijdert? tafel? Moeten alle corresponderende rijen in de suppliers tabel ook verwijderd? Dezelfde vragen voor de update-bewerking.

Om aan te geven hoe de externe-sleutelbeperking zich gedraagt ​​wanneer de bovenliggende sleutel wordt verwijderd of bijgewerkt, gebruikt u de ON DELETE of ON UPDATE actie als volgt:

FOREIGN KEY (foreign_key_columns)
   REFERENCES parent_table(parent_key_columns)
      ON UPDATE action 
      ON DELETE action;Code language: SQL (Structured Query Language) (sql)

SQLite ondersteunt de volgende acties:

  • STEL NULL IN
  • STANDAARD INSTELLEN
  • BEPERK
  • GEEN ACTIE
  • CASCADE

In de praktijk veranderen de waarden van de primaire sleutel in de bovenliggende tabel niet, daarom zijn de updateregels minder belangrijk. De belangrijkste regel is de DELETE regel die de actie specificeert wanneer de bovenliggende sleutel wordt verwijderd.

We zullen elke actie onderzoeken aan de hand van het volgende voorbeeld

STEL NULL IN

Wanneer de bovenliggende sleutel wordt gewijzigd, verwijderd of bijgewerkt, worden de bijbehorende onderliggende sleutels van alle rijen in de onderliggende tabel ingesteld op NULL.

Plaats eerst de tabel suppliers en maak deze aan met behulp van de SET NULL actie voor de group_id buitenlandse sleutel:

DROP TABLE suppliers;

CREATE TABLE suppliers (
    supplier_id   INTEGER PRIMARY KEY,
    supplier_name TEXT    NOT NULL,
    group_id      INTEGER,
    FOREIGN KEY (group_id)
    REFERENCES supplier_groups (group_id) 
       ON UPDATE SET NULL
       ON DELETE SET NULL
);
Code language: SQL (Structured Query Language) (sql)

Ten tweede, voeg enkele rijen toe aan de suppliers tafel:

INSERT INTO suppliers (supplier_name, group_id)
VALUES('XYZ Corp', 3);

INSERT INTO suppliers (supplier_name, group_id)
VALUES('ABC Corp', 3);Code language: SQL (Structured Query Language) (sql)

Ten derde, verwijder de leveranciersgroep-ID 3 uit de supplier_groups tafel:

DELETE FROM supplier_groups 
WHERE group_id = 3;Code language: SQL (Structured Query Language) (sql)

Ten vierde, gegevens opvragen bij de suppliers tafel.

SELECT * FROM suppliers;Code language: SQL (Structured Query Language) (sql)

De waarden van de group_id kolom van de corresponderende rijen in de suppliers tabel ingesteld op NULL.

STANDAARD INSTELLEN

De SET DEFAULT action stelt de waarde van de refererende sleutel in op de standaardwaarde die is opgegeven in de kolomdefinitie wanneer u de tabel maakt.

Omdat de waarden in de kolom group_id standaard ingesteld op NULL, als u een rij verwijdert uit de supplier_groups tabel, de waarden van de group_id wordt ingesteld op NULL.

Nadat de standaardwaarde is toegewezen, treedt de beperking van de refererende sleutel in werking en wordt de controle uitgevoerd.

BEPERK

De RESTRICT actie staat u niet toe om waarden in de bovenliggende sleutel van de bovenliggende tabel te wijzigen of te verwijderen.

Verwijder en maak eerst de suppliers tabel met de RESTRICT actie in de refererende sleutel group_id :

DROP TABLE suppliers;

CREATE TABLE suppliers (
    supplier_id   INTEGER PRIMARY KEY,
    supplier_name TEXT    NOT NULL,
    group_id      INTEGER,
    FOREIGN KEY (group_id)
    REFERENCES supplier_groups (group_id) 
       ON UPDATE RESTRICT
       ON DELETE RESTRICT
);Code language: SQL (Structured Query Language) (sql)

Ten tweede, plaats een rij in de tabel suppliers met de group_id 1.

INSERT INTO suppliers (supplier_name, group_id)
VALUES('XYZ Corp', 1);Code language: SQL (Structured Query Language) (sql)

Ten derde, verwijder de leveranciersgroep met id 1 uit de supplier_groups tafel:

DELETE FROM supplier_groups 
WHERE group_id = 1;Code language: SQL (Structured Query Language) (sql)

SQLite gaf de volgende fout:

[SQLITE_CONSTRAINT]  Abort due to constraint violation (FOREIGN KEY constraint failed)Code language: CSS (css)

Om dit op te lossen, moet u eerst alle rijen verwijderen uit de suppliers tabel met group_id 1:

DELETE FROM suppliers 
WHERE group_id =1;Code language: SQL (Structured Query Language) (sql)

Vervolgens kunt u de leveranciersgroep 1 verwijderen uit de supplier_groups tafel:

DELETE FROM supplier_groups 
WHERE group_id = 1;Code language: SQL (Structured Query Language) (sql)

GEEN ACTIE

De NO ACTION betekent niet dat de beperking van de externe sleutel wordt omzeild. Het heeft hetzelfde effect als de RESTRICT .

CASCADE

De CASCADE actie verspreidt de wijzigingen van de bovenliggende tabel naar de onderliggende tabel wanneer u de bovenliggende sleutel bijwerkt of verwijdert.

Voer eerst de supplier in groepen in de supplier_groups tafel:

INSERT INTO supplier_groups (group_name)
VALUES
   ('Domestic'),
   ('Global'),
   ('One-Time');Code language: SQL (Structured Query Language) (sql)

Ten tweede, drop en maak de tabel suppliers met de CASCADE actie in de refererende sleutel group_id :

DROP TABLE suppliers;

CREATE TABLE suppliers (
    supplier_id   INTEGER PRIMARY KEY,
    supplier_name TEXT    NOT NULL,
    group_id      INTEGER,
    FOREIGN KEY (group_id)
    REFERENCES supplier_groups (group_id) 
       ON UPDATE CASCADE
       ON DELETE CASCADE
);Code language: SQL (Structured Query Language) (sql)

Ten derde, voeg enkele leveranciers toe aan de tabel suppliers :

INSERT INTO suppliers (supplier_name, group_id)
VALUES('XYZ Corp', 1);

INSERT INTO suppliers (supplier_name, group_id)
VALUES('ABC Corp', 2);Code language: SQL (Structured Query Language) (sql)

Ten vierde, update group_id van de Domestic leveranciersgroep tot 100:

UPDATE supplier_groups
SET group_id = 100
WHERE group_name = 'Domestic';Code language: SQL (Structured Query Language) (sql)

Ten vijfde, gegevens opvragen uit de tabel suppliers :

SELECT * FROM suppliers;Code language: SQL (Structured Query Language) (sql)

Zoals je kunt zien in de group_id kolom van de XYZ Corp in de tabel suppliers veranderd van 1 naar 100 toen we de group_id . bijwerkten in de suplier_groups tafel. Dit is het resultaat van ON UPDATE CASCADE actie.

Ten zesde, verwijder leveranciersgroep-ID 2 uit de supplier_groups tafel:

DELETE FROM supplier_groups 
WHERE group_id = 2;Code language: SQL (Structured Query Language) (sql)

Ten zevende, vraag gegevens op uit de tabel suppliers :

SELECT * FROM suppliers;Code language: SQL (Structured Query Language) (sql)

De leverancier-ID 2 waarvan group_id is 2 werd verwijderd toen de leveranciersgroep-ID 2 werd verwijderd uit de supplier_groups tafel. Dit is het effect van de ON DELETE CASCADE actie.

In deze zelfstudie hebt u geleerd over SQLite-beperkingen voor externe sleutels en hoe u deze kunt gebruiken om de relatie tussen gerelateerde tabellen af ​​te dwingen.


  1. Er is een DBConcurrency-uitzondering opgetreden tijdens het bijwerken met behulp van Dataadapter

  2. Wat gebeurt er met de primaire sleutel-ID als deze de limiet overschrijdt?

  3. IIS 7 AppPool-identiteiten toevoegen als SQL Server-aanmeldingen

  4. Hoe csv-strings het beste te splitsen in oracle 9i