在没有游标的情况下更新每个 select 行结果

Update every select row result without cursor

正在学习使用 tsql 做不同的事情。我想改进我的代码并希望获得建议。

假设我有这个select:

SELECT [Id], [Type]
FROM 
(
    SELECT
        ROW_NUMBER() OVER(PARTITION BY [Id] ORDER BY CurrentDate DESC) AS RowN,
        CS.*
    FROM [CookieStore] CS 
)RN
WHERE RN.RowN = 1

我 returns 结果 table 有几行:

1) id=5  Type='chocolate'
2) id=6  Type='oatmeal'
3) id=7  Type='gingerbread'

为了实现我的目标,我将光标置于 select 结果上以进行更新:

/* some cursor logic */

UPDATE [SweetShop] SET [Type] = @CookieShopType WHERE [Id]=@CookieStoreId

/* some cursor logic */

有没有办法在没有游标的情况下更新 select 中的每一行?或者在这种情况下没有其他选择?

您可以使用基于集合的方法(无游标)执行此操作。

首先使用原始查询定义 CTE,然后可以使用 UPDATE FROM 语句从 CTE 和目标 table 之间的连接更新目标 table:

;with temp as (
    SELECT [Id], [Type]
    FROM 
    (
        SELECT
            ROW_NUMBER() OVER(PARTITION BY [Id] ORDER BY CurrentDate DESC) AS RowN,
            CS.*
        FROM [CookieStore] CS 
    )RN
    WHERE RN.RowN = 1
)
update 
    [SweetShop]
set 
    [Type] = t.[Type]
from
    [SweetShop] as d 
        inner join
    temp as t
        on t.Id = d.Id

使用CTE,还可以避免在CTE中写子查询。

WITH CTE AS (
    SELECT
        ROW_NUMBER() OVER(PARTITION BY [Id] ORDER BY CurrentDate DESC) AS RowN,
        CS.*
    FROM [CookieStore] CS 
)

UPDATE 
    [SweetShop]
SET 
    [Type] = cte.[Type]
FROM
    [SweetShop] as SS 
INNER JOIN
    CTE as C
ON cte.Id = d.Id
WHERE CTE.RowN = 1