Sql server T-SQL与。。。更新示例说明

Sql server T-SQL与。。。更新示例说明,sql-server,tsql,Sql Server,Tsql,我只是找不到以下查询的某些部分如何工作的文档或解释 查询: ;WITH ToUpdate AS ( SELECT Id, Foo, FIRST_VALUE(Foo) OVER (ORDER BY Id) + ROW_NUMBER() OVER (ORDER BY Id) - 1 AS newFoo FROM mytable WHERE Bar= 1 AND Id >=

我只是找不到以下查询的某些部分如何工作的文档或解释

查询:

;WITH ToUpdate AS (
    SELECT Id, 
           Foo, 
           FIRST_VALUE(Foo) OVER (ORDER BY Id) + 
               ROW_NUMBER() OVER (ORDER BY Id) - 1 AS newFoo
    FROM mytable
    WHERE Bar= 1 
        AND Id >= 111
)
UPDATE ToUPDATE
SET Foo = newFoo
它来自SO用户,作为对另一个问题的回答,该问题类似于下面描述的问题

假设我们有一张这样的桌子:

 Id   Foo  Bar
  2     5    1 
  3     6    1
 13   111   22
111     7    1
122    16    1
154    17    1
176    18    1
我们希望使用一个查询,该查询将:

  • 获取
    Bar=1和
    Id>=111的所有行
  • 按Id升序排列行
  • 更新所有
    Foo
    ,使新值等于上一行的值,从Id=111的行开始,增加1
因此,生成的表将如下所示:

 Id   Foo  Bar
  2     5    1 
  3     6    1
 13   111   22  <-- not affected 
111     7    1
122     8    1
154     9    1
176    10    1
Id Foo-Bar
2     5    1 
3     6    1

13 111 22当您更新CTE中的列时,SQL Server会将该列跟踪回其源表。在这种情况下,
mytable
表有一个名为
Foo
的列,因此它实际上会在
mytable
表中得到更新

顺便说一下,CTE不是任何类型的临时表,甚至不是视图。这只是包装SQL代码/功能的一种方便方法。在幕后,我希望CTE实际上会编译成一个典型的
UPDATE
语句,您可以运行
EXPLAIN
来说服自己

您可能想知道,如果您尝试对涉及无法追溯到物理表的列的CTE执行
更新
,会发生什么。在这种情况下,将出现如下错误:

更新或插入视图或函数“cte”失败,因为它包含派生字段或常量字段


错误消息说明了一切。您试图更新一个实际不存在于物理表中的列,但SQL Server拒绝进行更新,对此表示抗议。

当您更新CTE中的列时,SQL Server会将该列跟踪回其源表。在这种情况下,
mytable
表有一个名为
Foo
的列,因此它实际上会在
mytable
表中得到更新

顺便说一下,CTE不是任何类型的临时表,甚至不是视图。这只是包装SQL代码/功能的一种方便方法。在幕后,我希望CTE实际上会编译成一个典型的
UPDATE
语句,您可以运行
EXPLAIN
来说服自己

您可能想知道,如果您尝试对涉及无法追溯到物理表的列的CTE执行
更新
,会发生什么。在这种情况下,将出现如下错误:

更新或插入视图或函数“cte”失败,因为它包含派生字段或常量字段

错误消息说明了一切。您试图更新一个实际不存在于物理表中的列,但SQL Server拒绝更新而提出抗议