sql >> Databasteknik >  >> RDS >> Sqlserver

SQL Server DELETE – Ta bort en eller flera rader från en tabell med något avancerade scenarier

Den aktuella artikeln fokuserar på något avancerad användning av DELETE-satsen för att ta bort en eller flera poster (rader) från en tabell. Även om det främst riktar sig till nybörjare, kan dess tips vara till hjälp för alla databasspecialister.

Förutsättningar:DELETE-satsen Grundläggande scenarier

Om du inte redan är bekant med de grundläggande användningarna av Delete-satsen rekommenderar vi att du läser den tidigare artikeln SQL Server DELETE – Ta bort en eller flera rader från en tabell. Den artikeln fokuserar på följande aspekter:

  1. Sätta upp en exempeldatabas.
  2. Kör SQL-skript mot exempeldatabasen.
  3. Skapa en tabell i en exempeldatabas och infoga data i den.
  4. Ta bort alla rader från en tabell.
  5. Ta bort en eller flera rader från en tabell baserat på ett villkor.
  6. Ta bort en eller flera rader från en tabell baserat på flera villkor.

Dessa data är avgörande att förstå innan vi går till den något avancerade användningen av Delete-satsen, så läs artikeln om du inte har den nödvändiga bakgrunden hittills.

Lätt avancerade scenarier för DELETE-satsen

Som med alla andra genomgångar måste vi först skapa en exempeldatabas för att testa att köra våra skript mot den på ett säkert sätt.

Ett tips om exempeldatabasinställningen

Jag rekommenderar starkt att du installerar SQL Server Developer Edition på din maskin lokalt först. Det är bättre för inlärnings- och teständamål.

Ladda ner SQL Server Developer Edition

Konfigurera en exempeldatabas (WatchesDelSample)

Vi kommer att skapa en databas som heter WatchesDelSample. Denna databas innehåller följande tre tabeller:

  1. Titta.
  2. Färg.
  3. WatchType.

Watch-bordet är det viktigaste. Den innehåller klockans namn, färg och typ. Informationen om både typ och färg kommer från de två referenstabellerna Färg och WatchType ansluten via främmande nycklar.

Ställ in exempeldatabasen med följande skript:

-- 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

Snabb datakontroll

Låt oss se alla rader i Klockan tabell. För det, kör följande skript:

-- View the watch table data (rows)
SELECT w.WatchId
      ,w.Name
      ,w.WatchTypeId
      ,w.ColorId
      ,w.Price FROM dbo.Watch w

Utgången är som följer:

Observera att jag använder dbForge Studio för SQL Server för denna demo. Du kan dock använda SQL Server Management Studio (SSMS) för att köra samma skript – resultaten blir desamma.

Förstå ID:n (koderna) bakom typ- och färgkolumnerna

Som du kan se finns det några ID:n under följande kolumner i Watch-tabellen:

  1. WatchTypeId
  2. ColorId

Dessa kolumner får värden från referenstabellerna där de ursprungligen definierades. Watch-tabellen ansluter till dessa referenstabeller via främmande nyckelbegränsningar.

Tre problem uppstår med ovanstående utdata:

  1. Vi kan se WatchTypeId och ColorId men förstår inte vad de är.
  2. Om vi ​​förstår vad dessa id betyder måste vi gå tillbaka till deras ursprungliga tabeller hela tiden för att kontrollera.
  3. Det viktigaste av allt, varför behöver vi få färg och typ från andra tabeller?

Det finns en anledning till att vi definierade Color (ColorId) och Type (WatchTypeId) i andra tabeller. Vi måste se till att dessa värden förblir konsekventa.

Om vi ​​inte ursprungligen definierade värdet i referenstabellerna, kunde vi ha blandat orden för att representera färgen eller typen. Till exempel kan det finnas både Blå och Blues , eller Analog och Analog . För att undvika ett sådant problem standardiserar vi färger och typer i referenstabeller. Sedan skickar vi vidare deras koder till huvudbordet.

Genom att sammanfoga Watch-tabellen med andra referenstabeller kan vi hämta värdena bakom dessa koder. Det är en vanlig praxis vid databasutveckling.

Visa Watch-tabellen med typ- och färgvärden bakom ID:n

Vi kan se den faktiska innebörden av koderna bakom Färg och Typ genom att köra följande skript:

-- 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 är följande:

Förstå databasarkitekturen

Vi behöver mer information om arkitekturen för denna databas. Vårt fokus ligger på hur tabeller länkar till varandra.

Bilden ovan visar scenariot för referenstabellerna som hjälper huvudtabellen att ta emot konsekventa data. Det är inte ett enkelt scenario, särskilt för nybörjare, även om det är vanligt i många databaser.

Vi studerar den här arkitekturen eftersom vi behöver förstå hur man tar bort en eller flera rader från någon av ovanstående tabeller när de är länkade så här.

Ta bort en rad från referenstabellen (färg)

Kan vi ta bort en rad från referenstabellen eller inte? Låt oss ta reda på svaret.

Vi tar bort den första raden från färgtabellen:

-- Deleting one row with color id 1 from the reference table color 
DELETE FROM Color
WHERE ColorId = 1

Resultatet är följande:

Felet betyder att det inte är tillåtet att radera den raden vi ville ha.

Med andra ord kan vi inte ta bort en rad från en tabell som refereras av en annan tabell.

Länkade rader vs Olänkade rader

Låt oss dela upp raderna i en referenstabell i följande två kategorier:

  1. Länkade rader.
  2. Olänkade rader.

