DELETE (Transact-SQL)

Syntax
[ 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
}

Arguments
- WITH <common_table_expression>
Specifies the temporary named result set, also known as common table expression, defined within the scope of the DELETE statement. The result set is derived from a SELECT statement. Common table expressions can also be used with the SELECT, INSERT, UPDATE, and CREATE VIEW statements. For more information, see WITH Common. - TOP (expression) [ PERCENT ]
Specifies the number or percent of random rows that will be deleted. expression can be either a number or a percent of the rows. The rows referenced in the TOP expression used with INSERT, UPDATE, or DELETE are not arranged in any order. For more information, see TOP (Transact-SQL). - FROM
An optional keyword that can be used between the DELETE keyword and the target table_or_view_name, or rowset_function_limited. - table_alias
The alias specified in the FROM table_source clause representing the table or view from which the rows are to be deleted. - server_name
The name of the server (using a linked server name or the OPENDATASOURCE function as the server name) on which the table or view is located. If server_name is specified, database_name and schema_name are required. - database_name
The name of the database. - schema_name
The name of the schema to which the table or view belongs. - table_or view_name
The name of the table or view from which the rows are to be removed. A table variable, within its scope, also can be used as a table source in a DELETE statement. The view referenced by table_or_view_name must be updatable and reference exactly one base table in the FROM clause of the view definition. For more information about updatable views, see CREATE VIEW (Transact-SQL). - rowset_function_limited
Either the OPENQUERY or OPENROWSET function, subject to provider capabilities. - WITH ( <table_hint_limited> [... n] )
Specifies one or more table hints that are allowed for a target table. The WITH keyword and the parentheses are required. NOLOCK and READUNCOMMITTED are not allowed. For more information about table hints, see Table Hints (Transact-SQL). - <OUTPUT_Clause>
Returns deleted rows, or expressions based on them, as part of the DELETE operation. The OUTPUT clause is not supported in any DML statements targeting views or remote tables. For more information, see OUTPUT Clause (Transact-SQL). - FROM table_source
Specifies an additional FROM clause. This Transact-SQL extension to DELETE allows specifying data from <table_source> and deleting the corresponding rows from the table in the first FROM clause. This extension, specifying a join, can be used instead of a subquery in the WHERE clause to identify rows to be removed. For more information, see FROM (Transact-SQL). - WHERE
Specifies the conditions used to limit the number of rows that are deleted. If a WHERE clause is not supplied, DELETE removes all the rows from the table. There are two forms of delete operations based on what is specified in the WHERE clause: Searched deletes specify a search condition to qualify the rows to delete. For example, WHERE column_name = value. Positioned deletes use the CURRENT OF clause to specify a cursor. The delete operation occurs at the current position of the cursor. This can be more accurate than a searched DELETE statement that uses a WHERE search_condition clause to qualify the rows to be deleted. A searched DELETE statement deletes multiple rows if the search condition does not uniquely identify a single row.
- <search_condition>
Specifies the restricting conditions for the rows to be deleted. There is no limit to the number of predicates that can be included in a search condition. For more information, see Search Condition (Transact-SQL). - CURRENT OF
Specifies that the DELETE is performed at the current position of the specified cursor. - GLOBAL
Specifies that cursor_name refers to a global cursor. - cursor_name
Is the name of the open cursor from which the fetch is made. If both a global and a local cursor with the name cursor_name exist, this argument refers to the global cursor if GLOBAL is specified; otherwise, it refers to the local cursor. The cursor must allow updates. - cursor_variable_name
The name of a cursor variable. The cursor variable must reference a cursor that allows updates. - OPTION ( <query_hint> [ ,... n] )
Keywords that indicate which optimizer hints are used to customize the way the Database Engine processes the statement. For more information, see Query Hints (Transact-SQL).

Best Practices
To delete all the rows in a table, use TRUNCATE TABLE. TRUNCATE TABLE is faster than DELETE and uses fewer system and transaction log resources. Use the @@ROWCOUNT function to return the number of deleted rows to the client application. For more information, see @@ROWCOUNT (Transact-SQL).

