- Leren
- Informatica & ICT
- Programmeren
- De basis van SQL
- SQL CREATE TABLE
SQL CREATE TABLE: tabellen maken en gegevens wijzigen
CREATE TABLE-instructies met passende gegevenstypen, bescherm de gegevens met NOT NULL, UNIQUE, CHECK, primaire sleutels en refererende sleutels, en voeg rijen toe, wijzig ze en verwijder ze met INSERT, UPDATE en DELETE. Oefen met het selecteren van precies de juiste rijen, bundel samenhangende wijzigingen in transacties die je kunt vastleggen of terugdraaien, en wijzig of verwijder tabellen met ALTER TABLE en DROP TABLE. De voorbeelden gebruiken standaard-SQL die op SQLite en PostgreSQL werkt. Waar het verschil maakt, worden afwijkingen in MySQL, SQL Server en Oracle aangegeven.BeginnerLes 6 van 6 in SQL: de basis
Wat je leert
- Schrijf
CREATE TABLE-instructies die een tabel en de bijbehorende kolommen definiëren, en kies voor elke kolom een gegevenstype dat past bij de waarden die erin komen.- Schrijf een CREATE TABLE-instructieDefinieer een nieuwe tabel met benoemde kolommen, controleer de structuur en voorkom de syntaxisfouten die beginners het vaakst maken.
- Kies een gegevenstype voor elke kolomKies typen voor gehele getallen, exacte decimalen, drijvendekommagetallen, tekst, datums en waar/onwaar-waarden die passen bij de waarden in een kolom, en begrijp hoe de flexibele typering van SQLite verschilt van die van strengere databases.
- Schrijf een CREATE TABLE-instructie
- Gebruik integriteitsregels zodat de database zelf ontbrekende, dubbele, te hoge, te lage en niet-overeenkomende waarden weigert, en geef elke rij een betrouwbare sleutel.
- Stel verplichte waarden, standaardwaarden en beperkingen in met NOT NULL, DEFAULT, UNIQUE en CHECKDeclareer de kolom- en tabelregels die ervoor zorgen dat waarden aanwezig en uniek zijn en binnen het bereik vallen, en voorspel welke invoegingen een regel weigert.
- Identificeer rijen met primaire sleutels en gegenereerde identificatiewaardenDeclareer primaire sleutels met één kolom en samengestelde primaire sleutels, laat de database nieuwe rijen nummeren en weet wat gegenereerde identificatiewaarden in elk databasesysteem wel en niet garanderen.
- Koppel tabellen met refererende sleutelsDeclareer refererende sleutels die verwijzingen tussen tabellen geldig houden, kies wat er gebeurt als een rij waarnaar wordt verwezen wordt verwijderd, en schakel handhaving in waar die uitstaat.
- Stel verplichte waarden, standaardwaarden en beperkingen in met NOT NULL, DEFAULT, UNIQUE en CHECK
- Voeg nieuwe rijen toe met
INSERT, één voor één, meerdere tegelijk of gekopieerd uit een query, en verwerk gegenereerde sleutels en dubbele waarden.- Voeg rijen in met VALUESSchrijf
INSERT ... VALUES-instructies met een kolommenlijst en correct genoteerde tekst, getallen, datums enNULL, en lees de fouten die een invoeging stoppen. - Voeg queryresultaten in, haal nieuwe sleutels op en verwerk dubbele waardenKopieer rijen met
INSERT ... SELECT, lees gegenereerde waarden terug metRETURNINGen bepaal wat er gebeurt wanneer een ingevoegde rij botst met een bestaande rij.
- Voeg rijen in met VALUES
- Wijzig waarden met
UPDATEen verwijder rijen metDELETE, en zorg dat elke instructie precies de bedoelde rijen treft.- Wijzig waarden met UPDATESchrijf
UPDATE-instructies die één of meer kolommen instellen, nieuwe waarden berekenen op basis van oude en voldoen aan de integriteitsregels van de tabel. - Verwijder rijen met DELETEVerwijder gekozen rijen met
DELETE, onderscheidDELETE,TRUNCATEenDROP TABLE, en bepaal wanneer het beter is een rij als verwijderd te markeren dan deze te verwijderen. - Selecteer precies de rijen die je bedoeltStel
WHERE-voorwaarden voor wijzigingen op die alleen de bedoelde rijen selecteren en controleer het resultaat voordat je het vastlegt.
- Wijzig waarden met UPDATE
- Gebruik transacties zodat een groep samenhangende wijzigingen als geheel wordt vastgelegd of teruggedraaid, en herstel de situatie correct wanneer een instructie mislukt.
- Leg een groep wijzigingen vast of draai deze terugStart een transactie, leg de wijzigingen vast met
COMMITof draai ze terug metROLLBACK, en begrijp hoe autocommit werkt. - Ga binnen een transactie om met fouten, savepoints en structuurwijzigingenReageer correct als een instructie binnen een transactie mislukt, draai een deel van een transactie terug met een savepoint en weet welke databases
CREATE,ALTERenDROPkunnen terugdraaien.
- Leg een groep wijzigingen vast of draai deze terug
- Wijzig de structuur van bestaande tabellen zonder hun rijen te verliezen en verwijder tabellen veilig wanneer ze niet meer nodig zijn.
- Voeg kolommen toe, hernoem ze en verwijder ze met ALTER TABLEGebruik
ALTER TABLEom kolommen toe te voegen, te hernoemen en te verwijderen en om typen en integriteitsregels te wijzigen, en omzeil de beperkingen van SQLite. - Verwijder tabellen met DROP TABLEVerwijder tabellen met
DROP TABLE, houd rekening met de afhankelijkheden tussen tabellen en kies tussen tabellen verwijderen, tabellen leegmaken en rijen verwijderen.
- Voeg kolommen toe, hernoem ze en verwijder ze met ALTER TABLE
SQL CREATE TABLE: uitleg
1Maak tabellen met geschikte gegevenstypen voor de kolommen
Een tabel heeft een duidelijke structuur nodig voordat deze bruikbare gegevens kan bevatten. Begin met de gegevens die één rij vastlegt, geef elk gegeven een naam en kies hoe de database het opslaat. Je maakt een lege tabel, bekijkt wat er werkelijk is aangemaakt en leert onderscheid te maken tussen een getal waarmee je rekent en tekst die alleen numeriek lijkt. SQLite en PostgreSQL delen veel syntaxis, maar hun typeregels kunnen heel verschillende resultaten opleveren.
1.1 Schrijf een CREATE TABLE-instructie
Een tabeldefinitie beschrijft wat elke rij kan bevatten. Ze voegt geen rijen toe. In een webwinkel heeft elk product afzonderlijke velden nodig voor de identificatiewaarde, naam, prijs en voorraad.
Stel de definitie op
CREATE TABLE products (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
price NUMERIC(8, 2) NOT NULL,
in_stock INTEGER DEFAULT 0
);
Lees van buiten naar binnen. CREATE TABLE products geeft de nieuwe tabel een naam. Tussen haakjes staan de kolomdefinities. Elke regel geeft een kolomnaam, een type en eventuele regels voor die kolom. Komma's scheiden de definities; na de laatste definitie staat geen komma. De puntkomma beëindigt de instructie. Nadat die is geslaagd, geeft SELECT * FROM products; nul rijen terug.
Deze sleuteldeclaratie genereert identificatiewaarden in SQLite. Gebruik in PostgreSQL id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY om ze te genereren. De decimale declaratie gedraagt zich in deze systemen ook verschillend; een exacte opslag kiezen hoort bij de keuze van een type.
Geef elk gegeven een eigen kolom
Een klantrij kan id, first_name, last_name, email en signup_date bevatten. Als je “Ana Ruiz, ana@example.com” in één veld stopt, zijn de naam en het e-mailadres moeilijk afzonderlijk te doorzoeken of te controleren. Geef de velden namen die aangeven wat ze bevatten. Korte namen in kleine letters, verbonden met lage streepjes, zoals unit_price, zijn gemakkelijk opnieuw te gebruiken.
Gebruik geen trefwoorden als naam: orders werkt, terwijl order zonder aanhalingstekens botst met het SQL-trefwoord ORDER. Een naam met spaties heeft dubbele aanhalingstekens nodig, zoals in "order date", telkens wanneer je die gebruikt. PostgreSQL zet namen zonder aanhalingstekens om naar kleine letters, dus Products en products zonder aanhalingstekens verwijzen naar dezelfde naam.
Enkele aanhalingstekens hebben een andere functie: ze sluiten tekstwaarden zoals 'Desk lamp' in. Dubbele aanhalingstekens duiden namen aan. PostgreSQL leest "Desk lamp" als kolomnaam, niet als producttekst.
Controleer wat is aangemaakt
Een afsluitende komma vóór ) veroorzaakt een syntaxisfout. Een ontbrekende komma doet dat vaak ook, maar SQLite kan meerdere woorden als één typenaam lezen. CREATE TABLE t (a INTEGER b TEXT); maakt één kolom met de naam a, geen twee kolommen. Bekijk de definitie:
- SQLite-shell:
.schema productstoont de aanmaakinstructie. - SQLite-SQL:
PRAGMA table_info(products);geeft een lijst van kolommen en typen. - PostgreSQL-psql:
\d productstoont kolommen, typen en integriteitsregels.
CREATE TABLE IF NOT EXISTS products (...) voorkomt een fout als de naam al bestaat. De oude definitie wordt niet vergeleken of bijgewerkt. Een tabel waarin een benodigde kolom ontbreekt, blijft zo.
Maak een eenmalige kopie
CREATE TABLE cheap_products AS
SELECT name, price FROM products WHERE price < 10;
Dit maakt kolommen en kopieert de rijen van de query. Latere productwijzigingen werken de kopie niet bij. In SQLite en PostgreSQL erft de nieuwe tabel de primaire sleutel en de NOT NULL- en CHECK-regels van de bron niet.
CREATE, ALTER en DROP behoren tot de gegevensdefinitietaal, ofwel DDL: ze wijzigen de structuur. INSERT, UPDATE en DELETE zijn gegevensmanipulatietaal, ofwel DML: ze wijzigen rijen. SELECT leest gegevens; boeken verschillen van mening of dit bij DML hoort of dat query's een eigen familie vormen.
Belangrijkste punten
- Kolomdefinities bevatten een naam, een type en optionele regels.
- Gebruik komma's tussen definities, zonder afsluitende komma.
- Enkele aanhalingstekens sluiten tekst in; dubbele aanhalingstekens sluiten identificatoren in.
- Controleer de resulterende structuur, ook na een IF NOT EXISTS-instructie.
- CREATE TABLE AS kopieert querygegevens zonder de integriteitsregels van de bron te kopiëren.
1.2 Kies een gegevenstype voor elke kolom
Kies een type op basis van wat je met de waarde moet doen. Een hoeveelheid moet geschikt zijn voor berekeningen. Een Amerikaanse postcode moet zijn tekens behouden, inclusief voorloopnullen. Beide kunnen uit cijfers bestaan, maar hebben een andere opslag nodig.
Kies typen voor getallen en tekst
| Waarden | Bruikbaar type | Reden |
|---|---|---|
| Gehele aantallen | INTEGER | Aantallen hebben geen gebroken deel. |
| Exacte geldbedragen in PostgreSQL | NUMERIC(p, s) | Decimaal rekenen behoudt exacte bedragen. |
| Exacte geldbedragen in SQLite | Centen als INTEGER | Gehele centen voorkomen opslag als drijvendekommagetal. |
| Metingen | REAL of DOUBLE PRECISION | Benaderingen zijn geschikt voor gemeten grootheden. |
| Namen en codes | TEXT of VARCHAR(n) | Tekens en voorloopnullen blijven behouden. |
In PostgreSQL heeft NUMERIC(8, 2) in totaal acht cijfers, waarvan twee na de decimale komma. De grootste positieve waarde is 999.999,99. Als je 12,345 invoegt, wordt 12,35 opgeslagen; 1.234.567,00 veroorzaakt een overloop omdat er zeven cijfers vóór de komma nodig zijn. DECIMAL is een andere naam voor deze typenfamilie.
SQLite accepteert NUMERIC(8, 2), maar dwingt die precisie of schaal niet af. Het slaat 19,99 op als drijvendekommagetal en behoudt 12,345 zonder afronding. Sla 1999 gehele centen op voor een exact bedrag van 19,99. Drijvendekommagetallen kunnen decimale waarden als binaire benaderingen opslaan: SELECT 0.1 + 0.2 = 0.3; van SQLite geeft 0 terug. PostgreSQL behandelt deze losse decimale literals als exacte numerieke waarden; converteer ze naar DOUBLE PRECISION om het benaderde resultaat te zien.
Getallen als tekst worden op tekens gesorteerd: '100', '25', '9' verschijnen in die volgorde. Numerieke hoeveelheden hebben numerieke kolommen nodig. De Amerikaanse postcode '02139' hoort in tekst; bij opslag als geheel getal gaat de voorloopnul verloren.
VARCHAR(20) van PostgreSQL weigert tekst die langer is dan 20 tekens. CHAR(n) vult kortere tekst met spaties aan tot een vaste lengte. TEXT heeft geen gedeclareerde tekenlimiet. SQLite behandelt zowel VARCHAR(n) als CHAR(n) als tekst, zonder de lengte af te dwingen of aan te vullen.
Sla datums en ja/nee-waarden op
PostgreSQL heeft DATE, TIME, TIMESTAMP en BOOLEAN. Het weigert een onmogelijke DATE zoals '2026-02-30'. SQLite heeft geen afzonderlijk opslagtype voor datums. Gebruik ISO-tekst zoals '2026-03-15', waarvan de tekenvolgorde overeenkomt met de datumvolgorde. Tekst in Amerikaanse notatie sorteert datums uit verschillende jaren verkeerd: '12/01/2025' komt na '03/15/2026'.
Een tijdstempel voegt een tijd toe, zoals in '2026-03-15 14:30:00'. PostgreSQL gebruikt TRUE en FALSE voor Booleaanse waarden; SQLite slaat 1 en 0 op en accepteert die trefwoorden. MySQL behandelt BOOLEAN als een klein geheel getal; SQL Server gebruikt BIT.
Weet wat het systeem afdwingt
Gewone SQLite-tabellen gebruiken typeaffiniteit, een opslagvoorkeur. Een INTEGER-kolom zet '5' om naar 5, maar accepteert 'abc' als tekst. PostgreSQL weigert tekst die geen geheel getal kan worden. SQLite 3.37.0 en later ondersteunen STRICT-tabellen, waarvan de toegestane typen INT, INTEGER, REAL, TEXT, BLOB en ANY zijn.
Kies voor orders een gehele id, een e-mailadres als tekst, een PostgreSQL-DATE of SQLite-datum als ISO-tekst, PostgreSQL-NUMERIC(10, 2) of gehele centen in SQLite voor het totaal, en een Booleaanse waarde of 0/1-indicator voor de betaling. NULL betekent ontbrekend of onbekend; het is geen type en is niet hetzelfde als nul of een lege tekenreeks. Een kolom accepteert het tenzij een regel dat verbiedt.
Belangrijkste punten
- Kies typen op basis van het gebruik: rekenen, tekst, tijd of ja/nee.
- De precisie van NUMERIC telt alle cijfers; de schaal telt de decimalen.
- Gebruik PostgreSQL-NUMERIC of gehele centen in SQLite voor exacte geldbedragen.
- ISO-datumtekst sorteert op datum als deze consequent is genoteerd.
- SQLite-affiniteit staat gemengde opslag toe; STRICT maakt typecontroles strenger.
- NULL markeert een ontbrekende of onbekende waarde.
2Bescherm gegevens met integriteitsregels
Een database kan regels controleren op het moment dat gegevens veranderen, ongeacht welk programma de wijziging verstuurt. Kolomregels controleren ontbrekende waarden, dubbele waarden en bereiken; sleutels identificeren rijen en houden koppelingen tussen tabellen geldig. Je volgt geaccepteerde en geweigerde invoegingen, kiest gegenereerde identificatiewaarden en voorspelt wat er met orders gebeurt als een klant wordt verwijderd. Deze regels werken samen: een controle op de prijs heeft een andere taak dan de eis dat de prijs aanwezig is.
2.1 Stel verplichte waarden, standaardwaarden en beperkingen in met NOT NULL, DEFAULT, UNIQUE en CHECK
Een integriteitsregel laat de database gegevens weigeren die een gedeclareerde regel schenden. De controle wordt uitgevoerd wanneer rijen worden ingevoegd of bijgewerkt, ongeacht welke applicatie de instructie verstuurt. Verschillende regels beschermen verschillende onderdelen van een productrecord.
Combineer regels in een tabel
Deze SQLite-definitie genereert de sleutel en controleert de andere velden. Vervang voor PostgreSQL de sleutelregel door een primaire sleutel met identiteit.
CREATE TABLE products (
id INTEGER PRIMARY KEY,
sku TEXT NOT NULL UNIQUE,
name TEXT NOT NULL,
price NUMERIC(8, 2) NOT NULL CHECK (price > 0),
in_stock INTEGER NOT NULL DEFAULT 0 CHECK (in_stock >= 0)
);
NOT NULL vereist een waarde. UNIQUE voorkomt een herhaalde SKU. CHECK (price > 0) weigert prijzen van nul of lager. De voorraad heeft een standaardwaarde van 0 en mag niet negatief worden. De numerieke declaratie van SQLite zorgt niet voor exact decimaal rekenen, dus gebruik gehele centen wanneer exactheid van belang is.
Maak onderscheid tussen weglaten en NULL
Voeg een bureaulamp in met SKU 'LAMP-01', naam 'Desk lamp' en prijs 24,99, en laat de voorraad uit de kolommenlijst weg. De invoeging slaagt en de voorraad wordt 0. Met een opgegeven voorraad van NULL vraag je niet om de standaardwaarde: die voldoet niet aan NOT NULL.
Een koffiemok met een prijs van -3,50 voldoet niet aan de prijscontrole. Een tweede product met SKU 'LAMP-01' voldoet niet aan UNIQUE, ook als de naam en prijs verschillen. Een pen zonder naam voldoet niet aan NOT NULL. Lees welke regel of kolom in de foutmelding wordt genoemd en corrigeer de invoer.
Lege tekst is een echte waarde. name TEXT NOT NULL accepteert '' in SQLite en PostgreSQL. Voeg CHECK (name <> '') toe om die te weigeren. Oracle behandelt lege tekst als NULL, dus daar valt dezelfde invoer onder een andere regel.
Controleer combinaties en ontbrekende waarden
Een kolomregel volgt op het type. Een tabelregel is een afzonderlijk onderdeel binnen de tabeldefinitie en kan kolommen vergelijken:
CHECK (end_date >= start_date),
UNIQUE (order_id, product_id)
De eerste weigert een einddatum vóór een begindatum. De tweede weigert een herhaald paar: een product kan in verschillende orders voorkomen, maar niet tweemaal in dezelfde order. Een tabel kan meerdere uniekheidsregels hebben.
Een controle weigert een rij als de voorwaarde onwaar is. Als de prijs NULL is, is price > 0 onbekend en komt de rij dus door de controle. Daarom heeft de productprijs ook NOT NULL nodig. PostgreSQL, SQLite en MySQL staan normaal gesproken meerdere NULL-waarden toe onder UNIQUE; SQL Server staat er één toe bij een uniekheidsregel voor één kolom. PostgreSQL 15 en later bieden UNIQUE NULLS NOT DISTINCT als ook ontbrekende waarden met elkaar moeten botsen. MySQL-versies vóór 8.0.16 negeerden CHECK-regels.
Geef een regel een bruikbare naam met CONSTRAINT price_positive CHECK (price > 0). De naam helpt om de regel in een foutmelding te herkennen en later te verwijderen. Een integriteitsregel controleert precies de eigen expressie: CHECK (email LIKE '%@%') vangt een ontbrekend apenstaartje op, maar geen typefout in een adres dat verder aan het patroon voldoet.
Belangrijkste punten
- NOT NULL weigert ontbrekende waarden, maar weigert geen lege tekst in SQLite of PostgreSQL.
- DEFAULT vult weggelaten kolommen; een expliciete NULL vraagt niet om de standaardwaarde.
- UNIQUE kan een kolom of een combinatie van kolommen beschermen.
- CHECK weigert onware voorwaarden; voeg NOT NULL toe als ook onbekend moet worden geweigerd.
- Fouten door integriteitsregels wijzen gegevens aan die moeten worden gecorrigeerd.
2.2 Identificeer rijen met primaire sleutels en gegenereerde identificatiewaarden
Een primaire sleutel identificeert een rij op betrouwbare wijze. Dat kan één kolom of een combinatie zijn, maar een tabel heeft maximaal één primaire sleutel. De sleutel moet uniek en aanwezig zijn, zodat andere instructies een rij kunnen aanduiden zonder afhankelijk te zijn van de beschrijving ervan.
Kies een stabiele identificatiewaarde
Een natuurlijke sleutel is een bestaande identificatiewaarde uit de praktijk, zoals het ISBN van een boek. Een surrogaatsleutel is een kunstmatige identificatiewaarde, vaak een gegenereerd geheel getal. Het e-mailadres van een klant kan veranderen; een gegenereerde klantidentificatie kan daarbij gelijk blijven.
Een samengestelde sleutel identificeert een combinatie:
PRIMARY KEY (order_id, product_id)
Een order kan meerdere producten bevatten en een product kan in meerdere orders voorkomen. Het paar identificeert één orderregel. Geen van beide kolommen hoeft afzonderlijk uniek te zijn.
PostgreSQL, MySQL en SQL Server dwingen af dat primaire sleutels aanwezig zijn. Gewone SQLite-tabellen behouden een historische uitzondering: een primaire sleutel die geen INTEGER PRIMARY KEY is, kan NULL bevatten. Gebruik code TEXT PRIMARY KEY NOT NULL voor een tekstsleutel. SQLite-STRICT-tabellen sluiten deze uitzondering ook uit.
Laat de database het nummer genereren
| Database | Declaratie van een gegenereerde primaire sleutel |
|---|---|
| SQLite | id INTEGER PRIMARY KEY |
| PostgreSQL | id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY |
| MySQL | id INT AUTO_INCREMENT PRIMARY KEY |
| SQL Server | id INT IDENTITY(1, 1) PRIMARY KEY |
Laat id weg uit de kolommenlijst van de invoeging om een gegenereerde waarde te vragen. Een gewone PostgreSQL-INTEGER PRIMARY KEY genereert die niet. Oudere PostgreSQL-code gebruikt vaak SERIAL.
In SQLite is INTEGER PRIMARY KEY een alias voor het interne rijnummer. Begin met de gegenereerde identificatiewaarden 1, 2 en 3 en verwijder daarna 3. De volgende normaal gegenereerde identificatiewaarde is opnieuw 3, één boven het huidige maximum. Met INTEGER PRIMARY KEY AUTOINCREMENT is dat 4: een nummer dat een vastgelegde rij heeft gehad, wordt niet hergebruikt. Een nummer van een teruggedraaide invoeging kan nog wel worden hergebruikt. Deze sterkere garantie kost extra werk, dus kies ervoor als niet-hergebruiken een belangrijke eis is.
Lees identificatiewaarden zonder ze als aantallen te behandelen
Gaten zijn normaal. Verwijderingen laten ze achter en PostgreSQL geeft volgnummers na mislukte of teruggedraaide invoegingen niet opnieuw uit. Gebruik COUNT(*) voor een aantal rijen en een tijdstempel voor het tijdstip van een gebeurtenis. De grootste identificatiewaarde beantwoordt geen van beide vragen betrouwbaar.
De vorm GENERATED ALWAYS van PostgreSQL weigert normaal gesproken een expliciete identificatiewaarde zoals 50. GENERATED BY DEFAULT en SERIAL accepteren expliciete waarden, maar als je 50 opgeeft, gaat de generator daardoor niet voorbij 50. Een later gegenereerde waarde kan ermee botsen.
Lees de sleutel terug om die van een nieuwe rij in een gerelateerde rij te gebruiken:
INSERT INTO customers (first_name, last_name, email)
VALUES ('Dev', 'Patel', 'dev@example.com')
RETURNING id;
RETURNING werkt in PostgreSQL en SQLite 3.35.0 en later. SQLite biedt ook last_insert_rowid(), MySQL biedt LAST_INSERT_ID() en SQL Server gebruikt OUTPUT. Lees het resultaat van de invoeging in plaats van de volgende identificatiewaarde te raden.
Belangrijkste punten
- Een primaire sleutel identificeert een rij; een samengestelde sleutel identificeert een combinatie.
- Gegenereerde sleutels worden in verschillende databases verschillend gedeclareerd.
- SQLite-AUTOINCREMENT voorkomt hergebruik van vastgelegde identificatiewaarden, maar kost extra werk.
- Gaten in identificatiewaarden zijn normaal; gebruik COUNT(*) om rijen te tellen.
- RETURNING leest de daadwerkelijk gegenereerde sleutel terug.
2.3 Koppel tabellen met refererende sleutels
De customer_id van een order moet verwijzen naar een klant die bestaat. Een refererende sleutel laat de database die koppeling controleren. De tabel met de verwijzing is de kindtabel; de tabel waarnaar wordt verwezen is de oudertabel.
Declareer en handhaaf de koppeling
CREATE TABLE orders (
id INTEGER PRIMARY KEY,
customer_id INTEGER NOT NULL REFERENCES customers(id)
);
Hier moet customers eerst bestaan en moet de id daarvan een primaire of unieke sleutel zijn. Zorg dat de typen aan beide kanten overeenkomen. De tabelvorm, FOREIGN KEY (customer_id) REFERENCES customers(id), declareert dezelfde koppeling los van de kolom.
Als handhaving is ingeschakeld, mislukt een order voor klant 99 wanneer klant 99 niet bestaat. Een order wijzigen naar die ontbrekende klant mislukt ook. Een refererende sleutel die NULL toestaat, kan NULL bevatten, wat betekent dat er geen gekoppelde rij is; NOT NULL maakt de koppeling verplicht.
Voer in SQLite PRAGMA foreign_keys = ON; uit op elke nieuwe verbinding voordat je een transactie start. Een wijziging van de instelling binnen een transactie heeft geen effect. PostgreSQL en SQL Server handhaven refererende sleutels normaal gesproken, en de standaardengine InnoDB van MySQL doet dat ook.
Voorspel wat er gebeurt als een ouder wordt verwijderd
Gebruik klanten 1, Ana, en 2, Ben. Orders 101 en 102 horen bij Ana; 103 hoort bij Ben. Bekijk wat er gebeurt als klant 1 onder verschillende declaraties wordt verwijderd:
| ON DELETE-actie | Resultaat |
|---|---|
NO ACTION of RESTRICT | De verwijdering mislukt zolang 101 en 102 naar Ana verwijzen. |
CASCADE | Ana, 101 en 102 worden verwijderd; Ben en 103 blijven bestaan. |
SET NULL | Ana wordt verwijderd; alle orders blijven bestaan, waarbij 101 en 102 worden ontkoppeld. |
SET DEFAULT | De verwijzende waarden krijgen hun gedeclareerde standaardwaarde. |
SET NULL heeft een kolom nodig die NULL toestaat. Ook SET DEFAULT moet aan de refererende sleutel voldoen: een standaardwaarde die niet ontbreekt, moet een bestaande ouder identificeren. Een standaardwaarde NULL werkt wanneer ontbrekende koppelingen zijn toegestaan.
Kies op basis van de betekenis van de gegevens. Orderregels horen vaak volledig bij hun order, dus cascadering kan passen. Voor orders die bewaard moeten blijven, is een blokkerende actie nodig als iemand hun klant probeert te verwijderen. Een optionele leverancierskoppeling kan op NULL worden gezet. Als je overal cascadering toepast, kan één verwijdering meer records verwijderen dan de tabelnaam doet vermoeden.
Werk in volgorde van afhankelijkheid
Maak ouders vóór kinderen en voeg ouderr ijen in vóór rijen die ernaar verwijzen. Werk bij het verwijderen van gerelateerde gegevens of tabellen van kinderen naar ouders. Een ON UPDATE-actie biedt dezelfde keuzes wanneer de sleutel van de ouder verandert; ON UPDATE CASCADE kopieert de nieuwe sleutel naar de kinderen.
RESTRICT controleert direct. NO ACTION, de standaardwaarde, kan wachten tot het einde van de instructie, of tot het einde van de transactie bij een uitstelbare integriteitsregel. Beide blokkeren een gewone verwijdering die verwijzingen zonder overeenkomst zou achterlaten. Houd gegenereerde identificatiewaarden stabiel, zodat je niet elke verwijzing naar een klant hoeft te wijzigen als diens gegevens veranderen.
Belangrijkste punten
- Een refererende sleutel koppelt kindwaarden aan een bestaande primaire of unieke sleutel van de ouder.
- NULL staat een optionele koppeling toe, tenzij NOT NULL dat verbiedt.
- CASCADE verwijdert kinderen; SET NULL behoudt ze zonder hun koppeling.
- Schakel refererende sleutels in SQLite vóór BEGIN in op elke verbinding.
- Maak ouders eerst en voeg ze eerst in; verwijder kinderen eerst, zowel rijen als tabellen.
- Kies acties op basis van de records die bewaard moeten blijven.
3Voeg rijen toe met INSERT
Rijen toevoegen betekent elke waarde aan de juiste kolom koppelen en de database het resultaat laten controleren. Je kunt een product rechtstreeks invoeren, meerdere klanten tegelijk toevoegen en oudere orders uit een query kopiëren. Je leest ook een gegenereerde sleutel terug en kiest hoe je met een bestaande SKU omgaat. Dezelfde invoer kan een vervangende voorraadstand of een extra levering betekenen, dus een upsert moet de bedoelde wijziging precies uitdrukken.
3.1 Voeg rijen in met VALUES
INSERT voegt rijen toe aan een bestaande tabel. De kolommenlijst bepaalt hoe de opgegeven waarden worden gekoppeld aan de velden die ze ontvangen. Schrijf die lijst expliciet, zodat een latere tabelwijziging de betekenis van je invoer niet ongemerkt verandert.
Koppel waarden op volgorde
INSERT INTO products (sku, name, price, in_stock)
VALUES ('LAMP-01', 'Desk lamp', 24.99, 12);
Lees de paren op volgorde: SKU krijgt 'LAMP-01', naam krijgt 'Desk lamp', prijs krijgt 24,99 en voorraad krijgt 12. Voor deze vier kolommen moeten er vier waarden zijn. Een verschil, zoals twee waarden voor drie kolommen, leidt tot een fout.
Zonder de lijst volgen de waarden de gedeclareerde kolomvolgorde van de tabel. SQLite vereist dat alle kolommen een waarde krijgen; PostgreSQL staat minder waarden toe en geeft de resterende kolommen aan het einde hun standaardwaarde. Met een expliciete lijst hoef je niet op een van beide werkwijzen te vertrouwen. Je kunt de kolommen ook in een volgorde zetten die duidelijk is voor de invoer.
Een verwisseld paar kan erger zijn dan een syntaxisfout. Als je 9,99 als naam en 'Desk lamp' als prijs opgeeft, weigert PostgreSQL de niet-numerieke prijs. De gewone affiniteit van SQLite kan de naamtekst “9.99” en prijstekst “Desk lamp” zonder fout opslaan. Lees de ingevoegde rij terug met SELECT om de koppeling te controleren.
Schrijf literals correct
| Soort | SQL-voorbeeld |
|---|---|
| Tekst | 'Desk lamp' |
| Tekst met een apostrof | 'O''Brien' |
| Getal | 1250.50 |
| ISO-datum | '2026-03-15' |
| Ontbrekende waarde | NULL |
De dubbele apostrof slaat één apostrof op. Getallen hebben geen valutateken of scheidingsteken voor duizendtallen; een komma scheidt waarden, dus een komma binnen een bedrag zonder aanhalingstekens verandert het aantal waarden. 'NULL' is de tekst “NULL” van vier letters, geen ontbrekende waarde.
Laat weggelaten velden zichzelf vullen
Een weggelaten kolom krijgt de standaardwaarde, of NULL als er geen standaardwaarde is. Een gegenereerde sleutel krijgt een gegenereerde waarde. Dat laatste gedrag hangt af van de declaratie: INTEGER PRIMARY KEY van SQLite genereert identificatiewaarden; PostgreSQL heeft daarvoor een identiteitsdeclaratie nodig. Een gewone primaire sleutel met een geheel getal in PostgreSQL die uit een invoeging wordt weggelaten, leidt tot een fout omdat de waarde NULL zou zijn.
PostgreSQL, MySQL en SQL Server staan DEFAULT toe als plaatsaanduiding voor een waarde. SQLite accepteert dit niet binnen een VALUES-lijst; laat die kolom daar weg. Een expliciete NULL vraagt nooit om de standaardwaarde.
Voeg meerdere rijen tegelijk toe
INSERT INTO customers (first_name, last_name, email) VALUES
('Ana', 'Ruiz', 'ana@example.com'),
('Ben', 'Okafor', 'ben@example.com'),
('Chloe', 'Nguyen', 'chloe@example.com');
In een lege tabel waarvan de gegenereerde sleutel bij 1 begint, krijgen deze klanten de identificatiewaarden 1, 2 en 3. Bij de gewone afhandeling van integriteitsregels slaagt of mislukt de instructie voor meerdere rijen als geheel. Als één rij een regel schendt, wordt geen van de rijen van deze instructie ingevoegd.
Een UNIQUE-fout wijst op een dubbele sleutel of waarde; NOT NULL wijst op ontbrekende gegevens; CHECK wijst op een voorwaarde waaraan niet is voldaan; en een refererende-sleutelfout wijst op een ongeldige koppeling. Corrigeer de waarde of de bedoelde koppeling voordat je het opnieuw probeert.
Belangrijkste punten
- Vermeld de kolommen en koppel elke waarde er op volgorde aan.
- Weggelaten velden krijgen standaardwaarden of NULL; gegenereerde identificatiewaarden vereisen een generator.
- Gebruik enkele aanhalingstekens voor tekst en verdubbel een apostrof binnen de tekst.
- NULL en de tekst NULL zijn verschillend.
- Een gewone invoeging van meerdere rijen mislukt als geheel als één rij een integriteitsregel schendt.
3.2 Voeg queryresultaten in, haal nieuwe sleutels op en verwerk dubbele waarden
Je hoeft rijen niet één voor één in te typen. Een query kan de rijen voor een invoeging leveren en een conflictregel kan aangeven wat er moet gebeuren als een unieke waarde al bestaat. Bij beide functies is het belangrijk dat de gegevens precies overeenkomen met wat je bedoelt.
Kopieer een queryresultaat
INSERT INTO archived_orders (id, customer_id, order_date, total)
SELECT id, customer_id, order_date, total
FROM orders
WHERE order_date < '2026-01-01';
Er is geen VALUES-clausule: de query levert de waarden. Koppel de geselecteerde kolommen op volgorde aan de doellijst. De doeltabel moet al bestaan en de bijbehorende regels blijven gelden.
Bekijk de SELECT eerst afzonderlijk. Orders 201, 202 en 204 hebben de datums 2025-11-03, 2025-12-19 en 2025-10-30 en de bedragen 45,00, 120,50 en 60,00. Orders 203 en 205 zijn uit 2026. De query geeft drie rijen terug met een totaal van 225,50 en de invoeging kopieert die drie. Er kunnen ook nul rijen worden gekopieerd als het filter niets vindt.
Een tweede uitvoering probeert ze opnieuw te kopiëren. Een primaire sleutel in de doeltabel laat dat mislukken in plaats van ongemerkt dubbele gegevens op te slaan. INSERT ... SELECT is een kopieerbewerking; de bronrijen worden niet verwijderd en de twee tabellen worden niet gesynchroniseerd.
Bestanden worden vaak eerst in een stagingtabel geïmporteerd. De shell van SQLite gebruikt .import --csv file.csv staging; psql gebruikt \copy. In een latere query verwijdert TRIM(email) spaties aan het begin en einde en zet NULLIF(TRIM(email), '') een leeg e-mailadres om in NULL. De integriteitsregels van de doeltabel controleren vervolgens de opgeschoonde rijen.
Lees het resultaat van een schrijfbewerking
INSERT INTO customers (first_name, last_name, email)
VALUES ('Dev', 'Patel', 'dev@example.com')
RETURNING id;
Het resultaat geeft de gegenereerde klantidentificatie terug voor gebruik in een gerelateerde rij. PostgreSQL en SQLite 3.35.0 en later ondersteunen RETURNING bij invoegen, bijwerken en verwijderen. MySQL gebruikt LAST_INSERT_ID() voor een gegenereerde identificatiewaarde; SQL Server gebruikt OUTPUT.
Bepaal hoe dubbele waarden worden verwerkt
Stel dat bij stock (sku TEXT PRIMARY KEY, qty INTEGER NOT NULL) de hoeveelheid van 'LAMP-01' 12 is. Een gewone invoeging met dezelfde SKU en hoeveelheid 20 mislukt. In SQLite en PostgreSQL:
INSERT INTO stock (sku, qty) VALUES ('LAMP-01', 20)
ON CONFLICT (sku) DO UPDATE
SET qty = stock.qty + excluded.qty;
stock.qty is de bestaande 12. excluded.qty is de voorgestelde 20. Deze vorm slaat 32 op, wat past bij een extra levering. SET qty = excluded.qty slaat 20 op, wat past bij een vervangende voorraadstand. DO NOTHING behoudt 12 en slaat de conflicterende rij over. Elke variant gaat uit van dezelfde oorspronkelijke hoeveelheid 12.
Een upsert combineert het invoegen van een nieuwe rij met bijwerken bij een conflict. Het conflictdoel moet een geschikte uniekheidsregel hebben. De overeenkomstige instructiefamilie in MySQL is ON DUPLICATE KEY UPDATE. Een gewone INSERT corrigeert geen bestaande klant: er ontstaat een extra rij of een uniekheidsfout. Gebruik UPDATE voor een rij waarvan je weet dat die bestaat, en een upsert als de rij mogelijk al bestaat.
Belangrijkste punten
- INSERT ... SELECT kopieert queryresultaten naar een bestaande tabel.
- Bij het opnieuw uitvoeren van een kopieeractie moet je bewust omgaan met dubbele waarden.
- RETURNING geeft waarden terug uit de rijen die daadwerkelijk zijn geschreven.
- excluded duidt de voorgestelde rij aan in een upsert.
- Vervang de voorraad met excluded.qty; tel een levering erbij op met stock.qty + excluded.qty.
- DO NOTHING slaat een uniekheidsconflict over zonder de bestaande rij bij te werken.
4Wijzig en verwijder rijen met UPDATE en DELETE
Een geldige instructie die gegevens wijzigt, kan toch de verkeerde rijen treffen. Een prijs bijwerken, een order verwijderen en de te wijzigen records selecteren zijn afzonderlijke beslissingen. Je berekent nieuwe waarden op basis van opgeslagen waarden, leert het verschil tussen een veld leegmaken en een rij verwijderen, en stelt voorwaarden op met datums, ontbrekende waarden en gegroepeerde alternatieven. Door vooraf te bekijken en het resultaat te controleren, zie je het effect voordat een transactie de wijziging definitief vastlegt.
4.1 Wijzig waarden met UPDATE
UPDATE wijzigt waarden in bestaande rijen. De instructie noemt een tabel, wijst met SET nieuwe waarden toe en kiest vervolgens met WHERE de doelrijen. De integriteitsregels van de tabel controleren de resulterende waarden.
Stel één of meer velden in
UPDATE products
SET price = 22.50, in_stock = 30
WHERE id = 3;
Het product met sleutel 3 krijgt beide waarden; andere rijen behouden hun waarden. Tussen toewijzingen staan komma's. SET price = 22.50 AND in_stock = 30 betekent geen twee toewijzingen. PostgreSQL weigert dit; SQLite behandelt de rechterkant als een Booleaanse expressie en kan 0 of 1 opslaan in de prijs.
Een ontbrekende WHERE is geldige SQL en de instructie geldt dan voor elke rij. UPDATE products SET price = 0; zet de prijs van elk product op nul als de regels van de tabel dat toestaan. Als je vooraf met de bedoelde voorwaarde kijkt, zie je of het doel één rij, meerdere rijen of geen rijen omvat.
Bereken op basis van de opgeslagen waarde
UPDATE products
SET price = price * 1.10;
Een prijs van 20,00 wordt 22,00 na een verhoging van 10%. Een prijs van 19,99 geeft een niet-afgerond resultaat van 21,989. PostgreSQL slaat 21,99 op in een kolom van het type NUMERIC(8, 2). SQLite dwingt de schaal niet af, dus vraagt SET price = ROUND(price * 1.10, 2) om twee decimalen. Bewaar voor exacte opslag van geld in SQLite gehele centen en maak de keuze voor afronding op centen expliciet.
Bij een relatieve wijziging moet de expressie de oude waarde bevatten. SET in_stock = in_stock - 1 haalt één eenheid weg; SET in_stock = 1 vervangt het aantal door één.
In SQLite en PostgreSQL lezen alle expressies rechts van de toewijzing de rij zoals die vóór de wijziging was. UPDATE t SET a = b, b = a; verwisselt de waarden van een rij van 1 en 2 naar 2 en 1. Een wijziging op één tabel in MySQL evalueert toewijzingen van links naar rechts, zodat dezelfde vorm beide waarden 2 maakt. Ga er niet van uit dat dit in alle systemen hetzelfde werkt.
Houd rekening met regels en ontbrekende waarden
Gebruik SET phone = NULL om een telefoonveld leeg te maken. Gebruik WHERE phone IS NULL om ontbrekende telefoonwaarden te vinden. Een gelijkheidsvergelijking met NULL vindt ze niet.
Neem prijzen van 12,00, 3,00 en 8,50 die worden beschermd door CHECK (price > 0). Als je van elke prijs 5 aftrekt, wordt de tweede -2,00. Bij de gewone afhandeling van integriteitsregels draait die fout de hele instructie terug, zodat zelfs de verder geldige prijzen ongewijzigd blijven.
Een wijziging van een primaire sleutel moet ook aan gerelateerde refererende sleutels voldoen. Een geblokkeerde sleutelwijziging mislukt zolang kinderen naar de oude sleutel verwijzen; ON UPDATE CASCADE geeft de nieuwe waarde aan hen door. Door gegenereerde identificatiewaarden stabiel te houden, voorkom je dit extra werk als beschrijvende gegevens veranderen.
Interpreteer het aantal getroffen rijen
psql meldt een resultaat zoals UPDATE 3; changes() van SQLite geeft het aantal voor de laatste wijzigingsinstructie. Beide tellen geselecteerde en bijgewerkte rijen mee, ook als de toegewezen waarde gelijk is aan de oude waarde. Een aantal van drie garandeert geen drie zichtbaar verschillende waarden. Vergelijk het aantal met de selectie vooraf en bekijk daarna de relevante velden, of gebruik RETURNING om getroffen rijen direct te zien.
Belangrijkste punten
- SET wijst waarden toe; WHERE kiest rijen.
- Scheid toewijzingen met komma's, niet met AND.
- Gebruik de oude kolomwaarde in een relatieve berekening.
- Een gewone fout door een integriteitsregel draait de hele UPDATE-instructie terug.
- Aantallen getroffen rijen kunnen ook rijen bevatten waarvan de waarden gelijk zijn gebleven.
4.2 Verwijder rijen met DELETE
DELETE verwijdert hele rijen. De tabel blijft bestaan en kan opnieuw rijen bevatten. Gebruik UPDATE ... SET column = NULL om één veld leeg te maken; DELETE email FROM customers is geen geldige SQL.
Volg een gefilterde verwijdering
De winkel heeft deze orders:
| ID | Status | Orderdatum |
|---|---|---|
| 201 | geannuleerd | 2025-11-03 |
| 202 | verzonden | 2025-12-19 |
| 203 | geannuleerd | 2026-01-08 |
| 204 | geannuleerd | 2025-10-30 |
| 205 | verlopen | 2026-02-14 |
DELETE FROM orders
WHERE status = 'cancelled'
AND order_date < '2026-01-01';
Order 201 voldoet aan beide voorwaarden, net als 204. Order 203 is geannuleerd maar te recent; 202 is oud genoeg maar verzonden. De instructie verwijdert twee rijen en laat 202, 203 en 205 staan. DELETE FROM orders; zonder de voorwaarde zou alle vijf verwijderen.
Gebruik gerelateerde gegevens om rijen te kiezen
DELETE FROM order_items
WHERE order_id IN (
SELECT id FROM orders WHERE status = 'cancelled'
);
De binnenste query levert de identificatiewaarden van geannuleerde orders. IN vergelijkt de order_id van elke orderregel met die lijst. Voer de binnenste query afzonderlijk uit om de sleutels te bekijken en bekijk daarna de orderregels vooraf met dezelfde voorwaarde.
Refererende sleutels beïnvloeden de verwijdering ook. Een ouder met verwijzende kinderen kan worden beschermd door NO ACTION of RESTRICT; cascadering verwijdert kinderen; SET NULL behoudt kinderen maar maakt de koppeling leeg. Controleer die acties wanneer je het effect van het verwijderen van een ouder beoordeelt, want mogelijk verandert meer dan alleen de rechtstreeks genoemde tabel.
Kies wat moet blijven bestaan
| Instructie | Verwijderde rijen | Wat blijft bestaan |
|---|---|---|
DELETE ... WHERE ... | Overeenkomende rijen | Tabel en overige rijen |
DELETE FROM orders; | Alle rijen | Lege tabel |
TRUNCATE TABLE orders; | Alle rijen, zonder WHERE | Lege tabel |
DROP TABLE orders; | Alle rijen met de tabel | Geen orders-tabel |
PostgreSQL, MySQL, SQL Server en Oracle ondersteunen TRUNCATE; SQLite niet. De regels voor transacties en afhankelijkheden verschillen per database. Ook een instructie die klinkt als een snelle manier om een tabel leeg te maken, moet binnen die regels passen.
Bewaar geschiedenis met een logische verwijdering
UPDATE customers
SET deleted_at = '2026-03-15'
WHERE id = 7;
Een logische verwijdering markeert de rij zonder die te verwijderen. Zo kun je de geschiedenis bewaren en de rij herstellen door de markering te wissen. Query's voor actieve klanten moeten WHERE deleted_at IS NULL bevatten; anders verschijnen de gemarkeerde klanten nog steeds. Gegevens markeren wist ze niet.
Een vastgelegde verwijdering kan niet met een latere ROLLBACK ongedaan worden gemaakt. Herstel vereist een opgeslagen kopie of back-up. Binnen een open transactie kan een terugdraaiing verwijderde rijen nog herstellen. Controleer de geselecteerde identificatiewaarden en het aantal getroffen rijen voordat je het resultaat definitief vastlegt.
Belangrijkste punten
- DELETE verwijdert rijen; UPDATE kan één veld leegmaken.
- Een ontbrekende WHERE maakt de tabel leeg terwijl de structuur behouden blijft.
- IN kan rijen selecteren met sleutels uit een andere tabel.
- Refererende-sleutelacties kunnen een verwijdering uitbreiden of blokkeren.
- Een logische verwijdering vereist filters voor actieve rijen en wist de opgeslagen gegevens niet.
- ROLLBACK herstelt een verwijdering alleen zolang de transactie niet is vastgelegd.
4.3 Selecteer precies de rijen die je bedoelt
Rijen kiezen is vaak het moeilijkste onderdeel van een wijziging. Hetzelfde filter dat in een query onschuldig is, kan te veel verwijderen of bijwerken als je het opnieuw gebruikt bij een schrijfbewerking. Zet de bedoelde regel om in een voorwaarde en bekijk vervolgens wat die daadwerkelijk selecteert.
Bekijk precies dezelfde voorwaarde vooraf
SELECT id, status, order_date FROM orders
WHERE status = 'cancelled'
AND order_date < '2026-01-01';
Deze selectie geeft orders 201 en 204 terug in het winkelvoorbeeld met vijf orders. Gebruik precies die voorwaarde opnieuw bij het verwijderen. Als je die herschrijft terwijl je de opdracht wijzigt, ontstaat een nieuwe, ongecontroleerde selectie.
Gebruik voor één specifieke rij de primaire sleutel: WHERE id = 42 selecteert maximaal één rij. Meerdere producten kunnen dezelfde beschrijvende naam hebben, zoals 'Desk lamp'.
Groepeer alternatieven expliciet
AND bindt sterker dan OR. Vergelijk:
WHERE status = 'cancelled'
OR status = 'expired' AND order_date < '2026-01-01'
met:
WHERE (status = 'cancelled' OR status = 'expired')
AND order_date < '2026-01-01'
De eerste accepteert elke geannuleerde order, ongeacht de datum, plus verlopen orders van vóór 2026. Deze selecteert 201, 203 en 204. De tweede past de datumcontrole toe op beide statussen en selecteert 201 en 204. Order 203 laat het verschil zien omdat deze in 2026 is geannuleerd.
Neem ontbrekende waarden bewust mee
WHERE customer_id = NULL selecteert geen rijen. Ontbrekende waarden vereisen IS NULL of IS NOT NULL. Een negatieve test heeft ook een leemte: status <> 'shipped' neemt een ontbrekende status niet mee, omdat de vergelijking onbekend is.
Als een ontbrekende status bij de bedoelde groep hoort, schrijf je:
WHERE status <> 'shipped' OR status IS NULL
Als je nog een voorwaarde toevoegt, groepeer je dit hele alternatief met haakjes zodat beide takken aan die voorwaarde voldoen.
Een patroon kan meer vinden dan de bedoelde beschrijving. LIKE '%lamp%' vindt “Desk lamp” en “Clamp”. De standaardinstelling van LIKE in SQLite negeert ook het verschil tussen hoofdletters en kleine letters bij Engelse letters, zodat “Lamp shade” wordt gevonden. Een patroon is nuttig om mogelijke overeenkomsten te vinden, maar bekijk die overeenkomsten voordat je ze wijzigt.
Kies een lijstvergelijking voor een lijst
UPDATE orders SET status = 'on hold'
WHERE customer_id IN (
SELECT id FROM customers WHERE state = 'CA'
);
De subquery kan meerdere klantidentificaties leveren; IN controleert of een waarde in de lijst staat. Als je IN vervangt door =, vraag je om één scalaire waarde. PostgreSQL weigert daar meerdere rijen, terwijl SQLite ongemerkt de eerste teruggegeven rij gebruikt en andere klanten mist.
Vergelijk na de wijziging het aantal getroffen rijen met de selectie vooraf. PostgreSQL en SQLite kunnen ook RETURNING * toevoegen om de getroffen rijen te tonen. Start bij een risicovolle schrijfbewerking een transactie voordat je gegevens wijzigt, bekijk het resultaat en kies daarna COMMIT of ROLLBACK.
Belangrijkste punten
- Bekijk vooraf precies de WHERE-voorwaarde die de schrijfbewerking gaat gebruiken.
- Een filter op de primaire sleutel identificeert maximaal één rij.
- Met haakjes laat je OR-alternatieven een AND-voorwaarde delen.
- IS NULL verwerkt ontbrekende waarden; gewone vergelijkingen slaan ze over.
- IN accepteert een lijst uit een subquery; scalaire gelijkheid niet.
- Controleer het aantal en het resultaat voordat je vastlegt.
5Bundel wijzigingen in transacties
Sommige wijzigingen horen bij elkaar: een overboeking heeft zowel een afschrijving als een bijschrijving nodig. Met transacties beslis je voor die instructies als geheel of je ze vastlegt of terugdraait, terwijl je met savepoints naar een tussenliggend punt kunt terugkeren. Je volgt saldi bij geslaagde wijzigingen en fouten en vergelijkt daarna hoe SQLite en PostgreSQL een mislukte instructie afhandelen. De instellingen van de database en client zijn van belang, vooral wanneer een structuurwijziging eerder werk kan vastleggen.
5.1 Leg een groep wijzigingen vast of draai deze terug
Een transactie bundelt samenhangende instructies tot één werkeenheid. Je beslist of je de wijzigingen samen vastlegt met COMMIT of samen terugdraait met ROLLBACK. De alles-of-niets-eigenschap heet atomiciteit, de A in ACID.
Behoud beide kanten van een overboeking
De rekening van Maya, ID 1, bevat € 500,00. De rekening van Leo, ID 2, bevat € 120,00. Voor het overboeken van € 75,00 zijn twee wijzigingen nodig:
BEGIN;
UPDATE accounts SET balance = balance - 75.00 WHERE id = 1;
UPDATE accounts SET balance = balance + 75.00 WHERE id = 2;
SELECT id, balance FROM accounts WHERE id IN (1, 2);
COMMIT;
Na de eerste wijziging heeft Maya € 425,00. Na de tweede heeft Leo € 195,00. De controle toont beide saldi vóór het vastleggen en het totaal blijft € 620,00. Gebruik voor deze exacte decimale saldi PostgreSQL-NUMERIC; een SQLite-versie voor exacte geldbedragen slaat 50.000 en 12.000 cent op en boekt 7500 cent over.
Zonder expliciete transactie bij autocommit zou de eerste wijziging definitief kunnen worden voordat de tweede wordt uitgevoerd. Een crash daartussen zou de afschrijving behouden zonder de bijschrijving. Met een transactie neem je voor beide wijzigingen één definitieve beslissing om ze te behouden of terug te draaien. Handel een eventuele fout af voordat je besluit dat de overboeking is voltooid.
Begrijp de standaardgrens
Bij autocommit van de database wordt elke geslaagde afzonderlijke instructie als eigen transactie vastgelegd. Dit is de gebruikelijke begininstelling voor SQLite, PostgreSQL, MySQL en SQL Server. Een programmabibliotheek of client kan andere instellingen kiezen en een transactie voor je starten.
BEGIN; start een expliciete transactie in SQLite en PostgreSQL. SQLite en SQL Server gebruiken ook BEGIN TRANSACTION; PostgreSQL en MySQL accepteren START TRANSACTION. Oracle start een transactie bij een gegevenswijziging en wacht in programma's zoals SQL*Plus gewoonlijk op COMMIT, tenzij autocommit is ingeschakeld.
COMMIT beëindigt de transactie en legt de wijzigingen vast. ROLLBACK beëindigt de transactie en draait de niet-vastgelegde wijzigingen terug. Een latere terugdraaiing kan niet voorbij een eerdere vastlegging gaan.
Bekijk en draai terug
BEGIN;
DELETE FROM orders;
SELECT * FROM orders;
ROLLBACK;
Je verbinding ziet bij de SELECT een lege tabel en na de terugdraaiing weer de vijf orders. Het lege resultaat was werkelijk binnen de transactie, maar nog niet definitief. Andere verbindingen zien de niet-vastgelegde wijzigingen normaal gesproken niet.
Een transactie kan je alleen beschermen tegen een verkeerde rijselectie als je die bekijkt en besluit haar terug te draaien. SQL kan een onbedoelde rij met succes bijwerken: geen enkele databaseregel weet welke rekening je bedoelde. Vergelijk teruggegeven identificatiewaarden, waarden en aantallen met het bedoelde resultaat voordat je vastlegt.
Houd transacties kort en beëindig ze. Open transacties kunnen vergrendelingen vasthouden waardoor andere verbindingen moeten wachten; SQLite staat slechts één schrijver tegelijk toe. Als je een verbinding met een onvoltooide transactie sluit, worden de nog niet vastgelegde wijzigingen teruggedraaid. Wanneer een bibliotheek automatisch een transactie start, moet het programma de commitmethode aanroepen om het werk vast te leggen.
Belangrijkste punten
- Door atomiciteit kunnen samenhangende wijzigingen samen worden vastgelegd of teruggedraaid.
- Autocommit legt een geslaagde afzonderlijke instructie definitief vast.
- Je verbinding kan de eigen nog niet vastgelegde wijzigingen bekijken.
- Zowel COMMIT als ROLLBACK beëindigt de transactie.
- ROLLBACK kan werk uit een eerder vastgelegde transactie niet ongedaan maken.
5.2 Ga binnen een transactie om met fouten, savepoints en structuurwijzigingen
Een mislukte instructie heeft niet in elke database hetzelfde effect. Je moet weten wat nog niet is vastgelegd voordat je beslist hoe je herstelt. Een savepoint kan een tussenliggend punt bieden waarnaar je binnen een open transactie kunt terugkeren.
Volg een fout
Na de overboeking heeft Maya € 425,00 en Leo € 195,00. De tabel heeft CHECK (balance >= 0). Start een transactie en trek € 30,00 af van Maya: haar nog niet vastgelegde saldo is € 395,00. Probeer vervolgens € 300,00 van Leo af te trekken. Dat zou zijn saldo op -€ 105,00 brengen, dus de tweede instructie mislukt.
| Database | Toestand na de gewone fout door een integriteitsregel |
|---|---|
| SQLite | De mislukte instructie is teruggedraaid; Maya's eerdere wijziging is nog niet vastgelegd. |
| PostgreSQL | De transactie is mislukt en verdere gewone opdrachten worden geweigerd. |
Als je in SQLite op dit punt vastlegt, blijft alleen Maya's afschrijving behouden. In PostgreSQL beëindigt COMMIT op de mislukte transactie deze met een terugdraaiing. Een duidelijke herstelprocedure is ROLLBACK uitvoeren, de oorzaak corrigeren en de samenhangende instructies opnieuw uitvoeren. Beide saldi keren dan vóór de gecorrigeerde poging terug naar € 425,00 en € 195,00.
Draai een later deel terug met een savepoint
BEGIN;
UPDATE accounts SET balance = balance + 10 WHERE id = 1;
SAVEPOINT after_first;
UPDATE accounts SET balance = balance + 10 WHERE id = 2;
ROLLBACK TO after_first;
COMMIT;
Het savepoint komt na Maya's verhoging. ROLLBACK TO draait Leo's latere verhoging terug, maar behoudt die van Maya. De eindsaldi zijn € 435,00 en € 195,00. Dit beëindigt de buitenste transactie niet; COMMIT doet dat.
RELEASE after_first verwijdert het savepoint zonder de wijzigingen erna terug te draaien. Het is geen zelfstandige definitieve vastlegging binnen de buitenste transactie. PostgreSQL staat ook toe dat ROLLBACK TO naar een savepoint van vóór een fout de mislukte toestand opheft en vanaf dat punt doorgaat.
Controleer of structuurwijzigingen kunnen worden teruggedraaid
SQLite en PostgreSQL staan CREATE TABLE, ALTER TABLE en DROP TABLE toe binnen transacties. Zo herstelt BEGIN; DROP TABLE orders; ROLLBACK; de tabel en de rijen.
Gewone DDL voor permanente tabellen veroorzaakt in MySQL en Oracle impliciete vastleggingen. Een CREATE TABLE, ALTER TABLE, DROP TABLE of TRUNCATE TABLE kan zowel eerdere, nog niet vastgelegde wijzigingen vastleggen als de eigen structuurbewerking uitvoeren. Een latere terugdraaiing kan dat eerdere werk niet ongedaan maken. Ga er niet van uit dat alle databasedialecten zich hetzelfde gedragen doordat een script binnen een transactie staat.
Begin bij een risicovolle gegevenswijziging de transactie, voer de schrijfbewerking uit, bekijk de waarden en het aantal en leg daarna vast of draai terug. Bekijk bijvoorbeeld de prijzen van verlichting na UPDATE products SET price = ROUND(price * 1.10, 2) WHERE category = 'lighting';. Neem de beslissing snel, zodat de transactie ander werk niet laat wachten.
Belangrijkste punten
- Een gewone SQLite-fout door een integriteitsregel laat eerdere transactiewijzigingen nog niet vastgelegd.
- Een PostgreSQL-fout laat de transactie in een mislukte toestand totdat je terugdraait of herstelt naar een savepoint.
- ROLLBACK TO draait later werk terug zonder de transactie te beëindigen.
- RELEASE verwijdert een savepoint zonder de buitenste transactie vast te leggen.
- Of DDL kan worden teruggedraaid, hangt af van de database.
6Wijzig de tabelstructuur met ALTER TABLE en DROP TABLE
Tabellen hebben soms een nieuw veld, een duidelijkere naam of een strengere regel nodig nadat ze al gegevens bevatten. Om die structuur te wijzigen moet je de bestaande rijen en de objecten die van de tabel afhankelijk zijn controleren. Je voegt kolommen toe en vult ze, herkent wanneer SQLite een heropbouw nodig heeft en leert het verschil tussen records verwijderen en de tabel verwijderen waarin ze staan. Afhankelijkheden bepalen ook de werkvolgorde wanneer gerelateerde tabellen buiten gebruik worden gesteld.
6.1 Voeg kolommen toe, hernoem ze en verwijder ze met ALTER TABLE
ALTER TABLE wijzigt de structuur van een bestaande tabel en behoudt de rijen. UPDATE wijzigt de waarden in die rijen. Een kortingsveld toevoegen vereist ALTER TABLE; de al opgeslagen kortingen verhogen vereist UPDATE.
Voeg velden toe en hernoem ze
ALTER TABLE customers ADD COLUMN phone TEXT;
ALTER TABLE customers RENAME COLUMN phone TO mobile;
ALTER TABLE customers RENAME TO clients;
SQLite en PostgreSQL delen deze vormen. Een nieuwe kolom geeft bestaande rijen de standaardwaarde, of NULL als die er niet is. ADD COLUMN active INTEGER NOT NULL DEFAULT 1 geeft elke huidige rij een active-waarde van 1. email TEXT NOT NULL zonder standaardwaarde toevoegen aan een gevulde tabel mislukt omdat de bestaande rijen dan een verplichte waarde zouden missen.
SQLite ondersteunt RENAME COLUMN vanaf 3.25.0 en DROP COLUMN vanaf 3.35.0. Werk bij het hernoemen applicatiecode en opgeslagen query's bij die naar de oude naam verwijzen. SQL buiten de database kan de nieuwe naam niet automatisch ontdekken.
Vul gegevens voordat je ze verplicht maakt
Voeg in PostgreSQL een kolom toe die NULL toestaat, vul de bestaande rijen met geschikte waarden en maak de kolom pas daarna verplicht:
ALTER TABLE customers ADD COLUMN email TEXT;
UPDATE customers SET email = 'unknown@example.com'
WHERE email IS NULL;
ALTER TABLE customers ALTER COLUMN email SET NOT NULL;
Dit laat zien hoe je een verplicht veld vult; het verklaart e-mail niet uniek. Een echte unieke e-mailkolom heeft verschillende geldige waarden nodig. SET NOT NULL mislukt als er ontbrekende waarden overblijven. PostgreSQL ondersteunt ook het wijzigen van een type met ALTER COLUMN price TYPE NUMERIC(10, 2), het instellen van een standaardwaarde en het toevoegen van een benoemde controle. Bestaande rijen moeten aan een nieuw toegevoegde regel voldoen.
Verwijder een veld of bouw een tabel opnieuw op
ALTER TABLE customers DROP COLUMN mobile; verwijdert het veld en alle opgeslagen waarden daarin. Afhankelijkheden kunnen de bewerking blokkeren. SQLite weigert een kolom te verwijderen die een primaire sleutel of refererende sleutel is, uniek of geïndexeerd is, of door een ander schemaobject wordt gebruikt. PostgreSQL kan afhankelijke objecten verwijderen met CASCADE, waaronder een view die de kolom gebruikt.
SQLite kan het type van een bestaande kolom niet wijzigen of primaire-sleutel-, uniekheids-, refererende-sleutel- of CHECK-regels aan bestaande kolommen toevoegen met een eenvoudige ALTER. Versie 3.53.0 voegt ALTER COLUMN ... SET NOT NULL en DROP NOT NULL toe, geen algemene bewerking van integriteitsregels. Een nieuw toegevoegde kolom kan een controle of toegestane verwijzing hebben, maar geen PRIMARY KEY of UNIQUE; als refererende sleutels zijn ingeschakeld, heeft een toegevoegde verwijzing een standaardwaarde NULL nodig.
Voor een uitgebreidere wijziging in SQLite:
- Leg vast welke indexen, triggers en views opnieuw moeten worden gemaakt. Schakel refererende sleutels vóór de transactie uit als ze aanstaan.
- Start een transactie en maak een nieuwe tabel met de gewenste regels.
- Kopieer rijen met expliciete kolommen in
INSERT INTO new_products (...) SELECT ... FROM products;. - Verwijder de oude tabel en hernoem de nieuwe naar
products. - Maak afhankelijke objecten opnieuw en voer
PRAGMA foreign_key_check;uit. Los eventuele gemelde problemen op voordat je vastlegt. - Leg vast en herstel daarna de handhaving van refererende sleutels als die eerder aanstond.
MySQL wijzigt definities met MODIFY COLUMN; SQL Server gebruikt ALTER COLUMN. Zet een structuurwijziging vóór uitvoering om naar de syntaxis die de doeldatabase ondersteunt.
Belangrijkste punten
- ALTER TABLE wijzigt de structuur; UPDATE wijzigt opgeslagen waarden.
- Toegevoegde kolommen geven bestaande rijen een standaardwaarde of NULL.
- Vul een nieuwe verplichte kolom voordat je NOT NULL toevoegt.
- Een kolom verwijderen wist de waarden en kan worden geblokkeerd door afhankelijkheden.
- SQLite heeft voor veel wijzigingen van typen en integriteitsregels een heropbouw nodig.
- Bij heropbouw moet je afhankelijke objecten behouden en refererende sleutels controleren.
6.2 Verwijder tabellen met DROP TABLE
DROP TABLE verwijdert zowel de tabel als de inhoud. Na DROP TABLE archived_orders; kunnen query's die tabel niet meer lezen omdat ze niet meer bestaat. De integriteitsregels, indexen en triggers worden mee verwijderd.
Kies het niveau van verwijdering
| Bedoeld resultaat | Instructie |
|---|---|
| De tabel behouden en geselecteerde rijen verwijderen | DELETE FROM orders WHERE ...; |
| Een lege tabel behouden | DELETE FROM orders; |
| Een tabel snel leegmaken waar dat wordt ondersteund | TRUNCATE TABLE orders; |
| De tabel zelf verwijderen | DROP TABLE orders; |
DROP TABLE IF EXISTS archived_orders; voorkomt een fout als de tabel ontbreekt. Een bestaande tabel en de bijbehorende gegevens worden nog steeds verwijderd. Een installatiescript dat tabellen verwijdert en opnieuw maakt, wist gegevens als je het uitvoert op een database met records die je wilt behouden.
Houd rekening met koppelingen tussen tabellen
Verwijder kinderen vóór ouders, in omgekeerde volgorde van de gebruikelijke aanmaakvolgorde. In PostgreSQL mislukt het verwijderen van customers zolang een refererende sleutel van een order ervan afhankelijk is. DROP TABLE customers CASCADE; verwijdert ook de afhankelijke refererende sleutel en eventuele afhankelijke views. De ordertabel en de rijen blijven bestaan, maar de klantrelatie wordt niet meer gehandhaafd.
Deze PostgreSQL-CASCADE verschilt van ON DELETE CASCADE bij een refererende sleutel. De eerste verwijdert afhankelijke databaseobjecten tijdens een structuurwijziging. De tweede verwijdert kindrijen wanneer een ouderrij wordt verwijderd. Als je weet welke actie wordt gebruikt, voorkom je een verkeerde voorspelling over de resterende gegevens.
Als de handhaving van refererende sleutels in SQLite is ingeschakeld, voert het verwijderen van een tabel eerst een impliciete verwijdering van de rijen uit. Verwijzende kinderen kunnen dit blokkeren. Als de relatie ON DELETE CASCADE declareert, kunnen die kindrijen worden verwijderd; SET NULL kan hun koppelingen leegmaken. Bij het verwijderen van een tabel moet je dus even goed op verwijzingen letten als bij het verwijderen van rijen, en daarnaast op de tabelstructuur die wordt verwijderd.
Zorg dat herstel mogelijk blijft
Bewaar een bruikbare kopie voordat je een tabel met echte gegevens verwijdert of opnieuw opbouwt. Een snelle interne gegevenskopie is:
CREATE TABLE products_backup AS
SELECT * FROM products;
In SQLite en PostgreSQL blijven hiermee de geselecteerde gegevens bewaard, maar niet de oorspronkelijke integriteitsregels. Dit vormt geen volledige reconstructie van de tabeldefinitie. Een export of databaseback-up bewaart herstelgegevens buiten de tabel die wordt gewijzigd.
In SQLite en PostgreSQL kun je het verwijderen ook binnen een transactie testen:
BEGIN;
DROP TABLE archived_orders;
ROLLBACK;
De terugdraaiing herstelt de tabel en de rijen omdat de verwijdering niet was vastgelegd. Zodra de verwijdering is vastgelegd, kun je die niet meer terugdraaien door later ROLLBACK uit te voeren. In databases met impliciete DDL-vastleggingen biedt transactiesyntaxis rond de verwijdering deze herstelmogelijkheid niet. Bekijk de doeldatabase en de betrokken tabellen voordat je een heropbouwscript uitvoert.
Belangrijkste punten
- DROP TABLE verwijdert de tabel en de rijen, integriteitsregels, indexen en triggers.
- IF EXISTS onderdrukt een fout bij afwezigheid, maar verwijdert een bestaande tabel nog steeds.
- Verwijder kindtabellen vóór hun oudertabellen.
- PostgreSQL DROP CASCADE verwijdert afhankelijke objecten, terwijl kindtabellen kunnen blijven bestaan.
- Een kopie met alleen gegevens bewaart de oorspronkelijke integriteitsregels niet.
SQL CREATE TABLE: voorbeelden
1Maak en bekijk een producttabel
11 stappen
- 1IntroductieBegin met één product
Een winkel moet de identificatiewaarde, naam, prijs en voorraad van een product vastleggen. Een tabeldefinitie geeft elk gegeven een eigen veld voordat er productrijen worden toegevoegd.
We maken de structuur, bekijken die en controleren vervolgens of de typen behouden wat de waarden betekenen. De voorbeelden gebruiken SQLite en noemen de wijzigingen voor PostgreSQL waar die het resultaat beïnvloeden.
- 2UitlegLees een kolomdefinitie
In
name TEXT NOT NULLisnamede identificator van het veld, beschrijftTEXTde opslag en vereistNOT NULLeen waarde.De tabel vermeldt deze definities tussen haakjes, gescheiden door komma's. De puntkomma beëindigt de aanmaakinstructie. De structuur maken is DDL; er worden geen productrijen toegevoegd. Een latere
INSERTlevert die rijen. - 3VoorbeeldMaak vier velden
CREATE TABLE products ( id INTEGER PRIMARY KEY, name TEXT NOT NULL, price NUMERIC(8, 2) NOT NULL, in_stock INTEGER DEFAULT 0 );Er zijn vier kolomdefinities en drie scheidende komma's. SQLite genereert deze primaire sleutel met een geheel getal. PostgreSQL heeft een identiteitsdeclaratie nodig als een weggelaten identificatiewaarde moet worden gegenereerd.
- 4TipBekijk de daadwerkelijke definitie
Gebruik
PRAGMA table_info(products);in SQLite-SQL of.schema productsin de opdrachtregelshell. Gebruik in psql van PostgreSQL\d products.Door de definitie te bekijken ontdek je meer dan syntaxisfouten. SQLite kan een ontbrekende komma lezen als onderdeel van een typenaam met meerdere woorden, zodat één kolom overblijft waar je er twee verwachtte.
SELECT * FROM products;toont een lege tabel, maar de nul rijen bevestigen niet elke regel. - 5UitdagingHerstelt dit een oude tabel?
Een oudere tabel
productsheeft alleenidenname. Een script voertCREATE TABLE IF NOT EXISTS products (...)uit met vier gewenste kolommen. Hoeveel kolommen heeft de bestaande tabel daarna?---reveal---
Nog steeds twee.
IF NOT EXISTSslaat het aanmaken over als de naam bestaat. Het vergelijkt de definities niet en voegt de ontbrekende velden niet toe. Een structuurwijziging vereistALTER TABLEof een doelbewuste heropbouw. - 6UitlegMaak onderscheid tussen hoeveelheden en codes
Sla hoeveelheden op als getallen zodat rekenen en numeriek sorteren werken. Sla codes op als tekst wanneer hun tekens betekenis hebben.
De Amerikaanse postcode
'02139'verliest als geheel getal de voorloopnul. De tekstwaarden'100','25'en'9'worden in die tekenvolgorde gesorteerd, wat onjuist is voor numerieke hoeveelheden. De keuze volgt uit hoe het veld wordt gebruikt, niet uit de vraag of de voorbeelden cijfers bevatten. - 7VoorbeeldLees precisie en schaal
PostgreSQL-
NUMERIC(8, 2)staat in totaal acht cijfers toe, waarvan twee na de komma. Dat laat er zes vóór de komma over, tot 999.999,99.Een waarde van 12,345 wordt opgeslagen als 12,35. Een waarde van 1.234.567,00 mislukt omdat die zeven cijfers vóór de komma nodig heeft. SQLite accepteert dezelfde declaratie maar dwingt deze precisie of schaal niet af, dus die voorspelling geldt niet voor SQLite.
- 8KernpuntHoud exacte geldbedragen exact
Binaire drijvendekommagetallen kunnen kleine verschillen in decimale berekeningen veroorzaken.
SELECT 0.1 + 0.2 = 0.3;van SQLite geeft onwaar terug.Gebruik PostgreSQL-
NUMERICvoor exacte decimale bedragen. Sla in SQLite gehele centen op als gehele getallen: 1999 staat voor 19,99.NUMERIC(8, 2)schrijven in SQLite levert geen exacte decimale opslag met een vaste schaal op. Benaderende typen zijn wel geschikt voor metingen zoals temperaturen. - 9UitdagingHoud datums op volgorde
Een SQLite-tabel slaat datums op als tekst. Waarom helpt het om
'12/01/2025'en'03/15/2026'te veranderen in ISO-datums bij oplopend sorteren op datum?---reveal---
De ISO-vormen zijn
'2025-12-01'en'2026-03-15'. De tekstvergelijking controleert dan jaar, maand en dag in die volgorde, zodat de vroegste datum eerst komt. Tekst met de maand eerst vergelijkt de maand voordat het jaar aan bod komt en zet deze twee in de verkeerde datumvolgorde. - 10UitdagingControleer de tabel en het type
Een SQLite-script maakt een ontbrekende tabel met
CREATE TABLE IF NOT EXISTS readings (qty INTEGER);. Een invoeging geeft'abc'op als qty en slaagt. Wat moet je controleren voordat je aanneemt dat qty altijd getallen bevat?---reveal---
Bekijk de daadwerkelijke definitie, omdat
IF NOT EXISTSeen oudere tabel kan hebben overgeslagen. Houd ook rekening met gewone SQLite-affiniteit: een declaratie voor gehele getallen kan nog steeds niet-numerieke tekst opslaan. Een geschikteSTRICT-tabel maakt de typehandhaving strenger. - 11SamenvattingStem de structuur af op het gebruik
Een aanmaakinstructie definieert velden, typen en regels; een invoeging levert de records. Bekijk de bestaande structuur in plaats van aan te nemen dat een geslaagd script de bedoelde definitie heeft gemaakt.
Vraag je voor elk veld af wat behouden moet blijven: numerieke berekeningen, exacte centen, tekens van identificatoren of chronologische volgorde. Houd rekening met het typegedrag van de doeldatabase wanneer je het opgeslagen resultaat voorspelt.
2Bescherm producten en klantkoppelingen
13 stappen
Sla deze les op om elke Walkthrough stap voor stap te volgen.
- 1IntroductieControleer gegevens bij de database
- 2UitlegGeef elke regel één taak
- 3VoorbeeldVolg één geaccepteerde rij
- 4UitdagingLost een standaardwaarde een expliciete NULL op?
- 5KernpuntEen onbekend controleresultaat wordt geaccepteerd
- 6UitlegIdentificeer de hele rij
- 7VoorbeeldLaat het systeem de identificatiewaarde kiezen
- 8UitdagingIs de volgende identificatiewaarde een aantal rijen?
- 9UitlegZorg dat elke order zijn klant vindt
- 10VoorbeeldVolg een cascadering
- 11UitdagingBehoud de orders na verwijdering
- 12UitdagingCombineer de vereiste regels
- 13SamenvattingControleer waarden, identiteit en koppelingen
3Voeg producten in en kopieer orders
11 stappen
Sla deze les op om elke Walkthrough stap voor stap te volgen.
- 1IntroductieKies waar nieuwe rijen vandaan komen
- 2VoorbeeldKoppel de waarden van één product
- 3TipHoud literals intact
- 4UitdagingLees de expliciete lijst
- 5UitlegVoeg een groep toe als één instructie
- 6VoorbeeldBekijk de archiefquery vooraf
- 7VoorbeeldGebruik de query als invoer
- 8UitlegBenoem de voorgestelde rij
- 9UitdagingBehouden of vervangen?
- 10UitdagingKopieer en koppel zonder te raden
- 11SamenvattingVolg de invoer tijdens het schrijven
4Wijzig precies de bedoelde rijen
14 stappen
Sla deze les op om elke Walkthrough stap voor stap te volgen.
- 1IntroductieMaak onderscheid tussen wat verandert en welke rijen veranderen
- 2VoorbeeldWijs twee nieuwe waarden toe
- 3VoorbeeldVerhoog een prijs op basis van de oude waarde
- 4UitdagingVeranderen de andere prijzen?
- 5UitlegVerwijder een rij of maak een veld leeg
- 6VoorbeeldVolg de oude geannuleerde orders
- 7UitdagingBewaar de geschiedenis van een verwijderde klant
- 8TipGebruik de vooraf bekeken voorwaarde opnieuw
- 9VoorbeeldPas AND vóór OR toe
- 10UitdagingPas één datumregel toe op beide statussen
- 11KernpuntEen negatieve vergelijking mist NULL
- 12UitdagingGebruik een lijst met klantsleutels
- 13UitdagingBekijk een wijziging van alle rijen
- 14SamenvattingControleer betekenis en effect
5Leg een volledige wijziging vast of draai haar terug
12 stappen
Sla deze les op om elke Walkthrough stap voor stap te volgen.
- 1IntroductieEén overboeking vereist twee wijzigingen
- 2UitlegOpen een gezamenlijke transactie
- 3VoorbeeldTrek het over te boeken bedrag af
- 4VoorbeeldTel de bijschrijving op en controleer die
- 5UitdagingDraai de hele nog niet vastgelegde overboeking terug
- 6VoorbeeldVolg een mislukte saldowijziging
- 7UitlegHerstel op de manier die bij de database past
- 8UitdagingVoorkom dat je een onvolledige bewerking vastlegt
- 9VoorbeeldMarkeer een tussenliggend punt
- 10KernpuntEen savepoint vrijgeven legt de buitenste transactie niet vast
- 11UitdagingKan deze verwijdering worden teruggedraaid?
- 12SamenvattingEindig met een bewuste beslissing
6Wijzig of verwijder een gevulde tabel
13 stappen
Sla deze les op om elke Walkthrough stap voor stap te volgen.
- 1IntroductieWerk met bestaande records
- 2VoorbeeldVoeg een veld toe dat NULL toestaat
- 3UitdagingMaak een veld verplicht nadat je het hebt gevuld
- 4TipPas elk extern gebruik van de naam aan
- 5UitlegHerken de beperkingen van ALTER
- 6VoorbeeldBereid de vervanging voor
- 7VoorbeeldKopieer, vervang en controleer
- 8UitlegBepaal of de tabel moet blijven bestaan
- 9VoorbeeldVolg PostgreSQL-afhankelijkheden
- 10UitdagingMaak onderscheid tussen de twee betekenissen van cascadering
- 11TipHoud gegevens en definitie herstelbaar
- 12UitdagingBehoud regels tijdens een heropbouw
- 13SamenvattingVolg de structuur en de afhankelijkheden
SQL CREATE TABLE: oefenvragen
Set 1: Herken veelvoorkomende SQL-fouten10 Oefenvragen
Vraag 1 van 10
labels heeft al alleen de kolommen id en text. Een script voert CREATE TABLE IF NOT EXISTS labels (id INTEGER PRIMARY KEY, text TEXT, color TEXT); uit. Wat gebeurt er met color?Toon antwoordVerberg antwoord
Vraag 2 van 10
CREATE TABLE tickets (id INTEGER PRIMARY KEY, label TEXT); uit. Er worden geen andere instructies uitgevoerd. Wat bestaat er daarna?Toon antwoordVerberg antwoord
Vraag 3 van 10
CHECK (score BETWEEN 0 AND 100). Een invoeging geeft NULL op. Wat gebeurt er?Toon antwoordVerberg antwoord
NOT NULL moet een ontbrekende score afzonderlijk verbieden. De bereikcontrole kiest geen grenspunt en levert geen vervangende waarde als de invoer onbekend is.Vraag 4 van 10
ON DELETE SET NULL en project_id is ook NOT NULL. Refererende sleutels worden gehandhaafd. Wat gebeurt er als het project wordt verwijderd?Toon antwoordVerberg antwoord
NULL zetten, wat hun NOT NULL-regel schendt. De verwijdering mislukt daarom en laat geen gedeeltelijk ontkoppeld resultaat achter. SET NULL behoudt kindrijen alleen als het leegmaken van hun koppelingen volgens de rest van de definitie is toegestaan.Vraag 5 van 10
Toon antwoordVerberg antwoord
excluded.qty van de voorgestelde rij. Als je die bij de opgeslagen 7 optelt, krijg je 18 en behandel je de invoer als een levering. De bestaande waarde behouden zou de nieuwe stand volledig negeren.Vraag 6 van 10
Toon antwoordVerberg antwoord
IS NULL-tak nodig hebben. Door die takken met OR te combineren, neem je beide groepen mee. IS NULL vervangen door een gelijkheidsvergelijking werkt niet, omdat gelijkheid met NULL nooit waar is.Vraag 7 van 10
Toon antwoordVerberg antwoord
SET-clausule, zoals in SET color = 'blue', qty = 6. AND combineert voorwaarden en kan onderdeel worden van één expressie in plaats van het tweede veld toe te wijzen. Die fout kan in SQLite worden uitgevoerd met een onbedoelde Booleaanse waarde.Vraag 8 van 10
CHECK (balance >= 0). Wat zou COMMIT bij de gewone afhandeling van integriteitsregels vastleggen?Toon antwoordVerberg antwoord
Vraag 9 van 10
active INTEGER NOT NULL DEFAULT 1. Welke active-waarde hebben de bestaande rijen?Toon antwoordVerberg antwoord
Vraag 10 van 10
Toon antwoordVerberg antwoord
Set 2: Maak tabellen en voer eerste wijzigingen uit10 Oefenvragen
Sla deze les op om elk antwoord te zien en elke set te oefenen.
Vraag 1 van 10
00481 exact behouden. Welk opslagtype past?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 2 van 10
NUMERIC(6, 2). Wat is de grootste positieve waarde?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 3 van 10
qty INTEGER NOT NULL DEFAULT 4 CHECK (qty >= 0). Een invoeging geeft expliciet NULL op voor qty. Wat gebeurt er?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 4 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 5 van 10
supplier_id = 18, maar leverancier 18 bestaat niet. Wat moet je doen om diezelfde verwijzing zonder NULL met succes in te voegen?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 6 van 10
(code, name) met de waarden ('R7', 'Notebook'). Wat wordt opgeslagen in name?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 7 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 8 van 10
DELETE FROM logs; slaagt. Wat blijft over?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 9 van 10
BEGIN uit, wijzigt een hoeveelheid van 8 naar 11 en voert daarna ROLLBACK uit. Welke hoeveelheid leest die verbinding daarna?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 10 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Set 3: Volg de opgeslagen resultaten10 Oefenvragen
Sla deze les op om elk antwoord te zien en elke set te oefenen.
Vraag 1 van 10
NUMERIC(5, 2). Wat gebeurt er met een ingevoegde waarde van 48,726?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 2 van 10
UNIQUE (room_id, start_time). Ze bevat (4, '09:00') en (5, '09:00'). Wat gebeurt er als (4, '10:00') wordt ingevoegd?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 3 van 10
code TEXT PRIMARY KEY. Welke extra regel sluit de historische SQLite-uitzondering voor ontbrekende sleutels uit?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 4 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 5 van 10
qty INTEGER NOT NULL DEFAULT 6. Welke invoeging voegt een borstel toe met die standaardwaarde?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 6 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 7 van 10
state = 'closed' OR state = 'expired' AND opened < '2026-01-01'?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 8 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 9 van 10
ROLLBACK TO s uit en legt vast. Wat blijft over?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 10 van 10
DROP TABLE clients CASCADE; slaagt. Wat kan van invoices blijven bestaan?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Set 4: Kies een betrouwbare volgorde10 Oefenvragen
Sla deze les op om elk antwoord te zien en elke set te oefenen.
Vraag 1 van 10
CREATE TABLE t (a INTEGER b TEXT);. Bij controle blijkt er alleen een kolom a te zijn. Waarom?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 2 van 10
COUNT(*) terug?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 3 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 4 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 5 van 10
ON CONFLICT (code) DO UPDATE SET qty = stock.qty + excluded.qty. Daarna wordt dezelfde instructie opnieuw uitgevoerd. Welke qty wordt opgeslagen?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 6 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 7 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 8 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 9 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 10 van 10
CREATE TABLE saved AS SELECT * FROM original;. Wat moet je controleren voordat je saved als volledige vervanging behandelt?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Set 5: Pas de regels toe op gecombineerde wijzigingen10 Oefenvragen
Sla deze les op om elk antwoord te zien en elke set te oefenen.
Vraag 1 van 10
value NUMERIC(7, 2). Het invoegen van 6,789 slaagt. Welke opgeslagen waarde mag je op basis van alleen deze declaratie verwachten?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 2 van 10
label TEXT NOT NULL zonder andere regels. Wat gebeurt er wanneer de opgegeven waarde de lege tekenreeks is?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 3 van 10
parent_id INTEGER DEFAULT 90 REFERENCES parents(id) ON DELETE SET DEFAULT. Ouder 90 bestaat niet. Kind 12 verwijst naar ouder 7. Wat gebeurt er als ouder 7 wordt verwijderd?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 4 van 10
DO UPDATE SET qty = excluded.qty uit. Welke hoeveelheid wordt na beide imports opgeslagen en welk totaal zou correct optellen hebben opgeleverd?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 5 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 6 van 10
customer_id = (SELECT id FROM customers WHERE eligible = TRUE). Wat gebeurt er en welke vergelijking lost dit op?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 7 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 8 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 9 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 10 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Kom je niet uit je eigen opgave? Huiswerkhulp
Kernbegrippen
A
Aantal getroffen rijen
ADD COLUMN
active INTEGER NOT NULL DEFAULT 1 toevoegen geeft bestaande klanten de nieuwe waarde 1 zonder afzonderlijke invoegingen.Afhankelijkheid
ALTER TABLE
ALTER TABLE; telefoonwaarden later invullen gebruikt UPDATE.Atomiciteit
Autocommit
AUTOINCREMENT
B
Benoemde integriteitsregel
CONSTRAINT price_positive CHECK (price > 0) geeft de regel voor een positieve prijs een naam voor later onderhoud.C
CHECK
CHECK (price > 0) weigert een negatieve prijs, maar heeft ook NOT NULL nodig wanneer een prijs moet worden opgegeven.COMMIT
CREATE TABLE
CREATE TABLE labels (id INTEGER PRIMARY KEY, name TEXT); maakt een tabel klaar voordat labels worden ingevoegd.CREATE TABLE AS
cheap_products bevat de producten die bij het maken zijn geselecteerd, ook nadat de bronprijzen veranderen.D
DEFAULT
DEFAULT 0 weglaten geeft nul, terwijl expliciet NULL opgeven de waarde ontbrekend laat.DELETE
Drijvendekommaweergave
0.1 + 0.2 = 0.3 als onwaar evalueren omdat de decimale literals bij benadering worden opgeslagen.DROP CASCADE
DROP COLUMN
DROP TABLE
E
excluded
stock.qty + excluded.qty de voorgestelde binnenkomende hoeveelheid op bij de al opgeslagen hoeveelheid.G
Gegevensdefinitietaal
CREATE TABLE, ALTER TABLE en DROP TABLE wijzigen de structuur van de database in verschillende fasen.Gegevensmanipulatietaal
INSERT; de status corrigeren gebruikt UPDATE; de rij verwijderen gebruikt DELETE.Gegevenstype
H
Handhaving van refererende sleutels
PRAGMA foreign_keys = ON; op de verbinding nodig vóór een transactie om de gedeclareerde koppelingen te controleren.Heropbouw van een tabel
I
Identificator
"order date" heeft aanhalingstekens nodig, terwijl order_date geen spaties bevat en gemakkelijker opnieuw te gebruiken is.Identiteitskolom
INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY levert nieuwe identificatiewaarden zonder handmatig nummer in elke invoeging.IF EXISTS
DROP TABLE IF EXISTS archived_orders; slaagt wanneer de tabel ontbreekt en verwijdert haar wanneer ze bestaat.Impliciete commit
IN
INSERT
INSERT SELECT
INTEGER
Integriteitsregel (constraint)
Invoeging van meerdere rijen
IS NULL
WHERE phone IS NULL vindt klanten zonder telefoonnummer; WHERE phone = NULL vindt geen van die rijen.ISO-datum
'2026-03-15' sorteren op jaar, maand en dag wanneer ze allemaal dezelfde notatie gebruiken.K
Kindtabel
Kolommenlijst
(sku, name, price) te vermelden, wordt de eerste opgegeven waarde een SKU, ook als price eerder in de tabel is gedeclareerd.L
Logische verwijdering (soft delete)
deleted_at van een klant in te stellen blijft de rij behouden, dus voegen query's voor actieve klanten deleted_at IS NULL toe.M
Mislukte transactie
N
Natuurlijke sleutel
NOT NULL
NULL
NULL wanneer geen telefoonnummer bekend is; IS NULL vindt die klanten.NUMERIC-precisie
NUMERIC(8, 2) staat zes cijfers vóór de decimale komma en twee erna toe, tot 999.999,99.O
ON DELETE CASCADE
ON DELETE SET NULL
Operatorprioriteit
Oudertabel
P
Primaire sleutel
R
Refererende sleutel
RELEASE
RETURNING
ROLLBACK
ROLLBACK TO
after_first, gezet tussen twee saldoverhogingen, maakt de latere verhoging ongedaan, maar behoudt de eerdere als nog niet vastgelegde wijziging.ROUND
ROUND(price * 1.10, 2) vraagt om een resultaat met twee decimalen voor een SQLite-prijsberekening die 21,989 zou opleveren.S
Samengestelde sleutel
Savepoint
Schaal
NUMERIC(8, 2)-kolom slaat 12,345 op als 12,35 omdat de gedeclareerde schaal twee is.SET-toewijzing
SET in_stock = in_stock - 1 verlaagt het opgeslagen aantal, terwijl SET in_stock = 1 het vervangt door één.Stagingtabel
NULLIF(TRIM(email), '') in NULL veranderen.Subquery
order_id IN (SELECT id FROM orders WHERE status = 'cancelled') gebruiken om gerelateerde orderregels te kiezen.Surrogaatsleutel
T
Tekstliteral
'O''Brien' slaat de naam “O'Brien” op met één apostrof in plaats van de waarde voortijdig te beëindigen.Transactie
TRUNCATE
TRUNCATE TABLE, maar de regels voor afhankelijkheden en transacties blijven van belang.Typeaffiniteit
'5' om naar 5, maar kan 'abc' zonder fout als tekst behouden.U
UNIQUE
UNIQUE (order_id, product_id) staat hetzelfde product in verschillende orders toe, maar weigert een herhaald paar.UPDATE
UPDATE products SET price = 22.50 WHERE id = 3; wijzigt één product zonder een nieuwe productrij in te voegen.Upsert
ON CONFLICT (sku) DO UPDATE de voorraadstand bijwerken als de SKU bestaat.W
WHERE-voorwaarde
- 1Relationele databases
- 2SQL SELECT
- 3SQL CASE en functies
- 4SQL GROUP BY
- 5SQL-joins
- 6SQL CREATE TABLE
Over deze les
Door StudeliFout melden
Maak je eigen Studiemateriaal
Maak van je aantekeningen, slides en documenten Leermodules, Oefenvragen, Flashcards en 6 andere tools.