En länkad rad är en rad i en referenstabell som används av en annan tabell. En olänkad rad är en rad i en referenstabell som en annan tabell inte tilltalar.

Vi kan ta bort olänkade rader (poster) i en referenstabell direkt.

Vårt tidigare försök att ta bort en rad från färgtabellen misslyckades eftersom det där ColorId (1) användes av huvudbevakningstabellen.

Visa referenstabellen (färg)

Låt oss se referenstabellen enligt följande:

-- View reference table Color
SELECT c.ColorId
      ,c.Name
      ,c.Detail FROM dbo.Color c

Resultatuppsättningen är nedan:

Från de tidigare utgångarna vet vi att färgen Blue (ColorId:3) inte används av Watch-bordet eftersom det inte finns någon blå klocka lagrad i tabellen ännu.

Ta bort en olänkad rad från referenstabellen (färg)

Kör följande skript:

-- Deleting unlinked row with color id 3 from reference table Color
DELETE FROM Color
WHERE ColorId = 3 -- blue color

Vi har raderat raden och vi kan bekräfta det genom att titta på tabellen:

--View reference table Color after deleting the unlinked row
SELECT c.ColorId
      ,c.Name
      ,c.Detail FROM dbo.Color c

Resultatuppsättningen är nedan:

Det visar att raden som innehåller den blå färgen har tagits bort från tabellen.

Ett tips om att ta bort data från referenstabellen

Kom ihåg att du inte kan ta bort en post (rad) från en referenstabell om den används av en annan tabell eller grupp av tabeller. Du kan dock ta bort en post från samma (referens)tabell om den inte används.

Ta bort en länkad rad från referenstabellen (färg)

Vad händer om vi vill ta bort en rad från en referenstabell med vetskap om att den skickar referensdata som färger till en annan tabell? Med andra ord, hur tar vi bort en länkad rad från referenstabellen?

Först måste vi ta bort den raden från huvudtabellen där den refereras till.

Vi kan till exempel ta bort färgen Vit från färgtabellen enligt följande:

  1. Ta bort alla rader från huvudtabellen (Titta) där färgen är Vit (baserat på id).
  2. Ta bort raden från referensfärgtabellen där färgen är vit (baserat på id).

Låt oss nu undersöka det i praktiken.

Ta bort alla rader där färgen är vit från huvudtabellen (Titta på)

Vårt mål är att ta bort spåren av det vita färg från både referens- och huvudtabeller.

Låt oss ta en titt på data innan vi raderar dem. Vi vill kontrollera hur många rader från huvudtabellen som innehåller färg-id 2 (vit):

-- 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 är nedan:

Ta nu bort raderna med färg-id 2 genom att köra följande T-SQL-skript:

-- Deleting all the rows with color id 2 from main table Watch
DELETE FROM dbo.Watch
WHERE ColorId = 2 -- white color 

Utgången är som följer:

Visa huvudtabellen efter att ha tagit bort alla rader med den vita färgen

Vi måste kontrollera huvudtabellen för alla rader som innehåller färg-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 saknas rekorden för de vita färgklockorna. Det bevisar att vi har raderat alla dessa rader.

Ta bort en tidigare länkad rad från referenstabellen (Färg)

Efter att vi tagit bort de refererade raderna från huvudtabellen kan vi också ta bort den tidigare länkade raden från referenstabellen. Faktum är att den länken nu inte finns där längre.

Kör följande skript mot referensfärgtabellen för att ta bort raden med färg-id 2 (vit):

-- 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

Utgången är som följer:

Grattis!

Vi har lärt oss hur man tar bort en eller flera rader från en referenstabell. Vi kan göra det både om raden refereras och om inte. Vi har också undersökt borttagning av rader från huvudtabellen.

Ett tips om att radera all data

Det finns en annan T-SQL-sats som kallas Truncate Table – det är mer effektivt att ta bort all data från en tabell. Tabellen får dock inte refereras till någon annanstans eftersom du då måste radera data från huvudtabellen först. Det är samma sak som vi visade i den här artikeln tidigare. Sedan skulle vi tillämpa Truncate uttalande mot referenstabellen som ett sista steg.

Koden är följande:

-- Deleting all rows from the main table using Truncate 
  TRUNCATE TABLE dbo.Watch

Men precis som med Delete-satsen måste du vara mycket försiktig med Truncate , eller så tar du bort all data från en tabell.

Rådgivning

Radering av rader i realtidsscenarier hjälper oss för det mesta att antingen ta bort oönskad data (såsom pensionerade modeller) från huvuddatabasen eller att arkivera data och lagra den i en arkivdatabas.

Saker att göra

Nu när du kan ta bort en eller flera rader i något avancerade scenarier som länkade tabeller, prova följande saker för att förbättra dina färdigheter ytterligare:

  1. Ta bort den analoga klocktypen från referenstabellen WatchType baserat på ID.
  2. Ta bort alla rader från Färg referenstabell.
  3. Försök att återställa exempeldatabasen och se hur snabbt du kan radera all data från alla (referens- och huvudtabeller).

  1. Heroku Postgres Fel:PGError:ERROR:relationsorganisationer finns inte (ActiveRecord::StatementInvalid)

  2. CASE .. NÄR uttryck i Oracle SQL

  3. Hur man undviker variabelsubstitution i Oracle SQL Developer med "trinidad &tobago"

  4. Vilken är den perfekta verktygslådan för PL/SQL-utveckling?