Error Handling
You can implement error handling for the DELETE statement by specifying the statement in a TRY…CATCH construct. The DELETE statement may fail if it violates a trigger or tries to remove a row referenced by data in another table with a FOREIGN KEY constraint. If the DELETE removes multiple rows, and any one of the removed rows violates a trigger or constraint, the statement is canceled, an error is returned, and no rows are removed. When a DELETE statement encounters an arithmetic error (overflow, divide by zero, or a domain error) occurring during expression evaluation, the Database Engine handles these errors as if SET ARITHABORT is set ON. The rest of the batch is canceled, and an error message is returned.

Interoperability
DELETE can be used in the body of a user-defined function if the object modified is a table variable. When you delete a row that contains a FILESTREAM column, you also delete its underlying file system files. The underlying files are removed by the FILESTREAM garbage collector. For more information, see Access FILESTREAM Data with Transact-SQL. The FROM clause cannot be specified in a DELETE statement that references, either directly or indirectly, a view with an INSTEAD OF trigger defined on it. For more information about INSTEAD OF triggers, see CREATE TRIGGER (Transact-SQL).

Limitations and Restrictions
When TOP is used with DELETE, the referenced rows are not arranged in any order and the ORDER BY clause can not be directly specified in this statement. If you need to use TOP to delete rows in a meaningful chronological order, you must use TOP together with an ORDER BY clause in a subselect statement. See the Examples section that follows in this topic. TOP cannot be used in a DELETE statement against partitioned views.

Locking Behavior
By default, a DELETE statement always acquires an exclusive (X) lock on the table it modifies, and holds that lock until the transaction completes. With an exclusive (X) lock, no other transactions can modify data; read operations can take place only with the use of the NOLOCK hint or read uncommitted isolation level. You can specify table hints to override this default behavior for the duration of the DELETE statement by specifying another locking method, however, we recommend that hints be used only as a last resort by experienced developers and database administrators. For more information, see Table Hints (Transact-SQL). When rows are deleted from a heap the Database Engine may use row or page locking for the operation. As a result, the pages made empty by the delete operation remain allocated to the heap. When empty pages are not deallocated, the associated space cannot be reused by other objects in the database. To delete rows in a heap and deallocate pages, use one of the following methods. Specify the TABLOCK hint in the DELETE statement. Using the TABLOCK hint causes the delete operation to take a shared lock on the table instead of a row or page lock. This allows the pages to be deallocated. For more information about the TABLOCK hint, see Table Hints (Transact-SQL). Use TRUNCATE TABLE if all rows are to be deleted from the table. Create a clustered index on the heap before deleting the rows. You can drop the clustered index after the rows are deleted. This method is more time consuming than the previous methods and uses more temporary resources.

Logging Behavior
The DELETE statement is always fully logged.

Security
PermissionsDELETE permissions are required on the target table. SELECT permissions are also required if the statement contains a WHERE clause. DELETE permissions default to members of the sysadmin fixed server role, the db_owner and db_datawriter fixed database roles, and the table owner. Members of the sysadmin, db_owner, and the db_securityadmin roles, and the table owner can transfer permissions to other users.

