【问题标题】:Update statement SQL with CTE使用 CTE 更新语句 SQL
【发布时间】:2017-01-13 17:54:18
【问题描述】:

我有一个公用表表达式,我正在尝试将其用作更新语句。 CTE 的唯一原因是我可以使用 where 子句按 CredCount 进行过滤。我想使用 where 子句仅更新在这种情况下 CredCount 为 2 匹配的记录。但是,我在查询的更新部分遇到了问题。

Members_id Credentials CredCount members_amountdue
1 CMA, CPR 2 0
2 CMA, CPR 2 0
3 CMA, CPR 2 0

这是对它的查询

WITH CTE AS (
SELECT members_id,   members_amountdue,  [Credentials], LEN([Credentials]) - LEN(REPLACE([Credentials], ',', '')) + 1 AS CredCount
FROM (
        SELECT DISTINCT  mem1.members_id, mem1.members_amountdue, 
            STUFF(
                (SELECT DISTINCT ', ' + credentials_code
                FROM members AS mem JOIN
                members_credentials  AS mc ON mc.members_id = mem.members_id JOIN
                credentials AS c ON c.credentials_id = mc.credentials_id
                WHERE mem.[members_id] = mem1.[members_id]              
                FOR XML PATH ('')), 1, 1, '')  AS [Credentials]
        FROM members AS mem1 JOIN
        members_status as ms on ms.members_status_id = mem1.members_status_id   
    ) AS derived),
CTE2 AS ( SELECT members_id
            FROM members)
SELECT  CTE.members_id, CTE.Credentials, CTE.CredCount, (CTE.members_amountdue + 25) as NewPriceTotal
FROM CTE JOIN
CTE2 ON CTE.members_id = CTE2.members_id
WHERE CTE.CredCount = 2

使用更新语句,我正在查看Update records in table from CTE 此处提供的示例,因此我将更新语句添加到查询的底部

WITH CTE AS (
SELECT members_id,   members_amountdue,  [Credentials], LEN([Credentials]) - LEN(REPLACE([Credentials], ',', '')) + 1 AS CredCount
FROM (
        SELECT DISTINCT  mem1.members_id, mem1.members_amountdue, 
            STUFF(
                (SELECT DISTINCT ', ' + credentials_code
                FROM members AS mem JOIN
                members_credentials  AS mc ON mc.members_id = mem.members_id JOIN
                credentials AS c ON c.credentials_id = mc.credentials_id
                WHERE mem.[members_id] = mem1.[members_id]              
                FOR XML PATH ('')), 1, 1, '')  AS [Credentials]
        FROM members AS mem1 JOIN
        members_status as ms on ms.members_status_id = mem1.members_status_id   
    ) AS derived),
CTE2 AS ( SELECT members_id
            FROM members)
SELECT  CTE.members_id, CTE.Credentials, CTE.CredCount, (CTE.members_amountdue + 25) as NewPriceTotal
FROM CTE JOIN
CTE2 ON CTE.members_id = CTE2.members_id
WHERE CTE.CredCount = 2
UPDATE members
set members_amountdue = NewPriceTotal

当我添加更新语句时,我收到“NewPriceTotal”列名无效的错误。我知道我需要匹配列才能使更新生效,但我不确定它为什么无效。

Members_id Credentials CredCount NewPriceTotal
1 CMA, CPR 2 25
2 CMA, CPR 2 25
3 CMA, CPR 2 25

我希望将 NewPriceTotal 设置为 members 表中的 members_amountdue,但我不确定我在哪里做错了。非常感谢任何帮助、cmets 或反馈。

【问题讨论】:

  • 该更新是一个单独的声明,不知道您对 CTE 所做的任何事情。 CTE 类似于临时的内联视图,并且不会持久化。也许您应该将输出转储到 #temp 表并更改 UPDATE 语句以加入 #temp 表。

标签: sql sql-server tsql common-table-expression


【解决方案1】:

试试这个:

....
CTE2 AS ( 
   SELECT members_id
   FROM members
), CTE3 AS (
   SELECT  CTE.members_id, CTE.Credentials, CTE.CredCount,  
           CTE.members_amountdue,  
           (CTE.members_amountdue + 25) as NewPriceTotal
   FROM CTE JOIN CTE2 ON CTE.members_id = CTE2.members_id
   WHERE CTE.CredCount = 2)
UPDATE CTE3
SET members_amountdue = NewPriceTotal

【讨论】:

  • 感谢您的建议,但是这会遇到错误“消息 4403,级别 16,状态 1,第 1 行无法更新视图或函数 'CTE3',因为它包含聚合,或 DISTINCT 或 GROUP BY 子句, 或 PIVOT 或 UNPIVOT 运算符。”
  • @Jay 这是由于顶级 CTE 中使用了 DISTINCT 关键字。 UPDATE 被传播到数据库中的真实表。使用DISTINCT 会使引擎难以确定要更新的确切行。不使用DISTINCT会是什么结果?
  • 感谢 Giorgos - 感谢您的帮助。你的建议是对的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-09
  • 1970-01-01
相关资源
最近更新 更多