I relationsdatabaser skapar vi tabeller för att lagra data i olika format. SQL Server lagrar data i ett rad- och kolumnformat som innehåller ett värde som är associerat med varje datatyp. När vi designar SQL-tabeller definierar vi datatyper som heltal, float, decimal, varchar och bit. Till exempel kan en tabell som lagrar kunddata ha fält som kundnamn, e-postadress, adress, stat, land och så vidare. Olika SQL-kommandon utförs på en SQL-tabell och kan delas in i följande kategorier:
- Data Definition Language (DDL): Dessa kommandon används för att skapa och modifiera databasobjekten i en databas.
- Skapa: Skapar objekt
- Ändra: Modifierar objekt
- Släpp: Tar bort objekt
- Trunkera: Tar bort all data från en tabell
- Data Manipulation Language (DML): Dessa kommandon infogar, hämtar, ändrar, tar bort och uppdaterar data i databasen.
- Välj: Hämtar data från en enstaka eller flera tabeller
- Infoga: Lägger till ny data i en tabell
- Uppdatering: Ändrar befintliga data
- Ta bort: Tar bort befintliga poster i en tabell
- Data Control Language (DCL): Dessa kommandon är associerade med rättigheter eller behörighetskontroller i en databas.
- Bevilja: Tilldelar behörigheter till en användare
- Återkalla: Återkallar behörigheter från en användare
- Transaction Control Language (TCL): Dessa kommandon styr transaktioner i en databas.
- Bekräfta: Sparar ändringarna som gjorts av frågan
- Återställ: Återställer en explicit eller implicit transaktion till början av transaktionen, eller till en räddningspunkt inuti transaktionen
- Spara transaktioner: Ställer in en räddningspunkt eller markör inom en transaktion
Anta att du har kundorderdata lagrade i en SQL-tabell. Om du fortsatte att infoga data i den här tabellen kontinuerligt, kan tabellen innehålla miljontals poster, vilket skulle orsaka prestandaproblem i dina applikationer. Ditt indexunderhåll kan också bli extremt tidskrävande. Ofta behöver du inte behålla beställningar som är äldre än tre år. I dessa fall kan du ta bort dessa poster från tabellen. Detta skulle spara lagringsutrymme, samt minska dina underhållsinsatser.
Du kan ta bort data från en SQL-tabell på två sätt:
- Använda en SQL delete-sats
- Använda en trunkering
Vi kommer att titta på skillnaden mellan dessa SQL-kommandon senare. Låt oss först utforska SQL delete-satsen.
En SQL delete-sats utan några villkor
I DML-satser (data manipulation language) tar en SQL delete-sats bort raderna från en tabell. Du kan ta bort en specifik rad eller alla rader. En grundläggande delete-sats kräver inga argument.
Låt oss skapa en Orders SQL-tabell med skriptet nedan. Den här tabellen har tre kolumner [OrderID], [ProductName] och [ProductQuantity].
Create Table Orders
( OrderID int,
ProductName varchar(50),
ProductQuantity int
)
Infoga några poster i den här tabellen.
Insert into Orders values (1,'ABC books',10),
(2,'XYZ',100),
(3,'SQL book',50)
Anta nu att vi vill ta bort tabelldata. Du kan ange tabellnamnet för att ta bort data med hjälp av delete-satsen. Båda SQL-satserna är desamma. Vi kan ange tabellnamnet från det (valfria) nyckelordet eller ange tabellnamnet direkt efter borttagningen.
Delete Orders
Go
Delete from Orders
GO
En SQL delete-sats med filtrerad data
Dessa SQL delete-satser raderar alla tabellens data. Vanligtvis tar vi inte bort alla rader från en SQL-tabell. För att ta bort en specifik rad kan vi lägga till en where-sats med delete-satsen. Where-satsen innehåller filterkriterierna och bestämmer så småningom vilken eller vilka rader som ska tas bort.
Anta till exempel att vi vill ta bort order-id 1. När vi väl lägger till en where-klausul kontrollerar SQL Server först motsvarande rader och tar bort de specifika raderna.Delete Orders where orderid=1
Om where-satsvillkoret är falskt tar det inte bort några rader. Till exempel tog vi bort den beställda 1:an från beställningstabellen. Om vi kör satsen igen, hittar den inga rader som uppfyller where-satsvillkoret. I det här fallet returnerar den 0 rader påverkade.
SQL delete-sats och TOP-sats
Du kan använda TOP-satsen för att ta bort raderna också. Till exempel raderar frågan nedan de 100 översta raderna från ordertabellen.
Delete top (100) [OrderID]
from Orders
Eftersom vi inte har angett någon "ORDER BY" väljer den slumpmässiga rader och tar bort dem. Vi kan använda Order by-klausulen för att sortera data och ta bort de översta raderna. I frågan nedan sorterar den [OrderID] i fallande ordning och tar sedan bort det från tabellen [Order].
Delete from Orders where [OrderID] In
(
Select top 100 [OrderID] FROM Orders
order by [OrderID] Desc
)
Ta bort rader baserade på en annan tabell
Ibland behöver vi ta bort rader baserade på en annan tabell. Den här tabellen kan finnas i samma databas eller inte.
- Tabellsökning
Vi kan använda tabelluppslagsmetoden eller SQL-join för att ta bort dessa rader. Till exempel vill vi ta bort rader från tabellen [Order] som uppfyller följande villkor:
Den bör ha motsvarande rader i tabellen [dbo].[Kund].
Titta på frågan nedan, här har vi en select-sats i where-satsen i delete-satsen. SQL Server hämtar först de rader som uppfyller select-satsen och tar sedan bort dessa rader från tabellen [Order] med hjälp av SQL delete-satsen.
Delete Orders where orderid in
(Select orderid
from Customer)
- SQL Gå med
Alternativt kan vi använda SQL-kopplingar mellan dessa tabeller och ta bort raderna. I frågan nedan sammanfogar vi tabellerna [Order]] med tabellen [Kund]. En SQL-koppling fungerar alltid på en gemensam kolumn mellan tabellerna. Vi har en kolumn [OrderID] som sammanfogar båda tabellerna.
DELETE Orders
FROM Orders o
INNER JOIN Customer c ON o.orderid=c.orderid
För att förstå raderingssatsen ovan, låt oss se den faktiska exekveringsplanen.
Enligt exekveringsplanen utför den en tabellskanning på båda tabellerna, hämtar matchande data och tar bort dem från ordertabellen.
- Common table expression (CTE)
Vi kan använda ett vanligt tabelluttryck (CTE) för att ta bort raderna från en SQL-tabell också. Först definierar vi en CTE för att hitta raden som vi vill ta bort.
Sedan sammanfogar vi CTE med SQL-tabellorder och tar bort raderna.
WITH cteOrders AS
(SELECT OrderID
FROM Customer
WHERE CustomerID = 1 )
DELETE Orders
FROM cteOrders sp
INNER JOIN dbo.Orders o ON o.orderid = sp.orderid;
Påverkan på identitetsintervallet
Identitetskolumner i SQL Server genererar unika, sekventiella värden för din kolumn. De används främst för att unikt identifiera en rad i SQL-tabellen. En primärnyckelkolumn är också ett bra val för ett klustrat index i SQL Server.
I skriptet nedan har vi en [Anställd]-tabell. Den här tabellen har ett identitetskolumn-id.
Create Table Employee
(
id int identity(1,1),
[Name] varchar(50)
)
Vi infogade 50 poster i den här tabellen som genererade identitetsvärdena för id-kolumnen.
Declare @id int=1
While(@id<=50)
BEGIN
Insert into Employee([Name]) values('Test'+CONVERT(VARCHAR,@ID))
Set @id=@id+1
END
Om vi tar bort några rader från SQL-tabellen återställs inte identitetsvärdena för de efterföljande värdena. Låt oss till exempel ta bort några rader som har identitetsvärdena 20 till 25.
Delete from employee
where id between 20 and 25
Se nu tabellposterna.
Select * from employee where id>15
Den visar gapet i identitetsvärdesintervallet.
SQL delete uttalande och transaktionsloggen
SQL delete loggar varje radradering i transaktionsloggen. Anta att du behöver ta bort miljontals poster från en SQL-tabell. Du vill inte radera ett stort antal poster i en enda transaktion eftersom det kan få din loggfil att växa exponentiellt och din databas kanske också är otillgänglig. Om du avbryter en transaktion i mitten kan det ta timmar att återställa ett raderingsutdrag.
I det här fallet bör du alltid ta bort rader i små bitar och commitera dessa bitar regelbundet. Du kan till exempel ta bort en batch med 10 000 rader åt gången, commit den och flytta till nästa batch. När SQL Server commiterar biten kan transaktionsloggens tillväxt kontrolleras.
Bästa metoder
- Du bör alltid göra en säkerhetskopia innan du tar bort data.
- Som standard använder SQL Server implicita transaktioner och överför posterna utan att fråga användaren. Som en bästa praxis bör du starta en explicit transaktion med Start Transaction. Det ger dig kontrollen att utföra eller återställa transaktionen. Du bör också köra täta säkerhetskopior av transaktionsloggar om din databas är i fullt återställningsläge.
- Du vill radera data i små bitar för att undvika överdriven användning av transaktionsloggar. Det undviker också blockeringar för andra SQL-transaktioner.
- Du bör begränsa behörigheter så att användare inte kan radera data. Endast de auktoriserade användarna ska ha åtkomst att ta bort data från en SQL-tabell.
- Du vill köra delete-satsen med en where-sats. Den tar bort filtrerad data från en SQL-tabell. Om din applikation kräver frekvent radering av data är det en bra idé att återställa identitetsvärdena med jämna mellanrum. Annars kan du få problem med utmattning av identitetsvärde.
- Om du vill tömma tabellen är det lämpligt att använda trunkeringssatsen. Truncate-satsen tar bort all data från en tabell, använder minimal transaktionsloggning, återställer identitetsvärdeintervallet och är snabbare än SQL delete-satsen eftersom den omedelbart avallokerar alla sidor för tabellen.
- Om du använder främmande nyckelbegränsningar (förälder-underordnad relation) för dina tabeller, bör du ta bort raden från en underordnad rad och sedan från den överordnade tabellen. Om du tar bort raden från den överordnade raden kan du också använda alternativet kaskad vid radering för att automatiskt ta bort raden från en underordnad tabell. Du kan hänvisa till artikeln: Ta bort kaskad och uppdatera kaskad i SQL Server främmande nyckel för ytterligare insikter.
- Om du använder toppsatsen för att ta bort raderna, raderar SQL Server raderna slumpmässigt. Du bör alltid använda den översta klausulen med motsvarande Ordning efter och Gruppera efter klausul.
- En delete-sats får ett exklusivt avsiktslås på referenstabellen; Därför kan inga andra transaktioner ändra uppgifterna under den tiden. Du kan använda NOLOCK-tipset för att läsa data.
- Du bör undvika att använda tabelltipset för att åsidosätta standardlåsbeteendet för SQL delete-satsen; det bör endast användas av erfarna DBA:er och utvecklare.
Viktiga överväganden
Det finns många fördelar med att använda SQL delete-satser för att ta bort data från en SQL-tabell, men som du kan se kräver det ett metodiskt tillvägagångssätt. Det är viktigt att alltid radera data i små partier och att vara försiktig när man raderar data från en produktionsinstans. Att ha en säkerhetskopieringsstrategi för att återställa data på kortast möjliga tid är ett måste för att undvika driftstopp eller framtida prestandapåverkan.