【问题标题】:Using 'with' clause for update purpose使用 'with' 子句进行更新
【发布时间】:2014-03-24 16:33:06
【问题描述】:

我在 sql server 数据库中有如下关系:

假设我想对关系进行一些修改。我想删除 CPU_TYPE 表并在计算机表中添加一列“cpu”。

现在我想使用sql server中的'with'子句查询从两个表连接的数据,并执行update语句来更新计算机表。

这个sql server查询:

SELECT COMPUTER.compID, COMPUTER.serialNo, COMPUTER.cpuId, 
CPU_TYPE.name, CPU_TYPE.cpuSpeed, COMPUTER.cpu
FROM COMPUTER LEFT OUTER JOIN
CPU_TYPE ON COMPUTER.cpuId = CPU_TYPE.cpuId

结果如下:

现在我将使用 'with' 子句创建一个数据集,如下所示:

with ds as
(
SELECT COMPUTER.compID, COMPUTER.serialNo, COMPUTER.cpuId, 
CPU_TYPE.name, CPU_TYPE.cpuSpeed, COMPUTER.cpu
FROM COMPUTER LEFT OUTER JOIN
CPU_TYPE ON COMPUTER.cpuId = CPU_TYPE.cpuId
)
update ds set cpu = name +', '+ cpuSpeed;

结果如下:

查询执行成功但问题是COMPUTER表没有改变! 如何解决这个问题?

【问题讨论】:

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


    【解决方案1】:

    您的代码很好。您的数据已关闭。 CPUSpeedNULL,因此连接的结果将始终是 NULL。所以,使用coalesce()

    with ds as (
          SELECT COMPUTER.compID, COMPUTER.serialNo, COMPUTER.cpuId, 
                 CPU_TYPE.name, CPU_TYPE.cpuSpeed, COMPUTER.cpu
          FROM COMPUTER LEFT OUTER JOIN
               CPU_TYPE
               ON COMPUTER.cpuId = CPU_TYPE.cpuId
         )
    update ds
         set cpu = name +', '+ coalesce(cpuSpeed, '');
    

    【讨论】:

    • 谢谢您,Gordon Linoff 先生,这非常完美。
    • 我会花一些时间在函数 coalesce 上,以便更好地理解该函数。
    • 好吧,coalesce 的工作原理与 isnull 函数完全一样
    【解决方案2】:

    我相信很多人会在他们的回答中指出,您没有必须使用公用表表达式来完成此更新。

    不过,您可以(如果您希望练习 CTE 技能):

    WITH cte AS
    (
        SELECT c1.compID, c2.name, c2.cpuSpeed
        FROM [COMPUTER] AS c1
        LEFT OUTER JOIN [CPU_TYPE] AS c2
            ON ( comp.cpuId = c2.cpuId )
    )
    UPDATE [COMPUTER]
    SET cpu = cte.name + ', ' + cte.cpuSpeed
    FROM [COMPUTER] AS comp
    INNER JOIN cte ON ( comp.compId = cte.compId )
    

    如果你想过滤你的 CTEs 结果,那么你可以在你的 CTE 中添加一个 WHERE 子句,例如:

    WHERE c1.cpuId IS NOT NULL
    

    或其他任何事情。

    更新

    如果您的cpuSpeed 列中有NULL 数据,那么您可能需要考虑以下SET 语句,而不是上面列出的SET

    SET cpu = cte.name + Coalesce(', ' + cte.cpuSpeed, '')
    

    ...或者:

    SET cpu = cte.name + IsNull(', ' + cte.cpuSpeed, '')
    

    这样,如果cpuSpeed 为NULL,那么您仍然有来自name 列的数据,没有在末尾附加逗号(“,”);如果name 也为 NULL(或 NULL 而不是 cpuSpeed),则 cpu 将设置为 NULL。

    请记住,您始终可以为您的 CTE 添加一个更具保护性的过滤器,例如:

    WHERE c1.cpuId IS NOT NULL AND c2.name IS NOT NULL
    

    当然,您应该调整 SQL 以满足您的特定要求。

    我希望这会有所帮助。祝你好运!

    【讨论】:

    • Msg 102, Level 15, State 1, Line 36 '=' 附近的语法错误。
    • 印刷错误已更正。我没有按下shift键:SET cpu = cte.name = ', ' + cte.cpuSpeed应该是SET cpu = cte.name + ', ' + cte.cpuSpeed
    【解决方案3】:

    试试这个而不是使用 CTE。

    UPDATE COMPUTER 
    SET cpu = name + ', ' + cpuSpeed
    FROM COMPUTER C1 LEFT OUTER JOIN
    CPU_TYPE ON C1.cpuId = CPU_TYPE.cpuId
    

    【讨论】:

    • 执行成功但没有完成工作
    猜你喜欢
    • 2017-04-21
    • 1970-01-01
    • 1970-01-01
    • 2023-02-23
    • 2014-03-16
    • 1970-01-01
    • 2019-02-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多