TA BORT (Transact-SQL)
gäller för:SQL Server
Azure SQL Database
Azure SQL Managed Instance
Azure Synapse Analytics
Analytics Platform System (PDW)
Warehouse i Microsoft Fabric
SQL-databas i Microsoft Fabric
Tar bort en eller flera rader från en tabell eller vy i SQL Server.
Transact-SQL syntaxkonventioner
Syntax
-- Syntax for SQL Server and Azure SQL Database
[ WITH <common_table_expression> [ ,...n ] ]
DELETE
[ TOP ( expression ) [ PERCENT ] ]
[ FROM ]
{ { table_alias
| <object>
| rowset_function_limited
[ WITH ( table_hint_limited [ ...n ] ) ] }
| @table_variable
}
[ <OUTPUT Clause> ]
[ FROM table_source [ ,...n ] ]
[ WHERE { <search_condition>
| { [ CURRENT OF
{ { [ GLOBAL ] cursor_name }
| cursor_variable_name
}
]
}
}
]
[ OPTION ( <Query Hint> [ ,...n ] ) ]
[; ]
<object> ::=
{
[ server_name.database_name.schema_name.
| database_name. [ schema_name ] .
| schema_name.
]
table_or_view_name
}
-- Syntax for Azure Synapse Analytics and Microsoft Fabric
[ WITH <common_table_expression> [ ,...n ] ]
DELETE [database_name . [ schema ] . | schema. ] table_name
FROM [database_name . [ schema ] . | schema. ] table_name
JOIN {<join_table_source>}[ ,...n ]
ON <join_condition>
[ WHERE <search_condition> ]
[ OPTION ( <query_options> [ ,...n ] ) ]
[; ]
<join_table_source> ::=
{
[ database_name . [ schema_name ] . | schema_name . ] table_or_view_name [ AS ] table_or_view_alias
[ <tablesample_clause>]
| derived_table [ AS ] table_alias [ ( column_alias [ ,...n ] ) ]
}
-- Syntax for Parallel Data Warehouse
DELETE
[ FROM [database_name . [ schema ] . | schema. ] table_name ]
[ WHERE <search_condition> ]
[ OPTION ( <query_options> [ ,...n ] ) ]
[; ]
Argument
MED <common_table_expression>
Anger den tillfälliga namngivna resultatuppsättningen, även kallat common table expression, som definierats inom omfånget för DELETE-instruktionen. Resultatuppsättningen härleds från en SELECT-instruktion.
Vanliga tabelluttryck kan också användas med satserna SELECT, INSERT, UPDATE och CREATE VIEW. Mer information finns i WITH common_table_expression (Transact-SQL).
TOP (uttryck) [ PERCENT ]
Anger antalet eller procent av slumpmässiga rader som ska tas bort.
uttryck kan vara antingen ett tal eller en procent av raderna. Raderna som refereras i TOP-uttrycket som används med INSERT, UPDATE eller DELETE ordnas inte i någon ordning. Mer information finns i TOP (Transact-SQL).
FRÅN
Ett valfritt nyckelord som kan användas mellan nyckelordet DELETE och målet table_or_view_name, eller rowset_function_limited.
table_alias
Det alias som anges i FROM-table_source-satsen som representerar tabellen eller vyn som raderna ska tas bort från.
server_name
gäller för: SQL Server 2008 (10.0.x) och senare.
Namnet på servern (med ett länkat servernamn eller OPENDATASOURCE- funktion som servernamn) som tabellen eller vyn finns på. Om server_name anges krävs database_name och schema_name.
database_name
Namnet på databasen.
schema_name
Namnet på schemat som tabellen eller vyn tillhör.
table_or_view_name
Namnet på tabellen eller vyn som raderna ska tas bort från.
En tabellvariabel inom dess omfång kan också användas som en tabellkälla i en DELETE-instruktion.
Vyn som refereras av table_or_view_name måste vara uppdaterad och referera till exakt en bastabell i FROM-satsen i vydefinitionen. Mer information om uppdateringsbara vyer finns i CREATE VIEW (Transact-SQL).
rowset_function_limited
gäller för: SQL Server 2008 (10.0.x) och senare.
Antingen funktionen OPENQUERY eller OPENROWSET, beroende på providerfunktioner.
MED (<table_hint_limited> [... n] )
Anger en eller flera tabelltips som tillåts för en måltabell. Nyckelordet WITH och parenteserna krävs. NOLOCK och READUNCOMMITTED tillåts inte. Mer information om tabelltips finns i Tabelltips (Transact-SQL).
<OUTPUT_Clause>
Returnerar borttagna rader eller uttryck baserat på dem som en del av DELETE-åtgärden. OUTPUT-satsen stöds inte i DML-instruktioner som riktar sig till vyer eller fjärrtabeller. Mer information om argumenten och beteendet för den här satsen finns i OUTPUT-satsen (Transact-SQL).
FRÅN table_source
Anger ytterligare en FROM-sats. Med det här Transact-SQL tillägget delete kan du ange data från <table_source> och ta bort motsvarande rader från tabellen i den första FROM-satsen.
Det här tillägget, som anger en koppling, kan användas i stället för en underfråga i WHERE-satsen för att identifiera rader som ska tas bort.
Mer information finns i FROM (Transact-SQL).
VAR
Anger de villkor som används för att begränsa antalet rader som tas bort. Om en WHERE-sats inte har angetts tar DELETE bort alla rader från tabellen.
Det finns två former av borttagningsåtgärder baserat på vad som anges i WHERE-satsen:
Genomsökda borttagningar anger ett sökvillkor för att kvalificera raderna som ska tas bort. Till exempel WHERE column_name = -värdet.
Placerade borttagningar använder CURRENT OF-satsen för att ange en markör. Borttagningsåtgärden sker på markörens aktuella position. Detta kan vara mer exakt än en sökåtgärd för DELETE som använder en WHERE-search_condition-sats för att kvalificera raderna som ska tas bort. En genomsökt DELETE-instruktion tar bort flera rader om sökvillkoret inte unikt identifierar en enskild rad.
<search_condition>
Anger de begränsande villkoren för de rader som ska tas bort. Det finns ingen gräns för antalet predikat som kan ingå i ett sökvillkor. Mer information finns i sökvillkor (Transact-SQL).
AKTUELL FÖR
Anger att DELETE utförs på den aktuella positionen för den angivna markören.
GLOBAL
Anger att cursor_name refererar till en global markör.
cursor_name
Är namnet på den öppna markören som hämtningen görs från. Om både en global och en lokal markör med namnet cursor_name finns refererar det här argumentet till den globala markören om GLOBAL anges. annars refererar den till den lokala markören. Markören måste tillåta uppdateringar.
cursor_variable_name
Namnet på en markörvariabel. Markörvariabeln måste referera till en markör som tillåter uppdateringar.
ALTERNATIV (<query_hint> [ ,... n] )
Nyckelord som anger vilka optimerartips som används för att anpassa hur databasmotorn bearbetar instruktionen. Mer information finns i Frågetips (Transact-SQL).
Metodtips
Om du vill ta bort alla rader i en tabell använder du TRUNCATE TABLE
.
TRUNCATE TABLE
är snabbare än DELETE och använder färre system- och transaktionsloggresurser.
TRUNCATE TABLE
har begränsningar, till exempel kan tabellen inte delta i replikering. Mer information finns i TRUNKERA TABELL (Transact-SQL)
Använd funktionen @@ROWCOUNT
för att returnera antalet borttagna rader till klientprogrammet. Mer information finns i @@ROWCOUNT (Transact-SQL).
Felhantering
Du kan implementera felhantering för DELETE-instruktionen genom att ange -instruktionen i en TRY...CATCH
konstruktion.
Instruktionen DELETE
kan misslyckas om den bryter mot en utlösare eller försöker ta bort en rad som refereras av data i en annan tabell med en FOREIGN KEY
begränsning. Om DELETE
tar bort flera rader och någon av de borttagna raderna bryter mot en utlösare eller begränsning avbryts instruktionen, ett fel returneras och inga rader tas bort.
När en DELETE-instruktion stöter på ett aritmetikfel (spill, dividera med noll eller ett domänfel) som inträffar under uttrycksutvärderingen hanterar databasmotorn dessa fel som om SET ARITHABORT
är inställt på PÅ. Resten av batchen avbryts och ett felmeddelande returneras.
Samverkan
DELETE kan användas i brödtexten för en användardefinierad funktion om objektet som ändras är en tabellvariabel.
När du tar bort en rad som innehåller en FILESTREAM-kolumn tar du även bort dess underliggande filsystemfiler. De underliggande filerna tas bort av FILESTREAM-skräpinsamlaren. Mer information finns i Access FILESTREAM Data with Transact-SQL.
FROM-satsen kan inte anges i en DELETE-instruktion som refererar till, antingen direkt eller indirekt, en vy med en INSTEAD OF
utlösare som definierats på den. Mer information om I stället för utlösare finns i CREATE TRIGGER (Transact-SQL).
För närvarande går det inte att ange FROM-satsen i en DELETE-instruktion på Warehouse i Microsoft Fabric.
Begränsningar och begränsningar
När TOP
används med DELETE
ordnas inte de refererade raderna i någon ordning och ORDER BY
-satsen kan inte anges direkt i den här instruktionen. Om du behöver använda TOP för att ta bort rader i en meningsfull kronologisk ordning måste du använda TOP
tillsammans med en ORDER BY
-sats i en undermarkeringsinstruktion. Se avsnittet Exempel som följer i det här avsnittet.
TOP
kan inte användas i en DELETE
-instruktion mot partitionerade vyer.
Låsningsbeteende
Som standard hämtar en DELETE
-instruktion alltid ett exklusivt avsiktslås (IX
) på tabellobjektet och sidor som det ändrar, ett exklusivt (X
) lås på de rader som ändras och håller dessa lås tills transaktionen har slutförts.
Med ett exklusivt (IX
) lås kan inga andra transaktioner ändra samma uppsättning data. läsåtgärder kan endast utföras med hjälp av NOLOCK-tipset eller ogenomsläst isoleringsnivå. Du kan ange tabelltips för att åsidosätta det här standardbeteendet under delete-instruktionens varaktighet genom att ange en annan låsningsmetod, men vi rekommenderar att tips endast används som en sista utväg av erfarna utvecklare och databasadministratörer. Mer information finns i Tabelltips (Transact-SQL).
När rader tas bort från en heap kan databasmotorn använda rad- eller sidlåsning för åtgärden. Därför förblir de sidor som gjorts tomma av borttagningsåtgärden allokerade till heapen. När tomma sidor inte frigörs kan det associerade utrymmet inte återanvändas av andra objekt i databasen.
Om du vill ta bort rader i en heap och frigöra sidor använder du någon av följande metoder.
Ange
TABLOCK
tips iDELETE
-instruktionen. Med hjälp avTABLOCK
-tipset tar borttagningsåtgärden ett IX-lås på objektet i stället för ett rad- eller sidlås. På så sätt kan sidorna frigöras. Mer information omTABLOCK
tips finns i Table Hints (Transact-SQL).Använd
TRUNCATE TABLE
om alla rader ska tas bort från tabellen.Skapa ett grupperat index på heapen innan du tar bort raderna. Du kan släppa det klustrade indexet när raderna har tagits bort. Den här metoden är mer tidskrävande än de tidigare metoderna och använder mer tillfälliga resurser.
Not
Tomma sidor kan när som helst tas bort från en heap med hjälp av instruktionen ALTER TABLE <table_name> REBUILD
.
Om optimerad låsning är aktiverat kan vissa aspekter av låsningsbeteendet för DELETE
ändras. Till exempel hålls inte exklusiva lås (X
) förrän transaktionen har slutförts. Mer information finns i Optimerad låsning.
Loggningsbeteende
DELETE-instruktionen är alltid helt loggad.
Säkerhet
Behörigheter
DELETE
behörigheter krävs i måltabellen.
SELECT
behörigheter krävs också om -instruktionen innehåller en WHERE-sats.
DELETE-behörigheter är standard för medlemmar i den sysadmin
fasta serverrollen, db_owner
och db_datawriter
fasta databasroller och tabellägaren. Medlemmar i rollerna sysadmin
, db_owner
och db_securityadmin
och tabellägaren kan överföra behörigheter till andra användare.
Exempel
Kategori | Aktuella syntaxelement |
---|---|
Grundläggande syntax | TA BORT |
Begränsa borttagna rader | WHERE * FROM * cursor * |
ta bort rader från en fjärrtabell | Länkad server * funktionen OPENQUERY rowset * funktionen OPENDATASOURCE rowset |
Avbilda resultatet av DELETE-instruktionen | OUTPUT-sats |
Grundläggande syntax
Exempel i det här avsnittet visar de grundläggande funktionerna i DELETE-instruktionen med den minsta syntax som krävs.
A. Använda DELETE utan WHERE-sats
I följande exempel tas alla rader bort från tabellen SalesPersonQuotaHistory
i databasen AdventureWorks2022 eftersom en WHERE-sats inte används för att begränsa antalet borttagna rader.
DELETE FROM Sales.SalesPersonQuotaHistory;
GO
Begränsa borttagna rader
Exempel i det här avsnittet visar hur du begränsar antalet rader som ska tas bort.
B. Använda WHERE-satsen för att ta bort en uppsättning rader
I följande exempel tas alla rader bort från tabellen ProductCostHistory
i databasen AdventureWorks2022 där värdet i kolumnen StandardCost
är mer än 1000.00
.
DELETE FROM Production.ProductCostHistory
WHERE StandardCost > 1000.00;
GO
I följande exempel visas en mer komplex WHERE-sats. WHERE-satsen definierar två villkor som måste uppfyllas för att fastställa vilka rader som ska tas bort. Värdet i kolumnen StandardCost
måste vara mellan 12.00
och 14.00
och värdet i kolumnen SellEndDate
måste vara null. Exemplet skriver också ut värdet från funktionen @@ROWCOUNT för att returnera antalet borttagna rader.
DELETE Production.ProductCostHistory
WHERE StandardCost BETWEEN 12.00 AND 14.00
AND EndDate IS NULL;
PRINT 'Number of rows deleted is ' + CAST(@@ROWCOUNT as char(3));
C. Använda en markör för att fastställa vilken rad som ska tas bort
I följande exempel tas en rad bort från tabellen EmployeePayHistory
i databasen AdventureWorks2022 med hjälp av en markör med namnet complex_cursor
. Borttagningsåtgärden påverkar endast den enskild rad som för närvarande hämtas från markören.
DECLARE complex_cursor CURSOR FOR
SELECT a.BusinessEntityID
FROM HumanResources.EmployeePayHistory AS a
WHERE RateChangeDate <>
(SELECT MAX(RateChangeDate)
FROM HumanResources.EmployeePayHistory AS b
WHERE a.BusinessEntityID = b.BusinessEntityID) ;
OPEN complex_cursor;
FETCH FROM complex_cursor;
DELETE FROM HumanResources.EmployeePayHistory
WHERE CURRENT OF complex_cursor;
CLOSE complex_cursor;
DEALLOCATE complex_cursor;
GO
D. Använda kopplingar och underfrågor till data i en tabell för att ta bort rader i en annan tabell
I följande exempel visas två sätt att ta bort rader i en tabell baserat på data i en annan tabell. I båda exemplen tas rader från tabellen SalesPersonQuotaHistory
i databasen AdventureWorks2022 bort baserat på den hittills i år lagrade försäljningen i tabellen SalesPerson
. Den första DELETE
-instruktionen visar den ISO-kompatibla underfrågan, och den andra DELETE
-instruktionen visar Transact-SQL FROM-tillägget för att ansluta till de två tabellerna.
-- SQL-2003 Standard subquery
DELETE FROM Sales.SalesPersonQuotaHistory
WHERE BusinessEntityID IN
(SELECT BusinessEntityID
FROM Sales.SalesPerson
WHERE SalesYTD > 2500000.00);
GO
-- Transact-SQL extension
DELETE FROM Sales.SalesPersonQuotaHistory
FROM Sales.SalesPersonQuotaHistory AS spqh
INNER JOIN Sales.SalesPerson AS sp
ON spqh.BusinessEntityID = sp.BusinessEntityID
WHERE sp.SalesYTD > 2500000.00;
GO
-- No need to mention target table more than once.
DELETE spqh
FROM
Sales.SalesPersonQuotaHistory AS spqh
INNER JOIN Sales.SalesPerson AS sp
ON spqh.BusinessEntityID = sp.BusinessEntityID
WHERE sp.SalesYTD > 2500000.00;
E. Använda TOP för att begränsa antalet borttagna rader
När en TOP-sats (n) används med DELETE utförs borttagningsåtgärden på ett slumpmässigt urval av n antal rader. I följande exempel tas 20
slumpmässiga rader bort från tabellen PurchaseOrderDetail
i databasen AdventureWorks2022 som har förfallodatum som är tidigare än den 1 juli 2006.
DELETE TOP (20)
FROM Purchasing.PurchaseOrderDetail
WHERE DueDate < '20020701';
GO
Om du måste använda TOP för att ta bort rader i en meningsfull kronologisk ordning måste du använda TOP tillsammans med ORDER BY i en undermarkeringsinstruktör. Följande fråga tar bort de 10 raderna i tabellen PurchaseOrderDetail
som har de tidigaste förfallodatumen. För att säkerställa att endast 10 rader tas bort är kolumnen som anges i instruktionen subselect (PurchaseOrderID
) den primära nyckeln i tabellen. Om du använder en icke-nyckelkolumn i undermarkeringssatsen kan fler än 10 rader tas bort om den angivna kolumnen innehåller duplicerade värden.
DELETE FROM Purchasing.PurchaseOrderDetail
WHERE PurchaseOrderDetailID IN
(SELECT TOP 10 PurchaseOrderDetailID
FROM Purchasing.PurchaseOrderDetail
ORDER BY DueDate ASC);
GO
Ta bort rader från en fjärrtabell
Exempel i det här avsnittet visar hur du tar bort rader från en fjärrtabell med hjälp av en länkad server eller en raduppsättningsfunktion för att referera till fjärrtabellen. Det finns en fjärrtabell på en annan server eller instans av SQL Server.
gäller för: SQL Server 2008 (10.0.x) och senare.
F. Ta bort data från en fjärrtabell med hjälp av en länkad server
I följande exempel tas rader bort från en fjärrtabell. Exemplet börjar med att skapa en länk till fjärrdatakällan med hjälp av sp_addlinkedserver. Det länkade servernamnet, MyLinkServer
, anges sedan som en del av objektnamnet i fyra delar i formuläret server.catalog.schema.object.
USE master;
GO
-- Create a link to the remote data source.
-- Specify a valid server name for @datasrc as 'server_name' or 'server_name\instance_name'.
EXEC sp_addlinkedserver @server = N'MyLinkServer',
@srvproduct = N' ',
@provider = N'SQLNCLI',
@datasrc = N'server_name',
@catalog = N'AdventureWorks2022';
GO
-- Specify the remote data source using a four-part name
-- in the form linked_server.catalog.schema.object.
DELETE MyLinkServer.AdventureWorks2022.HumanResources.Department
WHERE DepartmentID > 16;
GO
G. Ta bort data från en fjärrtabell med hjälp av funktionen OPENQUERY
I följande exempel tas rader bort från en fjärrtabell genom att ange funktionen OPENQUERY rowset. Det länkade servernamnet som skapades i föregående exempel används i det här exemplet.
DELETE OPENQUERY (MyLinkServer, 'SELECT Name, GroupName
FROM AdventureWorks2022.HumanResources.Department
WHERE DepartmentID = 18');
GO
H. Ta bort data från en fjärrtabell med funktionen OPENDATASOURCE
I följande exempel tas rader bort från en fjärrtabell genom att ange funktionen OPENDATASOURCE rowset. Ange ett giltigt servernamn för datakällan med hjälp av formatet server_name eller server_name\instance_name.
DELETE FROM OPENDATASOURCE('SQLNCLI',
'Data Source= <server_name>; Integrated Security=SSPI')
.AdventureWorks2022.HumanResources.Department
WHERE DepartmentID = 17;
Samla in resultatet av DELETE-instruktionen
Jag. Använda DELETE med OUTPUT-satsen
I följande exempel visas hur du sparar resultatet av en DELETE
-instruktion i en tabellvariabel i databasen AdventureWorks2022.
DELETE Sales.ShoppingCartItem
OUTPUT DELETED.*
WHERE ShoppingCartID = 20621;
--Verify the rows in the table matching the WHERE clause have been deleted.
SELECT COUNT(*) AS [Rows in Table]
FROM Sales.ShoppingCartItem
WHERE ShoppingCartID = 20621;
GO
J. Använda UTDATA med <from_table_name> i en DELETE-instruktion
I följande exempel tas rader i tabellen ProductProductPhoto
bort i databasen AdventureWorks2022 baserat på sökvillkor som definierats i FROM
-satsen i DELETE
-instruktionen. Satsen OUTPUT
returnerar kolumner från tabellen som tas bort, DELETED.ProductID
, DELETED.ProductPhotoID
och kolumner från tabellen Product
. Detta används i FROM
-satsen för att ange de rader som ska tas bort.
DECLARE @MyTableVar table (
ProductID int NOT NULL,
ProductName nvarchar(50)NOT NULL,
ProductModelID int NOT NULL,
PhotoID int NOT NULL);
DELETE Production.ProductProductPhoto
OUTPUT DELETED.ProductID,
p.Name,
p.ProductModelID,
DELETED.ProductPhotoID
INTO @MyTableVar
FROM Production.ProductProductPhoto AS ph
JOIN Production.Product as p
ON ph.ProductID = p.ProductID
WHERE p.ProductModelID BETWEEN 120 and 130;
--Display the results of the table variable.
SELECT ProductID, ProductName, ProductModelID, PhotoID
FROM @MyTableVar
ORDER BY ProductModelID;
GO
Exempel: Azure Synapse Analytics and Analytics Platform System (PDW)
K. Ta bort alla rader från en tabell
I följande exempel tas alla rader bort från tabellen Table1
eftersom en WHERE-sats inte används för att begränsa antalet borttagna rader.
DELETE FROM Table1;
L. TA BORT en uppsättning rader från en tabell
I följande exempel tas alla rader bort från tabellen Table1
som har ett värde större än 1 000,00 i kolumnen StandardCost
.
DELETE FROM Table1
WHERE StandardCost > 1000.00;
M. Använda LABEL med en DELETE-instruktion
I följande exempel används en etikett med DELETE-instruktionen.
DELETE FROM Table1
OPTION ( LABEL = N'label1' );
N. Använda en etikett och ett frågetips med DELETE-instruktionen
Den här frågan visar den grundläggande syntaxen för att använda ett frågekopplingstips med DELETE-instruktionen. Mer information om kopplingstips och hur du använder OPTION-satsen finns i OPTION-satsen (Transact-SQL).
-- Uses AdventureWorks
DELETE FROM dbo.FactInternetSales
WHERE ProductKey IN (
SELECT T1.ProductKey FROM dbo.DimProduct T1
JOIN dbo.DimProductSubcategory T2
ON T1.ProductSubcategoryKey = T2.ProductSubcategoryKey
WHERE T2.EnglishProductSubcategoryName = 'Road Bikes' )
OPTION ( LABEL = N'CustomJoin', HASH JOIN ) ;
O. Ta bort med hjälp av en WHERE-sats
Den här frågan visar hur du tar bort med hjälp av en WHERE-sats och inte använder en FROM-sats.
DELETE tableA WHERE EXISTS (
SELECT TOP 1 1 FROM tableB tb WHERE tb.col1 = tableA.col1
)
P. Ta bort baserat på resultatet av anslutning till en annan tabell
Det här exemplet visar hur du tar bort från en tabell baserat på resultatet från anslutningen till en annan tabell.
CREATE TABLE dbo.Table1
(ColA int NOT NULL, ColB decimal(10,3) NOT NULL);
GO
CREATE TABLE dbo.Table2
(ColA int PRIMARY KEY NOT NULL, ColB decimal(10,3) NOT NULL);
GO
INSERT INTO dbo.Table1 VALUES(1, 10.0), (1, 20.0);
INSERT INTO dbo.Table2 VALUES(1, 0.0);
GO
DELETE dbo.Table2
FROM dbo.Table2
INNER JOIN dbo.Table1
ON (dbo.Table2.ColA = dbo.Table1.ColA)
WHERE dbo.Table2.ColA = 1;
Se även
CREATE TRIGGER (Transact-SQL)
INSERT (Transact-SQL)
SELECT (Transact-SQL)
TRUNKERA TABELL (Transact-SQL)
UPDATE (Transact-SQL)
MED common_table_expression (Transact-SQL)
@@ROWCOUNT (Transact-SQL)