UPDATE authors
SET authors.au_fname = 'Annie'
WHERE au_fname = 'Anne'
FROM 子句中指定的表的别名不能作为 SET column_name 子句中的限定符使用。例如,下面的内容无效:
UPDATE titles
SET t.ytd_sales = t.ytd_sales + s.qty
FROM titles t, sales s
WHERE t.title_id = s.title_id
AND s.ord_date = (SELECT MAX(sales.ord_date) FROM sales)
若要使上例合法,请从列名中删除别名 t。
UPDATE titles
SET ytd_sales = t.ytd_sales + s.qty
FROM titles t, sales s
WHERE t.title_id = s.title_id
AND s.ord_date = (SELECT MAX(sales.ord_date) FROM sales)
SET @variable = column = expression 将变量设置为与列相同的值。这与 SET @variable = column, column = expression 不同,后者将变量设置为列更新前的值。
FROM < table_source >
指定用表来为更新操作提供准则。有关更多信息,请参见 FROM。
table_name [[AS] table_alias ]
为更新操作提供准则的表的名称。
如果所更新表与 FROM 子句中的表相同,并且在 FROM 子句中对该表只有一个引用,则指定或不指定 table_alias 均可。如果所更新表在 FROM 子句中出现了不止一次,则对该表的一个(且仅仅一个)引用不能指定表的别名。FROM 子句中对该表的所有其它引用都必须包含表的别名。
view_name [ [ AS ] table_alias ]
为更新操作提供准则的视图的名称。带 INSTEAD OF UPDATE 触发器的视图不能是含有 FROM 子句的 UPDATE 的目标。
WITH ( < table_hint > [ ...n ] )
为源表指定一个或多个表提示。有关表提示的信息,请参见本卷的"FROM"。
{ MERGE | HASH | CONCAT } UNION
指定所有的 UNION 操作通过合并、哈希或串联 UNION 集合来完成。如果指定了不止一个 UNION 提示,查询优化器就会从这些指定的提示中选择开销最少的策略。
说明 如果在 FROM 子句中亦为任何特定联接表对指定了联接提示,则该提示优先于任何 OPTION 子句中指定的联接提示。
FAST number_rows
指定对查询进行优化,以便快速检索第一个 number_rows(非负整数)。在第一个 number_rows 返回后,查询继续进行并生成完整的结果集。
FORCE ORDER
指定查询语法所指示的联接顺序在查询优化过程中予以保留。
MAXDOP number
只对指定了 sp_configure 的 max degree of parallelism 配置选项的查询替代该选项。当使用 MAXDOP 查询提示时,所有和 max degree of parallelism 配置选项一起使用的语义规则均适用。有关更多信息,请参见 max degree of parallelism 选项。
ROBUST PLAN
强制查询优化器尝试执行一个计划,该计划以性能为代价获得最大可能的行大小。如果没有可行的计划,则查询优化器返回错误,而不是将错误检测延迟至查询执行。行可能包含长度可变的列;SQL Server 允许定义最大可能大小超出 SQL Server 处理能力的行。通常,应用程序存储实际大小在 SQL Server 处理能力范围内的行,而不管最大可能大小。如果 SQL Server 遇到过长的行,则返回执行错误。
KEEP PLAN
强制查询优化器对查询放宽估计的重新编译阈值。当对表中索引列的更改(更新、删除或插入)达到估计数目时查询会自动重新编译,该估计数目即为重新编译阈值。指定 KEEP PLAN 将确保当表有多个更新时不会频繁地对查询进行重新编译。
对于用于远程表以及本地和远程分区视图的 UPDATE 语句,忽略 SET ROWCOUNT 选项的设置。
如果 ANSI_PADDING 设置为 OFF,则会从插入 varchar 和 nvarchar 列的数据中删除所有尾随空格,但只包含空格的字符串除外。这些字符串被截断为空字符串。如果 ANSI_PADDING 设置为 ON,则插入尾随空格。Microsoft SQL Server ODBC 驱动程序和用于 SQL Server 的 OLE DB 提供程序自动对每个连接设置 ANSI_PADDING ON。这可在 ODBC 数据源中进行配置,或者通过设置连接特性或属性进行设置。
使用 WHERE CURRENT OF 子句的定位更新将在游标的当前位置更新单行。这比使用 WHERE <search_condition> 子句限定要更新的行的搜索更新更为精确。当搜索条件不唯一标识一行时,搜索更新将修改多行。
如果 UPDATE 语句包含了未指定每个所更新列的位置只有一个可用值的 FROM 子句(换句话说,如果 UPDATE 语句是不确定性的),则其结果将不明确。例如,对于下面脚本中的 UPDATE 语句,表 s 中的两行都满足 UPDATE 语句中的 FROM 子句的限定条件,但是将用 s 的哪一行来更新表 t 内的行是不明确的。
CREATE TABLE s (ColA INT, ColB DECIMAL(10,3))
GO
CREATE TABLE t (ColA INT PRIMARY KEY, ColB DECIMAL(10,3))
GO
INSERT INTO s VALUES(1, 10.0)
INSERT INTO s VALUES(1, 20.0)
INSERT INTO t VALUES(1, 0.0)
GO
UPDATE t
SET t.ColB = t.ColB + s.ColB
FROM t INNER JOIN s ON (t.ColA = s.ColA)
GO
当组合 FROM 和 WHERE CURRENT OF 子句时,可能发生同样的问题。在本例中,表 t2 中的两行都满足 UPDATE 语句中的 FROM 子句的限定条件。将用表 t2 的哪一行来更新表 t1 中的行是不明确的。
CREATE TABLE t1(c1 INT PRIMARY KEY, c2 INT)
GO
CREATE TABLE t2(d1 INT PRIMARY KEY, d2 INT)
GO
INSERT INTO t1 VALUES (1, 10)
INSERT INTO t2 VALUES (1, 20)
INSERT INTO t2 VALUES (2, 30)
go
DECLARE abc CURSOR LOCAL FOR
SELECT * FROM t1
OPEN abc
FETCH abc
UPDATE t1 SET c2 = c2 + d2
FROM t2
WHERE CURRENT OF abc
GO
UPDATE publishers
SET city = 'Atlanta', state = 'GA'
本示例将所有出版商的名字变为 NULL。
UPDATE publishers
SET pub_name = NULL
也可以在更新中使用计算值。本示例将表 titles 中的所有价格加倍。
UPDATE titles
SET price = price * 2
B.把 WHERE 子句和 UPDATE 语句一起使用
WHERE 子句指定要更新的行例如,在下面这个虚构的事件中,北加利福尼亚更名为 Pacifica(缩写为 PC),而奥克兰的市民投票决定将其城市的名字改为 Bay City。这个例子说明如何为奥克兰市以前的所有居民(他们的地址已经过时)更新表 authors。
UPDATE authors
SET state = 'PC', city = 'Bay City'
WHERE state = 'CA' AND city = 'Oakland'
UPDATE titles
SET ytd_sales = titles.ytd_sales + sales.qty
FROM titles, sales
WHERE titles.title_id = sales.title_id
AND sales.ord_date = (SELECT MAX(sales.ord_date) FROM sales)
UPDATE titles
SET ytd_sales =
(SELECT SUM(qty)
FROM sales
WHERE sales.title_id = titles.title_id
AND sales.ord_date IN (SELECT MAX(ord_date) FROM sales))
FROM titles, sales
D. 将 UPDATE 语句与 SELECT 语句中的 TOP 子句一起使用
这个例子对来自表 authors 的前十个作者的 state 列进行更新。
UPDATE authors
SET state = 'ZZ'
FROM (SELECT TOP 10 * FROM authors ORDER BY au_lname) AS t1
WHERE authors.au_id = t1.au_id
指定两个表的矢量积。这将返回相同的行,就好像在旧式的非 SQL-92 式联接中并没有指定 WHERE 子句。
WHERE
指定用于限制删除行数的条件。如果没有提供 WHERE 子句,则 DELETE 删除表中的所有行。基于 WHERE 子句中所指定的条件,有两种形式的删除操作。
搜索删除指定搜索条件限定删除的行。
定位删除使用 CURRENT OF 子句指定游标。删除操作在游标的当前位置发生。这比使用 WHERE search_condition 子句限定删除的行的搜索 DELETE 精确。如果搜索条件不唯一标识单行,则搜索 DELETE 删除多行。
<search_condition>
指定删除行的限定条件。对搜索条件中可以包含的谓词数量没有限制。有关更多信息,请参见搜索条件。
{HASH | ORDER} GROUP
指定在查询的 GROUP BY 或 COMPUTE 子句中指定的聚合使用哈希或排列。
{MERGE | HASH | CONCAT} UNION
指定所有的 UNION 操作通过合并、哈希或串联 UNION 集合来完成。如果指定了不止一个 UNION 提示,查询优化器就会从这些指定的提示中选择开销最少的策略。
说明 如果还为 FROM 子句中的某对链接表指定了 <joint_hint>,则这个提示优先于 OPTION 子句中所指定的任何 <join_hint>。
FAST number_rows
指定对查询进行优化,以便快速检索第一个 number_rows(非负整数)。在第一个 number_rows 返回后,查询继续进行并生成完整的结果集。
FORCE ORDER
指定在查询优化过程中保持由查询语法表示的联接顺序。
MAXDOP number
只对指定了 sp_configure 的 max degree of parallelism 配置选项的查询替代该选项。当使用 MAXDOP 查询提示时,所有和 max degree of parallelism 配置选项一起使用的语义规则均适用。有关更多信息,请参见 max degree of parallelism 选项。
ROBUST PLAN
强制查询优化器尝试执行一个计划,该计划以性能为代价获得最大可能的行大小。如果不能使用这样的计划,查询优化器将返回错误而不是延迟对查询执行的错误检测。行可以包含可变长度列;SQL Server 允许将行大小定义为超过 SQL Server 处理能力的最大可能的大小。通常,应用程序存储实际大小在 SQL Server 处理能力范围内的行,而不管最大可能大小。如果 SQL Server 遇到过长的行,则返回执行错误。
KEEP PLAN
强制查询优化器对查询放宽估计的重新编译阈值。当对表中索引列的更改(更新、删除或插入)达到估计数目时查询会自动重新编译,该估计数目即为重新编译阈值。指定 KEEP PLAN 将确保当表有多个更新时不会频繁地对查询进行重新编译。
/* SQL-92-Standard subquery */
USE pubs
DELETE FROM titleauthor
WHERE title_id IN
(SELECT title_id
FROM titles
WHERE title LIKE '%computers%')
/* Transact-SQL extension */
USE pubs
DELETE titleauthor
FROM titleauthor INNER JOIN titles
ON titleauthor.title_id = titles.title_id
WHERE titles.title LIKE '%computers%'
E. 在 DELETE 和 SELECT 中使用 TOP 子句
由于可以在 DELETE 语句中指定 SELECT 语句,因此还可以在 SELECT 语句中使用 TOP 子句。例如,下例从 authors 表中删除前 10 个作者。
DELETE authors
FROM (SELECT TOP 10 * FROM authors) AS t1
WHERE authors.au_id = t1.au_id
<query_hint> ::=
{ { HASH | ORDER } GROUP
| { CONCAT | HASH | MERGE } UNION
| {LOOP | MERGE | HASH} JOIN
| FAST number_rows
| FORCE ORDER
| MAXDOP
| ROBUST PLAN
| KEEP PLAN
}
Arguments
table_name
Is the name of the table to update. The name can be qualified with the linked server, database, and owner name if the table is not in the current server or database, or is not owned by the current user.
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. READPAST, NOLOCK, READUNCOMMITTED, and UPDLOCK are not allowed. For information about table hints, see FROM.
view_name
Is the name of the view to update. The view referenced by view_name must be updatable. The modifications made by the UPDATE statement cannot affect more than one of the base tables referenced in the FROM clause of the view. For more information on updatable views, see CREATE VIEW.
rowset_function_limited
Is either the OPENQUERY or OPENROWSET function, subject to provider capabilities. For more information about capabilities needed by the provider, see UPDATE and DELETE Requirements for OLE DB Providers. For more information about the rowset functions, see OPENQUERY and OPENROWSET.
SET
Specifies the list of column or variable names to be updated.
column_name
Is a column that contains the data to be changed. column_name must reside in the table or view specified in the UPDATE clause. Identity columns cannot be updated.
If a qualified column name is specified, the qualifier must match the table or view name in the UPDATE clause. For example, this is valid:
UPDATE authors
SET authors.au_fname = 'Annie'
WHERE au_fname = 'Anne'
A table alias specified in a FROM clause cannot be used as a qualifier in SET
column_name. For example, this is not valid:
UPDATE titles
SET t.ytd_sales = t.ytd_sales + s.qty
FROM titles t, sales s
WHERE t.title_id = s.title_id
AND s.ord_date = (SELECT MAX(sales.ord_date) FROM sales)
To make the example work, remove the t. alias from the column name.
UPDATE titles
SET ytd_sales = t.ytd_sales + s.qty
FROM titles t, sales s
WHERE t.title_id = s.title_id
AND s.ord_date = (SELECT MAX(sales.ord_date) FROM sales)
expression
Is a variable, literal value, expression, or a parenthesized subSELECT statement that returns a single value. The value returned by expression replaces the existing value in column_name or @variable.
DEFAULT
Specifies that the default value defined for the column is to replace the existing value in the column. This can also be used to change the column to NULL if the column has no default and is defined to allow null values.
@variable
Is a declared variable that is set to the value returned by expression.
SET @variable = column = expression sets the variable to the same value as the column. This differs from SET @variable = column, column = expression, which sets the variable to the pre-update value of the column.
FROM <table_source>
Specifies that a table is used to provide the criteria for the update operation. For more information, see FROM.
table_name [[AS] table_alias ]
Is the name of a table to provide criteria for the update operation.
If the table being updated is the same as the table in the FROM clause, and there is only one reference to the table in the FROM clause, table_alias
may or may not be specified. If the table being updated appears more than one time in the FROM clause, one (and only one) reference to the table must not specify a table alias. All other references to the table in the FROM clause must include a table alias.
view_name [ [AS] table_alias ]
Is the name of a view to provide criteria for the update operation.
WITH (<table_hint> [...n])
Specifies one or more table hints for a source table. For information about table hints, see FROM.
rowset_function [ [AS] table_alias ]
Is the name of any rowset function and an optional alias. For information about a list of rowset functions, see Rowset Functions.
derived_table
Is a subquery that retrieves rows from the database. derived_table is used as input to the outer query.
column_alias
Is an optional alias to replace a column name in the result set. Include one column alias for each column in the select list, and enclose the entire list of column aliases in parentheses.
<joined_table>
Is a result set that is the product of two or more tables, for example:
FROM tab1 LEFT OUTER JOIN tab1.c3 = tab2.c3
RIGHT OUTER JOIN tab3 LEFT OUTER JOIN tab4
ON tab3.c1
ON tab2.c3 = tab4.c3
For multiple CROSS joins, use parentheses to change the natural order of the joins.
<join_type>
Specifies the type of join operation.
INNER
Specifies that all matching pairs of rows are returned. Discards unmatched rows from both tables. This is the default if no join type is specified.
LEFT [OUTER]
Specifies that all rows from the left table not meeting the specified condition are included in the result set in addition to all rows returned by the inner join. Output columns from the left table are set to NULL.
RIGHT [OUTER]
Specifies that all rows from the right table not meeting the specified condition are included in the result set in addition to all rows returned by the inner join. Output columns from the right table are set to NULL.
FULL [OUTER]
If a row from either the left or right table does not match the selection criteria, specifies the row be included in the result set, and output columns that correspond to the other table be set to NULL. This is in addition to all rows usually returned by the inner join.
<join_hint>
Specifies a join hint or execution algorithm. If <join_hint> is specified, INNER, LEFT, RIGHT, or FULL must also be explicitly specified. For more information about joint hints, see FROM.
JOIN
Indicates that the specified tables or views should be joined.
ON <search_condition>
Specifies the condition on which the join is based. The condition can specify any predicate, although columns and comparison operators are often used, for example:
FROM Suppliers JOIN Products
ON (Suppliers.SupplierID = Products.SupplierID)
When the condition specifies columns, the columns do not have to have the same name or same data type; however, if the data types are not identical, they must be either compatible or types that Microsoft?SQL Server?can implicitly convert. If the data types cannot be implicitly converted, the condition must explicitly convert the data type using the CAST function.
For more information about search conditions and predicates, see Search Condition.
CROSS JOIN
Specifies the cross-product of two tables. Returns the same rows as if the tables to be joined were simply listed in the FROM clause and no WHERE clause was specified.
WHERE
Specifies the conditions that limit the rows that are updated. There are two forms of update based on which form of the WHERE clause is used:
?Searched updates specify a search condition to qualify the rows to delete.
?Positioned updates use the CURRENT OF clause to specify a cursor. The update operation occurs at the current position of the cursor.
<search_condition>
Specifies the condition to be met for the rows to be updated. The search condition can also be the condition upon which a join is based. There is no limit to the number of predicates that can be included in a search condition. For more information about predicates and search conditions, see Search Condition.
CURRENT OF
Specifies that the update 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 should be made. If both a global and a local cursor exist with cursor_name as their name, cursor_name refers to the global cursor if GLOBAL is specified. If GLOBAL is not specified,
cursor_name refers to the local cursor. The cursor must allow updates.
cursor_variable_name
Is the name of a cursor variable. cursor_variable_name must reference a cursor that allows updates.
OPTION (<query_hint> [,...n] )
Specifies that optimizer hints are used to customize SQL Server抯 processing of the statement.
{HASH | ORDER} GROUP
Specifies that the aggregations specified in the GROUP BY or COMPUTE clause of the query should use hashing or ordering.
{LOOP | MERGE | HASH |} JOIN
Specifies that all join operations are performed by loop join, merge join, or hash join in the whole query. If more than one join hint is specified, the query optimizer selects the least expensive join strategy for the allowed ones. If, in the same query, a join hint is also specified for a specific pair of tables, it takes precedence in the joining of the two tables.
{MERGE | HASH | CONCAT} UNION
Specifies that all UNION operations should be performed by merging, hashing, or concatenating UNION sets. If more than one UNION hint is specified, the query optimizer selects the least expensive strategy from those hints specified.
Note If a join hint is also specified for any particular pair of joined tables in the FROM clause, it takes precedence over any join hint specified in the OPTION clause.
FAST number_rows
Specifies that the query is optimized for fast retrieval of the first number_rows (a nonnegative integer). After the first number_rows are returned, the query continues execution and produces its full result set.
FORCE ORDER
Specifies that the join order indicated by the query syntax should be preserved during query optimization.
MAXDOP number
Overrides the max degree of parallelism configuration option (of sp_configure) only for the query specifying this option. All semantic rules used with max degree of parallelism configuration option are applicable when using the MAXDOP query hint. For more information, see max degree of parallelism Option.
ROBUST PLAN
Forces the query optimizer to attempt a plan that works for the maximum potential row size at the expense of performance. If no such plan is possible, the query optimizer returns an error rather than deferring error detection to query execution. Rows may contain variable-length columns; SQL Server allows rows to be defined whose maximum potential size is beyond the ability of SQL Server to process. Usually, despite the maximum potential size, an application stores rows that have actual sizes within the limits that SQL Server can process. If SQL Server encounters a row that is too long, an execution error is returned.
KEEP PLAN
Forces the query optimizer to relax the estimated recompile threshold for a query. The estimated recompile threshold is the point at which a query is automatically recompiled when the estimated number of indexed column changes (update, delete or insert) have been made to a table. Specifying KEEP PLAN ensures that a query will not be recompiled as frequently when there are multiple updates to a table.
Remarks
If an update to a row violates a constraint or rule, if it violates the NULL setting for the column, or if the new value is an incompatible data type, the statement is canceled, an error is returned, and no records are updated.
When an UPDATE statement encounters an arithmetic error (overflow, divide by zero, or a domain error) during expression evaluation the update is not performed. The remainder of the batch is not executed, and an error message is returned.
If an update to a column or columns participating in a clustered index causes the size of the clustered index and the row to exceed 8,060 bytes, the update fails and an error message is returned.
If an update query could alter more than one row while updating both the clustering key and one or more text, image, or Unicode columns, the update operation fails and SQL Server returns an error message.
Modifying a text, ntext, or image column with UPDATE initializes the column, assigns a valid text pointer to it, and allocates at least one data page unless updating the column with NULL.
Note The UPDATE statement is logged. If you are replacing or modifying large blocks of text, ntext, or image data, use the WRITETEXT or UPDATETEXT statement instead of the UPDATE statement. The WRITETEXT and UPDATETEXT statements (by default) are not logged.
All char and nchar columns are right-padded to the defined length.
If ANSI_PADDING is set OFF, all trailing spaces are removed from data inserted into varchar and nvarchar columns, except in strings containing only spaces. These strings are truncated to an empty string. If ANSI_PADDING is set ON, trailing spaces are inserted. The Microsoft SQL Server ODBC driver and OLE DB Provider for SQL Server automatically set ANSI_PADDING ON for each connection. This can be configured in ODBC data sources or by setting connection attributes or properties.
A positioned update using a WHERE CURRENT OF clause updates the single row at the current position of the cursor. This can be more accurate than a searched update that uses a WHERE <search_condition> clause to qualify the rows to be updated. A searched update modifies multiple rows when the search condition does not uniquely identify a single row.
The results of an UPDATE statement are undefined if the statement includes a FROM clause that is not specified in such a way that only one value is available for each column occurrence that is updated (in other words, if the UPDATE statement is not deterministic). For example, given the UPDATE statement in the following script, both rows in table s meet the qualifications of the FROM clause in the UPDATE statement, but it is undefined which row from s is used to update the row in table t.
CREATE TABLE s (ColA INT, ColB DECIMAL(10,3))
GO
CREATE TABLE t (ColA INT PRIMARY KEY, ColB DECIMAL(10,3))
GO
INSERT INTO s VALUES(1, 10.0)
INSERT INTO s VALUES(1, 20.0)
INSERT INTO t VALUES(1, 0.0)
GO
UPDATE t
SET t.ColB = t.ColB + s.ColB
FROM t INNER JOIN s ON (t.ColA = s.ColA)
GO
The same problem can occur when combining the FROM and WHERE CURRENT OF clauses. In this example, both rows in table t2 meet the qualifications of the FROM clause in the UPDATE statement. It is undefined which row from t2 is to be used to update the row in table t1.
CREATE TABLE t1(c1 INT PRIMARY KEY, c2 INT)
GO
CREATE TABLE t2(d1 INT PRIMARY KEY, d2 INT)
GO
INSERT INTO t1 VALUES (1, 10)
INSERT INTO t2 VALUES (1, 20)
INSERT INTO t2 VALUES (2, 30)
go
DECLARE abc CURSOR LOCAL FOR
SELECT * FROM t1
OPEN abc
FETCH abc
UPDATE t1 SET c2 = c2 + d2
FROM t2
WHERE CURRENT OF abc
GO
Setting Variables and Columns
Variable names can be used in UPDATE statements to show the old and new values affected. This should only be used when the UPDATE statement affects a single record; if the UPDATE statement affects multiple records, the variables only contain the values for one of the updated rows.
Permissions
UPDATE permissions default to members of the sysadmin fixed server role, the
db_owner fixed database role, and the table owner, who can transfer permissions to other users. SELECT permissions are also required for the table being updated if the UPDATE statement contains a WHERE clause, or if expression in the SET clause uses a column in the table.
Examples
A. Use a simple UPDATE
These examples show how all rows can be affected if a WHERE clause is eliminated from an UPDATE statement.
If all the publishing houses in the publishers table move their head offices to Atlanta, Georgia, this example shows how the publishers table can updated.
UPDATE publishers
SET city = 'Atlanta', state = 'GA'
This example changes the names of all the publishers to NULL.
UPDATE publishers
SET pub_name = NULL
You can also use computed values in an update. This example doubles all prices in the titles table.
UPDATE titles
SET price = price * 2
B. Use the UPDATE statement with a WHERE clause
The WHERE clause specifies the rows to update. For example, in the unlikely event that northern California is renamed Pacifica (abbreviated PC) and the people of Oakland vote to change the name of their city to Bay City. This example shows how to update the authors table for all former Oakland residents whose addresses are now out of date.
UPDATE authors
SET state = 'PC', city = 'Bay City'
WHERE state = 'CA' AND city = 'Oakland'
You must write another statement to change the name of the state for residents of other northern California cities.
C. Use the UPDATE statement using information from another table
This example modifies the ytd_sales column in the titles table to reflect the most recent sales recorded in the sales table.
UPDATE titles
SET ytd_sales = titles.ytd_sales + sales.qty
FROM titles, sales
WHERE titles.title_id = sales.title_id
AND sales.ord_date = (SELECT MAX(sales.ord_date) FROM sales)
This example assumes that only one set of sales is recorded for a given title on a given date and that updates are current. If this is not the case (if more than one sale for a given title can be recorded on the same day), the example shown here does not work correctly. It executes without error, but each title is updated with only one sale, regardless of how many sales actually occurred on that day. This is because a single UPDATE statement never updates the same row twice.
In the situation in which more than one sale for a given title can occur on the same day, all the sales for each title must be aggregated together within the UPDATE statement, as shown in this example:
UPDATE titles
SET ytd_sales =
(SELECT SUM(qty)
FROM sales
WHERE sales.title_id = titles.title_id
AND sales.ord_date IN (SELECT MAX(ord_date) FROM sales))
FROM titles, sales
D. Use UPDATE with the TOP clause in a SELECT statement
This example updates the state column for the first 10 authors from the authors
table.
UPDATE authors
SET state = 'ZZ'
FROM (SELECT TOP 10 * FROM authors ORDER BY au_lname) AS t1
<query_hint> ::=
{ { HASH | ORDER } GROUP
| { CONCAT | HASH | MERGE } UNION
| FAST number_rows
| FORCE ORDER
| MAXDOP
| ROBUST PLAN
| KEEP PLAN
}
Arguments
FROM
Is an optional keyword that can be used between the DELETE keyword and the target table_name, view_name, or rowset_function_limited.
table_name
Is the name of the table from which the rows are to be removed.
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. READPAST, NOLOCK, READUNCOMMITTED, and UPDLOCK are not allowed. For information about table hints, see FROM.
view_name
Is the name of a view. The view referenced by view_name must be updatable and reference exactly one base table in the FROM clause of the view. For more information on updatable views, see CREATE VIEW.
Note If the table or view exists in another database or has an owner other than the current user, use a four-part qualified name in the format server_name
.database.[owner].object_name. For more information, see Transact-SQL Syntax Conventions.
rowset_function_limited
Is either the OPENQUERY or OPENROWSET function, subject to provider capabilities. For more information about capabilities needed by the provider, see UPDATE and DELETE Requirements for OLE DB Providers. For more information about the rowset functions, see OPENQUERY and
OPENROWSET.
FROM <table_source>
Specifies an additional FROM clause. This Transact-SQL extension to DELETE allows you to specify data from <table_sources> and delete 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.
table_name [[AS] table_alias ]
Is the name of the table to provide criteria values for the delete operation.
view_name [ [AS] table_alias ]
Is the name of the view to provide criteria values for the delete operation.
WITH (<table_hint>
Specifies one or more table hints. For more information about table hints, see FROM.
rowset_function [ [AS] table_alias ]
Is the name of a rowset function and an optional alias. For more information about a list of rowset functions, see Rowset Functions.
derived_table [AS] table_alias
Is a subquery that retrieves rows from the database. derived_table is used as input to the outer query.
column_alias
Is an optional alias to replace a column name in the result set. Include one column alias for each column in the select list, and enclose the entire list of column aliases in parentheses.
<joined_table>
Is a result set that is the product of two or more tables, for example:
FROM tab1 LEFT OUTER JOIN tab1.c3 = tab2.c3
RIGHT OUTER JOIN tab3 LEFT OUTER JOIN tab4
ON tab3.c1
ON tab2.c3 = tab4.c3
For multiple CROSS joins, use parentheses to change the natural order of the joins.
<join_type>
Specifies the type of join operation.
INNER
Specifies all matching pairs of rows are returned. Discards unmatched rows from both tables. This is the default if no join type is specified.
LEFT [OUTER]
Specifies that all rows from the left table not meeting the specified condition are included in the result set, and output columns from the right table are set to NULL in addition to all rows returned by the inner join.
RIGHT [OUTER]
Specifies that all rows from the right table not meeting the specified condition are included in the result set, and output columns from the left table are set to NULL in addition to all rows returned by the inner join.
FULL [OUTER]
If a row from either the left or right table does not match the selection criteria, specifies the row be included in the result set, and output columns that correspond to the other table be set to NULL. This is in addition to all rows usually returned by the inner join.
JOIN
Is a keyword to indicate that an SQL-92 style join be used in the delete operation.
ON <search_condition>
Specifies the condition on which the join is based. The condition can specify any predicate, although columns and comparison operators are often used, for example:
FROM Suppliers JOIN Products
ON (Suppliers.SupplierID = Products.SupplierID)
When the condition specifies columns, they need not have the same name or same data type; however, if the data types are not identical, they must be either compatible or types that Microsoft?SQL Server?can implicitly convert. If the data types cannot be implicitly converted, the condition must explicitly convert the data type using the CAST function.
For more information about search conditions and predicates, see Search Condition.
CROSS JOIN
Specifies the cross-product of two tables. Returns the same rows as if no WHERE clause was specified in an old-style, non-SQL-92-style join.
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.
?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 that uses a WHERE search_condition clause to qualify the rows to be deleted. A searched DELETE 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.
CURRENT OF
Specifies that the DELETE is done 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, and to the local cursor otherwise. The cursor must allow updates.
cursor_variable_name
Is the name of a cursor variable. The cursor variable must reference a cursor that allows updates.
OPTION (<query_hint> [,...n] )
Are keywords indicating that optimizer hints are used to customize SQL Server抯 processing of the statement.
{HASH | ORDER} GROUP
Specifies that the aggregations specified in the GROUP BY or COMPUTE clause of the query should use hashing or ordering.
{MERGE | HASH | CONCAT} UNION
Specifies that all UNION operations should be performed by merging, hashing, or concatenating UNION sets. If more than one UNION hint is specified, the query optimizer selects the least expensive strategy from those hints specified.
Note If a <joint_hint> is also specified for any particular pair of joined tables in the FROM clause, it takes precedence over any <join_hint> specified in the OPTION clause.
FAST number_rows
Specifies that the query is optimized for fast retrieval of the first number_rows (a nonnegative integer). After the first number_rows are returned, the query continues execution and produces its full result set.
FORCE ORDER
Specifies that the join order indicated by the query syntax is preserved during query optimization.
MAXDOP number
Overrides the max degree of parallelism configuration option (of sp_configure) only for the query specifying this option. All semantic rules used with max degree of parallelism configuration option are applicable when using the MAXDOP query hint. For more information, see max degree of parallelism Option.
ROBUST PLAN
Forces the query optimizer to attempt a plan that works for the maximum potential row size at the expense of performance. If such a plan is not possible, the query optimizer returns an error rather than deferring error detection to query execution. Rows may contain variable-length columns; SQL Server allows rows to be defined that have a maximum potential size beyond the ability of SQL Server to process them. Usually, despite the maximum potential size, an application stores rows that have actual sizes within the limits that SQL Server can process. If SQL Server encounters a row that is too long, an execution error is returned.
KEEP PLAN
Forces the query optimizer to relax the estimated recompile threshold for a query. The estimated recompile threshold is the point at which a query is automatically recompiled when the estimated number of indexed column changes (update, delete or insert) have been made to a table. Specifying KEEP PLAN ensures that a query will not be recompiled as frequently when there are multiple updates to a table.
Remarks
DELETE cannot remove data from tables on the nullable side of an outer join.
The DELETE statement may fail if it violates a trigger or attempts 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, SQL Server handles these errors as if SET ARITHABORT is ON. The remainder of the batch is canceled, and an error message is returned.
If you want to delete all the rows in a table, TRUNCATE TABLE is faster than DELETE. DELETE physically removes rows one at a time and records each deleted row in the transaction log. TRUNCATE TABLE deallocates all pages associated with the table. For this reason, TRUNCATE TABLE is faster and requires less transaction log space than DELETE. TRUNCATE TABLE is functionally equivalent to DELETE with no WHERE clause, but TRUNCATE TABLE cannot be used with tables referenced by foreign keys. Both DELETE and TRUNCATE TABLE make the space occupied by the deleted rows available for the storage of new data.
Permissions
DELETE permissions default to members of the sysadmin fixed server role, members of the db_owner fixed database role, and the table owner, who can transfer permissions to other users. SELECT permissions are also required if the statement contains a WHERE clause.
Examples
A. Use DELETE with no parameters
This example deletes all rows from the authors table.
USE pubs
DELETE authors
B. Use DELETE on a set of rows
Because au_lname may not be unique, this example deletes all rows in which au_lname is McBadden.
USE pubs
DELETE FROM authors
WHERE au_lname = 'McBadden'
C. Use DELETE on the current row of a cursor
This example shows a delete made against a cursor named complex_join_cursor. It affects only the single row currently fetched from the cursor.
USE pubs
DELETE FROM authors
WHERE CURRENT OF complex_join_cursor
D. Use DELETE based on a subquery or use the Transact-SQL extension
This example shows the Transact-SQL extension used to delete records from a base table that is based on a join or correlated subquery. The first DELETE shows the SQL-92-compatible subquery solution, and the second DELETE shows the Transact-SQL extension. Both queries remove rows from the titleauthors table based on the titles stored in the titles table.
/* SQL-92-Standard subquery */
USE pubs
DELETE FROM titleauthor
WHERE title_id IN
(SELECT title_id
FROM titles
WHERE title LIKE '%computers%')
/* Transact-SQL extension */
USE pubs
DELETE titleauthor
FROM titleauthor INNER JOIN titles
ON titleauthor.title_id = titles.title_id
WHERE titles.title LIKE '%computers%'
E. Use DELETE and a SELECT with the TOP Clause
Because a SELECT statement can be specified in a DELETE statement, the TOP clause can also be used within the SELECT statement. For example, this example deletes the top 10 authors from the authors table.