Examples
Basic SyntaxExamples in this section demonstrate the basic functionality of the DELETE statement using the minimum required syntax. A.Using DELETE with no WHERE clauseThe following example deletes all rows from the SalesPersonQuotaHistory table because a WHERE clause is not used to limit the number of rows deleted.
USE AdventureWorks2012;
GO
DELETE FROM Sales.SalesPersonQuotaHistory;
GO
Limiting the Rows DeletedExamples in this section demonstrate how to limit the number of rows that will be deleted. A.Using the WHERE clause to delete a set of rowsThe following example deletes all rows from the ProductCostHistory table in which the value in the StandardCost column is more than 1000.00.
USE AdventureWorks2012;
GO
DELETE FROM Production.ProductCostHistory
WHERE StandardCost > 1000.00;
GO
The following example shows a more complex WHERE clause. The WHERE clause defines two conditions that must be met to determine the rows to delete. The value in the StandardCost column must be between 12.00 and 14.00 and the value in the column SellEndDate must be null. The example also prints the value from the @@ROWCOUNT function to return the number of deleted rows.
USE AdventureWorks2012;
GO
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));
B.Using a cursor to determine the row to deleteThe following example deletes a single row from the EmployeePayHistory table using a cursor named my_cursor. The delete operation affects only the single row currently fetched from the cursor.
USE AdventureWorks2012;
GO
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
C.Using joins and subqueries to data in one table to delete rows in another tableThe following examples show two ways to delete rows in one table based on data in another table. In both examples, rows from the SalesPersonQuotaHistory table based are deleted based on the year-to-date sales stored in the SalesPerson table. The first DELETE statement shows the ISO-compatible subquery solution, and the second DELETE statement shows the Transact-SQL FROM extension to join the two tables.
-- SQL-2003 Standard subquery
USE AdventureWorks2012;
GO
DELETE FROM Sales.SalesPersonQuotaHistory
WHERE BusinessEntityID IN
(SELECT BusinessEntityID
FROM Sales.SalesPerson
WHERE SalesYTD > 2500000.00);
GO
-- Transact-SQL extension
USE AdventureWorks2012;
GO
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
A.Using TOP to limit the number of rows deletedWhen a TOP (n) clause is used with DELETE, the delete operation is performed on a random selection of n number of rows. The following example deletes 20 random rows from the PurchaseOrderDetail table that have due dates that are earlier than July 1, 2006.
USE AdventureWorks2012;
GO
DELETE TOP (20)
FROM Purchasing.PurchaseOrderDetail
WHERE DueDate < '20020701';
GO
If you have to use TOP to delete rows in a meaningful chronological order, you must use TOP together with ORDER BY in a subselect statement. The following query deletes the 10 rows of the PurchaseOrderDetail table that have the earliest due dates. To ensure that only 10 rows are deleted, the column specified in the subselect statement (PurchaseOrderID) is the primary key of the table. Using a nonkey column in the subselect statement may result in the deletion of more than 10 rows if the specified column contains duplicate values.
USE AdventureWorks2012;
GO
DELETE FROM Purchasing.PurchaseOrderDetail
WHERE PurchaseOrderDetailID IN
(SELECT TOP 10 PurchaseOrderDetailID
FROM Purchasing.PurchaseOrderDetail
ORDER BY DueDate ASC);
GO
Deleting Rows From a Remote TableExamples in this section demonstrate how to delete rows from a remote table by using a linked server or a rowset function to reference the remote table. A remote table exists on a different server or instance of SQL Server. A.Deleting data from a remote table by using a linked serverThe following example deletes rows from a remote table. The example begins by creating a link to the remote data source by using sp_addlinkedserver. The linked server name, MyLinkServer, is then specified as part of the four-part object name in the form 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'AdventureWorks2012';
GO
-- Specify the remote data source using a four-part name
-- in the form linked_server.catalog.schema.object.
DELETE MyLinkServer.AdventureWorks2012.HumanResources.Department WHERE DepartmentID > 16;
GO
B.Deleting data from a remote table by using the OPENQUERY functionThe following example deletes rows from a remote table by specifying the OPENQUERY rowset function. The linked server name created in the previous example is used in this example.
DELETE OPENQUERY (MyLinkServer, 'SELECT Name, GroupName FROM AdventureWorks2012.HumanResources.Department
WHERE DepartmentID = 18');
GO
C.Deleting data from a remote table by using the OPENDATASOURCE functionThe following example deletes rows from a remote table by specifying the OPENDATASOURCE rowset function. Specify a valid server name for the data source by using the format server_name or server_name\instance_name.
DELETE FROM OPENDATASOURCE('SQLNCLI',
'Data Source= <server_name>; Integrated Security=SSPI')
.AdventureWorks2012.HumanResources.Department
WHERE DepartmentID = 17;'
Capturing the results of the DELETE statementA.Using DELETE with the OUTPUT clauseThe following example shows how to save the results of a DELETE statement to a table variable.
USE AdventureWorks2012;
GO
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
B.Using OUTPUT with <from_table_name> in a DELETE statementThe following example deletes rows in the ProductProductPhoto table based on search criteria defined in the FROM clause of the DELETE statement. The OUTPUT clause returns columns from the table being deleted, DELETED.ProductID, DELETED.ProductPhotoID, and columns from the Product table. This is used in the FROM clause to specify the rows to delete.
USE AdventureWorks2012;
GO
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

See Also
|
DELETE (Transact-SQL)

Sintaxis
[ 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
}

Argumentos
- WITH <common_table_expression>
Especifica el conjunto de resultados de nombre temporal, también conocido como expresión de tabla común, definido dentro del ámbito de la instrucción DELETE. El conjunto de resultados se deriva de una instrucción SELECT. Las expresiones de tabla comunes también se pueden utilizar con las instrucciones SELECT, INSERT, UPDATE y CREATE VIEW. Para obtener más información, vea WITH Common. - TOP (expression) [ PERCENT ]
Especifica el número o el porcentaje de filas aleatorias que se van a eliminar. expression puede ser un número o un porcentaje de las filas. Las filas a las que se hace referencia en la expresión TOP utilizada con INSERT, UPDATE o DELETE no se ordenan. Para obtener más información, vea TOP (Transact-SQL). - FROM
Palabra clave opcional que se puede usar entre la palabra clave DELETE y el destino table_or_view_name o rowset_function_limited. - table_alias
Alias especificado en la cláusula FROM table_source que representa la tabla o vista de la que se van a eliminar las filas. - server_name
Nombre del servidor (un nombre de servidor vinculado o la función OPENDATASOURCE como nombre de servidor) en el que se encuentra la tabla o la vista. Si se especifica server_name, son obligatorios database_name y schema_name. - database_name
El nombre de la base de datos. - schema_name
Nombre del esquema al que pertenece la tabla o la vista. - table_or view_name
Nombre de la tabla o vista cuyas filas se van a quitar. En este ámbito, se puede utilizar una variable de tabla como origen de tabla de una instrucción DELETE. La vista a la que hace referencia table_or_view_name debe poderse actualizar y debe hacer referencia exactamente a una tabla base de la cláusula FROM de la definición de vista. Para obtener más información acerca de las vistas que se pueden actualizar, vea CREATE VIEW (Transact-SQL). - rowset_function_limited
Función OPENQUERY u OPENROWSET, dependiendo del proveedor. - WITH ( <table_hint_limited> [... n] )
Especifica una o varias sugerencias de tabla que están permitidas en una tabla de destino. La palabra clave WITH y los paréntesis son obligatorios. No se permiten NOLOCK ni READUNCOMMITTED. Para obtener más información acerca de las sugerencias de tabla, vea Sugerencias de tabla (Transact-SQL). - <OUTPUT_Clause>
Devuelve filas eliminadas, o expresiones basadas en ellas, como parte de la operación DELETE. La cláusula OUTPUT no se admite en instrucciones DML dirigidas a tablas o vistas remotas. Para obtener más información, vea OUTPUT (cláusula de Transact-SQL). - FROM table_source
Especifica una cláusula FROM adicional. Esta extensión de Transact-SQL para DELETE permite especificar datos de <table_source> y eliminar las filas correspondientes de la tabla en la primera cláusula FROM. Se puede utilizar esta extensión, que especifica una combinación, en lugar de una subconsulta en la cláusula WHERE para identificar las filas que se van a quitar. Para obtener más información, vea FROM (Transact-SQL). - WHERE
Especifica las condiciones utilizadas para limitar el número de filas que se van a eliminar. Si no se proporciona una cláusula WHERE, DELETE quita todas las filas de la tabla. Hay dos formas de operaciones de eliminación, que se basan en las condiciones que se especifiquen en la cláusula WHERE: Las eliminaciones por búsqueda especifican una condición de búsqueda que califica las filas que se van a eliminar. Por ejemplo, WHERE column_name = value. Las eliminaciones por posición utilizan la cláusula CURRENT OF para especificar un cursor. La operación de eliminación se produce en la posición actual del cursor. Este método puede ser más preciso que una instrucción DELETE por búsqueda que utilice una cláusula WHERE search_condition para calificar las filas que se van a eliminar. Una instrucción DELETE por búsqueda elimina varias filas si la condición de búsqueda no identifica exclusivamente una única fila.
- <search_condition>
Especifica las condiciones restrictivas de las filas que se van a eliminar. No hay límite en el número de predicados que se pueden incluir en una condición de búsqueda. Para obtener más información, vea Condiciones de búsqueda (Transact-SQL). - CURRENT OF
Especifica que la instrucción DELETE se ejecutará en la posición actual del cursor especificado. - GLOBAL
Especifica que cursor_name hace referencia a un cursor global. - cursor_name
Es el nombre del cursor abierto desde el que se realiza la captura. Si hay un cursor global y otro local con el nombre cursor_name, este argumento hace referencia al cursor global si se especifica GLOBAL; de lo contrario, hace referencia al cursor local. El cursor debe permitir actualizaciones. - cursor_variable_name
Nombre de una variable de cursor. La variable de cursor debe hacer referencia a un cursor que permita realizar actualizaciones. - OPTION ( <query_hint> [ ,... n] )
Palabras clave que indican que se utilizan sugerencias del optimizador para personalizar el procesamiento de la instrucción por parte del Motor de base de datos. Para obtener más información, vea Sugerencias de consulta (Transact-SQL).

Prácticas recomendadas
Para eliminar todas las filas de una tabla, use TRUNCATE TABLE. TRUNCATE TABLE es más rápido que DELETE y utiliza menos recursos de los registros de transacciones y de sistema. Use la función @@ROWCOUNT para devolver el número de filas eliminadas a la aplicación cliente. Para obtener más información, vea @@ROWCOUNT (Transact-SQL).

Tratamiento de errores
Puede implementar el control de errores de la instrucción DELETE especificando la instrucción en una construcción TRY…CATCH. La instrucción DELETE puede tener un error si infringe un desencadenador o intenta quitar una fila a la que hacen referencia datos de otra tabla con una restricción FOREIGN KEY. Si la instrucción DELETE quita varias filas y cualquiera de las filas eliminadas infringe un desencadenador o restricción, se cancela la instrucción, se devuelve un error y no se elimina ninguna fila. Cuando una instrucción DELETE encuentra un error aritmético (desbordamiento, división entre cero o error de dominio) al evaluar una expresión, el Motor de base de datos trata ese error como si SET ARITHABORT fuese ON. Se cancela el resto del proceso por lotes y se devuelve un mensaje de error.

Interoperabilidad
Es posible utilizar DELETE en el cuerpo de una función definida por el usuario si el objeto que se va a modificar es una variable de tabla. Al eliminar una fila que contiene una columna FILESTREAM, también elimina los archivos del sistema de archivos subyacentes. El recolector de elementos no utilizados de FILESTREAM quita los archivos subyacentes. Para obtener más información, vea Obtener acceso a datos FILESTREAM con Transact-SQL. No se puede especificar la cláusula FROM en una instrucción DELETE que haga referencia, directa o indirectamente, a una vista que tiene definido un desencadenador INSTEAD OF. Para obtener más información acerca de los desencadenadores INSTEAD OF, vea CREATE TRIGGER (Transact-SQL).

Limitaciones y restricciones
Cuando se usa TOP con DELETE, las filas a las que hace referencia no están organizadas de ninguna manera y la cláusula ORDER BY no se puede especificar directamente en esta instrucción. Si necesita utilizar TOP para eliminar filas por un orden cronológico significativo, debe usar TOP junto con una cláusula ORDER BY en una instrucción de subselección. Vea la sección Ejemplos que aparece más adelante en este tema. TOP no se puede usar en una instrucción DELETE con vistas divididas en particiones.

Comportamiento del bloqueo
De forma predeterminada, una instrucción DELETE siempre adquiere un bloqueo exclusivo (X) en la tabla que modifica y retiene ese bloqueo hasta que se completa la transacción. Al utilizar un bloqueo exclusivo (X), el resto de las transacciones no pueden modificar los datos; las operaciones de lectura solo se pueden realizar si se utiliza la sugerencia NOLOCK o el nivel de aislamiento de lectura no confirmada. Puede especificar sugerencias de tabla para invalidar este comportamiento predeterminado durante la ejecución de la instrucción DELETE especificando otro método de bloqueo, sin embargo se recomienda que solo los desarrolladores y administradores de bases de datos experimentados usen las sugerencias y únicamente como último recurso. Para obtener más información, vea Sugerencias de tabla (Transact-SQL). Cuando se eliminan filas de un montón, Motor de base de datos puede usar bloqueo de filas o páginas para la operación. Como consecuencia, las páginas que han quedado vacías por la operación de eliminación permanecen asignadas al montón. Si no se cancela la asignación de las páginas vacías, otros objetos de la base de datos no pueden volver a utilizar el espacio asociado. Para eliminar las filas de un montón y cancelar la asignación de las páginas, use uno de los métodos siguientes. Especifique la sugerencia TABLOCK en la instrucción DELETE. Si se utiliza la sugerencia TABLOCK, la operación de eliminación aplica un bloqueo compartido a la tabla, en lugar de un bloqueo de fila o de página. Esto permite cancelar la asignación de las páginas. Para obtener más información acerca de la sugerencia TABLOCK, vea Sugerencias de tabla (Transact-SQL). Se debe utilizar TRUNCATE TABLE si se van a eliminar todas las filas de la tabla. Cree un índice clúster en el montón antes de eliminar las filas. Puede quitar el índice clúster tras eliminar las filas. Este método requiere más tiempo que los métodos anteriores y utiliza más recursos temporales.

Comportamiento del registro
La instrucción DELETE siempre está registrada totalmente.

Seguridad
PermisosSe requieren permisos DELETE en la tabla de destino. También se requieren los permisos para utilizar SELECT si la instrucción contiene una cláusula WHERE. Los permisos para utilizar DELETE corresponden de forma predeterminada a los miembros del rol fijo de servidor sysadmin, de los roles fijos de base de datos db_owner y db_datawriter y al propietario de la tabla. Los miembros de los roles sysadmin, db_owner y db_securityadmin y el propietario de la tabla pueden transferir permisos a otros usuarios.

Ejemplos
Sintaxis básicaEn los ejemplos de esta sección se muestra la funcionalidad básica de la instrucción DELETE usando la sintaxis mínima requerida. A.Utilizar DELETE sin la cláusula WHEREEn el ejemplo siguiente se eliminan todas las filas de la tabla SalesPersonQuotaHistory porque no se utiliza una cláusula WHERE para limitar el número de filas eliminadas.
USE AdventureWorks2012;
GO
DELETE FROM Sales.SalesPersonQuotaHistory;
GO
Limitar las filas eliminadasEn los ejemplos de esta sección se muestra cómo se limita el número de filas que se van a eliminar. A.Usar la cláusula WHERE para eliminar un conjunto de filasEn el ejemplo siguiente se eliminan todas las filas de la tabla ProductCostHistory en las que el valor de la columna StandardCost es superior a 1000.00.
USE AdventureWorks2012;
GO
DELETE FROM Production.ProductCostHistory
WHERE StandardCost > 1000.00;
GO
En el siguiente ejemplo se muestra una cláusula WHERE más compleja. La cláusula WHERE define dos condiciones que deben cumplirse para determinar las filas que se van a eliminar. El valor de la columna StandardCost debe estar comprendido entre 12.00 y 14.00 y el valor de la columna SellEndDate debe ser NULL. En el ejemplo se imprime también el valor desde la función @@ROWCOUNT para devolver el número de filas eliminadas.
USE AdventureWorks2012;
GO
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));
B.Usar un cursor para determinar la fila que se va a eliminarEn el ejemplo siguiente se elimina una fila única de la tabla EmployeePayHistory mediante un cursor denominado my_cursor. La operación de eliminación solo afecta a la única fila que se captura actualmente del cursor.
USE AdventureWorks2012;
GO
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
C.Usar combinaciones y subconsultas en los datos de una tabla para eliminar filas de otra tablaEn los siguientes ejemplos se muestran dos maneras de eliminar filas de una tabla en función de los datos de otra tabla. En ambos ejemplos, se eliminan las filas de la tabla SalesPersonQuotaHistory basándose en las ventas del año hasta la fecha almacenadas en la tabla SalesPerson. La primera instrucción DELETE muestra la solución de subconsulta compatible con ISO y la segunda instrucción DELETE muestra la extensión de FROM de Transact-SQL para unir las dos tablas.
-- SQL-2003 Standard subquery
USE AdventureWorks2012;
GO
DELETE FROM Sales.SalesPersonQuotaHistory
WHERE BusinessEntityID IN
(SELECT BusinessEntityID
FROM Sales.SalesPerson
WHERE SalesYTD > 2500000.00);
GO
-- Transact-SQL extension
USE AdventureWorks2012;
GO
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
A.Utilizar TOP para limitar el número de filas eliminadasCuando se utiliza una cláusula TOP (n) con DELETE, la operación de eliminación se realiza en una selección aleatoria de n número de filas. En el ejemplo siguiente se eliminan 20 filas aleatorias de la tabla PurchaseOrderDetail cuyas fechas de vencimiento sean anteriores al primero de julio de 2006.
USE AdventureWorks2012;
GO
DELETE TOP (20)
FROM Purchasing.PurchaseOrderDetail
WHERE DueDate < '20020701';
GO
Si necesita utilizar TOP para eliminar filas por un orden cronológico significativo, debe utilizarla junto con ORDER BY en una instrucción de subselección. La siguiente consulta elimina de la tabla PurchaseOrderDetail las 10 filas con las fechas de vencimiento más antiguas. Para garantizar que solo se eliminen 10 filas, la columna especificada en la instrucción de subselección (PurchaseOrderID) es la clave principal de la tabla. El uso de una columna sin clave en la instrucción de subselección podría causar la eliminación de más de 10 filas si la columna especificada contiene valores duplicados.
USE AdventureWorks2012;
GO
DELETE FROM Purchasing.PurchaseOrderDetail
WHERE PurchaseOrderDetailID IN
(SELECT TOP 10 PurchaseOrderDetailID
FROM Purchasing.PurchaseOrderDetail
ORDER BY DueDate ASC);
GO
Eliminar filas de una tabla remotaEn los ejemplos de esta sección se muestra cómo se eliminan filas de una tabla remota mediante un servidor vinculado o una función de conjunto de filas para hacer referencia a la tabla remota. Una tabla remota existe en un servidor o instancia diferente de SQL Server. A.Eliminar datos de una tabla remota usando un servidor vinculadoEn el ejemplo siguiente se eliminan filas de una tabla remota. En el ejemplo se comienza creando un vínculo al origen de datos remoto mediante sp_addlinkedserver. El nombre del servidor vinculado, MyLinkServer, se especifica entonces como parte del nombre de objeto de cuatro partes en el formato 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'AdventureWorks2012';
GO
-- Specify the remote data source using a four-part name
-- in the form linked_server.catalog.schema.object.
DELETE MyLinkServer.AdventureWorks2012.HumanResources.Department WHERE DepartmentID > 16;
GO
B.Eliminar datos de una tabla remota con la función OPENQUERYEn el ejemplo siguiente se eliminan filas de una tabla remota especificando la función de conjunto de filas OPENQUERY. En este ejemplo se usa el nombre del servidor vinculado creado en el ejemplo anterior.
DELETE OPENQUERY (MyLinkServer, 'SELECT Name, GroupName FROM AdventureWorks2012.HumanResources.Department
WHERE DepartmentID = 18');
GO
C.Eliminar datos de una tabla remota con una función OPENDATASOURCEEn el ejemplo siguiente se elimina una fila de una tabla remota especificando la función de conjunto de filas OPENDATASOURCE. Especifique un nombre de servidor válido para el origen de datos con el formato server_name o server_name\instance_name.
DELETE FROM OPENDATASOURCE('SQLNCLI',
'Data Source= <server_name>; Integrated Security=SSPI')
.AdventureWorks2012.HumanResources.Department
WHERE DepartmentID = 17;'
Capturar los resultados de la instrucción DELETEA.Usar DELETE con la cláusula OUTPUTEn el ejemplo siguiente se muestra cómo se guardan los resultados de una instrucción DELETE en una variable de tabla.
USE AdventureWorks2012;
GO
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
B.Usar OUTPUT con <from_table_name> en una instrucción DELETEEn el ejemplo siguiente se eliminan las filas de la tabla ProductProductPhoto según los criterios de búsqueda definidos en la cláusula FROM de la instrucción DELETE. La cláusula OUTPUT devuelve columnas de la tabla que se elimina (DELETED.ProductID, DELETED.ProductPhotoID) y de la tabla Product. Esta información se utiliza en la cláusula FROM para especificar las filas que se deben eliminar.
USE AdventureWorks2012;
GO
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

Vea también
|