Den aktuelle artikel fokuserer på lidt avanceret brug af DELETE-sætningen til at fjerne en eller flere poster (rækker) fra en tabel. Selvom den hovedsagelig henvender sig til begyndere, kan dens tips være til hjælp for alle databasespecialister.
Forudsætninger:DELETE-sætningen Grundlæggende scenarier
Hvis du ikke allerede er bekendt med de grundlæggende anvendelser af Slet-sætningen, anbefaler vi, at du gennemgår den tidligere artikel SQL Server DELETE – Fjernelse af en eller flere rækker fra en tabel. Denne artikel fokuserer på følgende aspekter:
- Opsætning af en eksempeldatabase.
- Kører SQL-scripts mod eksempeldatabasen.
- Oprettelse af en tabel i en eksempeldatabase og indsættelse af data i den.
- Sletning af alle rækker fra en tabel.
- Sletning af en eller flere rækker fra en tabel baseret på en betingelse.
- Sletning af en eller flere rækker fra en tabel baseret på flere betingelser.
Disse data er afgørende at forstå, før vi springer til den lidt avancerede brug af Slet-erklæringen, så læs artiklen, hvis du ikke har den nødvendige baggrund indtil videre.
Lidt avancerede scenarier for DELETE-sætningen
Som med enhver anden gennemgang skal vi først konfigurere en prøvedatabase for at teste at køre vores scripts sikkert mod den.
Et tip om eksempeldatabaseopsætningen
Jeg vil varmt anbefale at installere SQL Server Developer Edition på din maskine lokalt først. Det er bedre til lærings- og testformål.
SQL Server Developer edition download
Opsæt en prøvedatabase (WatchesDelSample)
Vi vil oprette en database kaldet WatchesDelSample. Denne database indeholder følgende tre tabeller:
- Se.
- Farve.
- WatchType.
Watch-bordet er det vigtigste. Det indeholder urets navn, farve og type. Oplysningerne om både type og farve kommer fra de to referencetabeller Farve og WatchType forbundet via fremmednøgler.
Konfigurer eksempeldatabasen med følgende script:
-- Create sample database WatchesDelSample
USE MASTER
GO
CREATE DATABASE WatchesDelSample
GO
USE WatchesDelSample
-- Creating a reference table WatchType
CREATE TABLE dbo.WatchType
(
WatchTypeId INT IDENTITY(1,1),
Name VARCHAR(50)NOT NULL,
Detail VARCHAR(200)NULL
CONSTRAINT PK_WatchType_WatchTypeId PRIMARY KEY (WatchTypeId)
)
GO
-- Populating (adding rows to the) table WatchType
SET IDENTITY_INSERT dbo.WatchType ON
GO
INSERT INTO dbo.WatchType
(
WatchTypeId
,Name
,Detail
)
VALUES
(
1 -- ID - INT Primary Key
,'Analogue' -- Name - varchar(50) NOT NULL
,'This is Analogue' -- Detail - varchar(200)
),
(
2 -- ID - INT Primary Key
,'Digital' -- Name - varchar(50) NOT NULL
,'This is Digital' -- Detail - varchar(200)
),
(
3 -- ID - INT Primary Key
,'Sports' -- Name - varchar(50) NOT NULL
,'This is Sports' -- Detail - varchar(200)
);
GO
SET IDENTITY_INSERT dbo.WatchType OFF
GO
-- Creating a reference table Color
CREATE TABLE dbo.Color
(
ColorId INT IDENTITY(1,1),
Name VARCHAR(50)NOT NULL,
Detail VARCHAR(200)NULL
CONSTRAINT PK_Color_ColorId PRIMARY KEY (ColorId)
)
GO
-- Populating (adding rows to the) table Color
SET IDENTITY_INSERT dbo.Color ON
GO
INSERT INTO dbo.Color
(
ColorId
,Name
,Detail
)
VALUES
(
1 -- ID - INT Primary Key
,'Black' -- Name - varchar(50) NOT NULL
,'This is Black' -- Detail - varchar(200)
),
(
2 -- ID - INT Primary Key
,'White' -- Name - varchar(50) NOT NULL
,'This is White' -- Detail - varchar(200)
),
(
3 -- ID - INT Primary Key
,'Blue' -- Name - varchar(50) NOT NULL
,'This is Blue' -- Detail - varchar(200)
);
GO
SET IDENTITY_INSERT dbo.Color OFF
GO
-- Creating a table Watch
CREATE TABLE dbo.Watch
(
WatchId INT IDENTITY(1,1),
Name VARCHAR(50),
WatchTypeId INT,
ColorId INT,
Price DECIMAL(5,2),
CONSTRAINT PK_Watch_WatchId PRIMARY KEY (WatchId)
)
GO
-- Creating foreign key constraint on Watch table to get WatchTypeId values from WatchType table
ALTER TABLE dbo.Watch
ADD CONSTRAINT [FK_Watch_WatchType_WatchTypeId]
FOREIGN KEY ([WatchTypeId]) REFERENCES dbo.[WatchType] ([WatchTypeId]);
-- Creating foreign key constraint on Watch table to get ColorId values from Color table
ALTER TABLE dbo.Watch
ADD CONSTRAINT [FK_Watch_Color_ColorId]
FOREIGN KEY ([ColorId]) REFERENCES dbo.[Color] ([ColorId]);
-- Populating (adding rows to the) table Watch getting some columns values from reference tables
SET IDENTITY_INSERT WatchesDelSample.dbo.Watch ON
GO
INSERT WatchesDelSample.dbo.Watch(WatchId, Name, WatchTypeId, ColorId, Price) VALUES (1, 'Casio', 1, 1, 100.00)
INSERT WatchesDelSample.dbo.Watch(WatchId, Name, WatchTypeId, ColorId, Price) VALUES (2, 'Timex', 2, 2, 70.00)
GO
SET IDENTITY_INSERT WatchesDelSample.dbo.Watch OFF
GO
Hurtigt datatjek
Lad os se alle rækkerne i Watch bord. Til det skal du køre følgende script:
-- View the watch table data (rows)
SELECT w.WatchId
,w.Name
,w.WatchTypeId
,w.ColorId
,w.Price FROM dbo.Watch w
Outputtet er som følger:
Bemærk, at jeg bruger dbForge Studio til SQL Server til denne demo. Du kan dog bruge SQL Server Management Studio (SSMS) til at køre de samme scripts – resultaterne vil være de samme.
Forstå ID'erne (koderne) bag type- og farvekolonnerne
Som du kan se, er der nogle ID'er under følgende kolonner i Watch-tabellen:
- WatchTypeId
- ColorId
Disse kolonner får værdier fra referencetabellerne, hvor de oprindeligt er defineret. Watch-tabellen forbinder til disse referencetabeller via fremmednøgle-begrænsninger.
Tre problemer opstår med ovenstående output:
- Vi kan se WatchTypeId og ColorId, men forstår ikke, hvad de er.
- Hvis vi forstår, hvad disse id'er betyder, skal vi hele tiden gå tilbage til deres oprindelige tabeller for at kontrollere.
- Vigtigst af alt, hvorfor skal vi hente Farve og Type fra andre tabeller?
Der er en grund til, at vi definerede Color (ColorId) og Type (WatchTypeId) i andre tabeller. Vi skal sikre, at disse værdier forbliver konsekvente.
Hvis vi ikke oprindeligt definerer værdien i referencetabellerne, kunne vi have blandet ordene for at repræsentere farven eller typen. For eksempel kan der være både Blå og Blues , eller Analog og Analog . For at undgå et sådant problem standardiserer vi farver og typer i referencetabeller. Så videregiver vi deres koder til hovedbordet.
Ved at forbinde Watch-tabellen med andre referencetabeller kan vi hente værdierne bag disse koder. Det er en almindelig praksis i databaseudvikling.
Visning af Watch-tabellen med Type- og Farveværdier bag ID'er
Vi kan se den faktiske betydning af koderne bag Farve og Type ved at udføre følgende script:
-- View the watch table data (rows)
SELECT w.WatchId
,w.Name
,wt.Name AS WatchType
,c.Name AS ColorName
,w.Price FROM dbo.Watch w
INNER JOIN dbo.Color c ON c.ColorId=w.ColorId
INNER JOIN dbo.WatchType wt ON w.WatchTypeId = wt.WatchTypeId
Resultatet er som følger:
Forstå databasearkitekturen
Vi har brug for mere information om arkitekturen af denne database. Vores fokus er på, hvordan tabeller linker til hinanden.
Ovenstående billede viser scenariet for referencetabellerne, der hjælper hovedtabellen med at modtage konsistente data. Det er ikke et simpelt scenario, især for begyndere, selvom det er almindeligt i mange databaser.
Vi studerer denne arkitektur, fordi vi skal forstå, hvordan man sletter en eller flere rækker fra en af ovenstående tabeller, når de er linket på denne måde.
Sletning af en række fra referencetabellen (farve)
Kan vi slette en række fra referencetabellen eller ej? Lad os finde ud af svaret.
Vi sletter den første række fra farvetabellen:
-- Deleting one row with color id 1 from the reference table color
DELETE FROM Color
WHERE ColorId = 1
Resultatet er som følger:
Fejlen betyder, at det ikke er tilladt at slette den række, vi ønskede.
Med andre ord kan vi ikke slette en række fra en tabel, der refereres til af en anden tabel.
Linkede rækker vs ikke-linkede rækker
Lad os opdele rækkerne i en referencetabel i følgende to kategorier:
- Linkede rækker.
- Ulinkede rækker.
En sammenkædet række er en række i en referencetabel, der bruges af en anden tabel. En ikke-linket række er en række i en referencetabel, som en anden tabel ikke appellerer til.
Vi kan slette ikke-linkede rækker (poster) af en referencetabel med det samme.
Vores tidligere forsøg på at slette en række fra Color-tabellen mislykkedes, fordi det ColorId (1) var i brug af den primære Watch-tabellen.
Se referencetabellen (farve)
Lad os se referencetabellen som følger:
-- View reference table Color
SELECT c.ColorId
,c.Name
,c.Detail FROM dbo.Color c
Resultatsættet er nedenfor:
Fra de tidligere output ved vi, at farven Blue (ColorId:3) ikke er i brug af Watch-bordet, da der endnu ikke er gemt noget blåt ur i tabellen.
Sletning af en ikke-linket række fra referencetabellen (farve)
Udfør følgende script:
-- Deleting unlinked row with color id 3 from reference table Color
DELETE FROM Color
WHERE ColorId = 3 -- blue color
Vi har slettet rækken, og vi kan bekræfte det ved at se tabellen:
--View reference table Color after deleting the unlinked row
SELECT c.ColorId
,c.Name
,c.Detail FROM dbo.Color c
Resultatsættet er nedenfor:
Det viser, at rækken, der indeholder den blå farve er blevet fjernet fra tabellen.
Et tip om fjernelse af data fra referencetabellen
Husk, at du ikke kan slette en post (række) fra en referencetabel, hvis den er i brug af en anden tabel eller gruppe af tabeller. Du kan dog slette en post fra den samme (reference) tabel, hvis den ikke er i brug.
Sletning af en linket række fra referencetabellen (farve)
Hvad hvis vi vil fjerne en række fra en referencetabel velvidende, at den sender referencedataene, såsom farver, til en anden tabel? Med andre ord, hvordan sletter vi en linket række fra referencetabellen?
Først skal vi slette den række fra hovedtabellen, hvor der henvises til den.
For eksempel kan vi slette farven Hvid fra farvetabellen som følger:
- Slet alle rækker fra hovedtabellen (Watch), hvor farven er hvid (baseret på id).
- Slet rækken fra referencefarvetabellen, hvor farven er hvid (baseret på id).
Lad os nu undersøge det i praksis.
Sletning af alle rækker, hvor farven er hvid, fra hovedtabellen (Watch)
Vores mål er at fjerne sporene af det hvide farve fra både reference- og hovedtabeller.
Lad os se på dataene, før du sletter dem. Vi vil kontrollere, hvor mange rækker fra hovedtabellen, der indeholder farve-id 2 (hvid):
-- View Watch table before deleting rows with white color (color id:2)
SELECT w.WatchId
,w.Name
,w.WatchTypeId
,w.ColorId
,w.Price FROM dbo.Watch w
WHERE w.ColorId=2 -- White Color
Resultatet er nedenfor:
Slet nu rækkerne med farve-id 2 ved at køre følgende T-SQL-script:
-- Deleting all the rows with color id 2 from main table Watch
DELETE FROM dbo.Watch
WHERE ColorId = 2 -- white color
Outputtet er som følger:
Se hovedtabellen efter at have fjernet alle rækker med den hvide farve
Vi skal tjekke hovedtabellen for rækker, der indeholder farve-id 2:
-- View the watch table data (rows)
SELECT w.WatchId
,w.Name
,wt.Name AS WatchType
,w.ColorId
,c.Name AS ColorName
,w.Price FROM dbo.Watch w
INNER JOIN dbo.Color c ON c.ColorId=w.ColorId
INNER JOIN dbo.WatchType wt ON w.WatchTypeId = wt.WatchTypeId
Som vi ser, mangler rekorderne for de hvide farveure. Det beviser, at vi har slettet alle disse rækker.
Sletning af en tidligere linket række fra referencetabellen (farve)
Efter at vi har fjernet de refererede rækker fra hovedtabellen, kan vi også fjerne den tidligere linkede række fra referencetabellen. Faktum er, at det link nu ikke er der længere.
Kør følgende script mod referencefarvetabellen for at slette rækken med farve-id 2 (hvid):
-- View reference table before removing color id 1 (white)
SELECT c.ColorId
,c.Name
,c.Detail FROM dbo.Color c
-- Deleting one row with color id 2 from the reference table color
DELETE FROM Color
WHERE ColorId = 2 -- White Color
-- View reference table after removing color id 1 (white)
SELECT c.ColorId
,c.Name
,c.Detail FROM dbo.Color c
Outputtet er som følger:
Tillykke!
Vi har lært, hvordan man fjerner en eller flere rækker fra en referencetabel. Vi kan gøre det både, hvis rækken bliver refereret, og hvis ikke. Vi har også undersøgt sletning af rækker fra hovedtabellen.
Et tip om sletning af alle data
Der er en anden T-SQL-sætning kendt som Truncate Table – det er mere effektivt at fjerne alle data fra en tabel. Tabellen må dog ikke henvises andre steder, for så skal du først slette dataene fra hovedtabellen. Det er det samme, som vi demonstrerede i denne artikel tidligere. Derefter vil vi anvende Truncate sætning mod referencetabellen som et sidste trin.
Koden er som følger:
-- Deleting all rows from the main table using Truncate
TRUNCATE TABLE dbo.Watch
Men ligesom med Slet-erklæringen skal du være meget forsigtig med Truncate , eller du ender med at slette alle data fra en tabel.
Ord af råd
Sletning af rækker i realtidsscenarier hjælper os for det meste med enten at fjerne uønskede data (såsom pensionerede modeller) fra hoveddatabasen eller til at arkivere data og gemme dem i en arkivdatabase.
Ting at gøre
Nu hvor du kan slette en eller flere rækker i lidt avancerede scenarier, såsom linkede tabeller, kan du prøve følgende ting for at forbedre dine færdigheder yderligere:
- Slet den analoge urtype fra referencetabellen WatchType baseret på ID'et.
- Slet alle rækker fra Farve referencetabel.
- Prøv at nulstille eksempeldatabasen, og se, hvor hurtigt du kan slette alle data fra alle (reference- og hoved)tabeller.