使用双FROM子句删除

时间:2015-04-28 16:31:56

标签: sql-server sql-server-2008-r2

我很惊讶这是有效的。我不确定我理解为什么。

create table #tempt(something int)

DELETE FROM #tempt -- works fine
FROM #tempt EM

我希望在DELETE中使用别名,我特别希望不需要第一个FROM。为什么第一个FROM存在?

DELETE EM --what I would expect to work
FROM #tempt EM

2 个答案:

答案 0 :(得分:3)

因为如果您查看文档msdn

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

有两个FROM s!

第一个是可选的,用于标识目标表。

第二个(不是标准的)它可以用来在目标表上用连接而不是存在来实现额外的过滤。

通过一些进一步的调查,似乎第一个FROM是编写DELETE FROM语句的标准方式。但是使用第二个FROM会使语句看起来不自然(就像你提到的那样),所以这可能是它可选的原因。

答案 1 :(得分:2)

来自MSDN(摘录):

DELETE 
    [ FROM ] 
    { { table_alias
      | table_or_view_name       
    }
    [ FROM table_source [ ,...n ] ] 

首先FROM

  

FROM:可以在DELETE之间使用的可选关键字   关键字和目标 table_or_view_name

第一个FROM的参数:

  

table_alias :FROM table_source子句中指定的别名   表示要从中删除行的表或视图。

     

table_or view_name :行的表或视图的名称   将被删除。

第二个FROM

  

FROM table_source:指定附加 FROM子句。这个   DELETE的Transact-SQL扩展允许指定数据    并从中删除表中的相应行   第一个FROM子句。

所以,只需几句话:

  • 首先FROM可选,用于指定要从中删除行的目标表。您可以省略它,正如您在OP中指出的那样,只需使用第二个FROM中指定的 table_alias 即可。
  • 第二个FROM是一个T-SQL扩展,用于指定要从 target 表中删除的行。