• MS SQL变更及字段更新顺序问题


    思考

    如果在更新语句中引用到变量,并且在更新语句中对变量赋值,更新后的值将如何变化?另外变量与字段的更新顺序又是怎样的呢?

    探索

    创建表并插入数据,声明变量,在更新语句中对变量及字段进行变更:

    1. DECLARE @t TABLE(seq INT IDENTITY, a INT,b INT,c INT, d INT,e INT)
    2. INSERT @t VALUES (0,0,0,0,1),(0,0,0,0,2),(0,0,0,0,3),(0,0,0,0,4),(0,0,0,0,5)
    3. SELECT * FROM @t
    4. DECLARE @n INT=1
    5. UPDATE @t SET a=@n,@n=@n+1,b=@n,c=(SELECT @n),d=e,e=d
    6. SELECT * FROM @t

    结果如图所示:

     此时发现a、b两列的值是一样的,更新语句中对变量的赋值位置不会影响到更新的值,而d、e两列的内容互换了。但是采购子查询更新的c列内容全部是变量的初始值。说明子查询被优化了,只计算了一次?

    通过此次示例可以看到计算的顺序是先算子查询,而且子查询中的变量不会改变,然后每行会先更新变量值,再更新字段值。

    那如果子查询中要根据不同的变量值来获取不同的值怎么办呢?

    根据实践,只有采用函数来处理,才会实现针对不同变更值获取不同返回内容。

    先创建函数,示例中仅简单地返回原来的值:

    1. CREATE FUNCTION GetN
    2. (
    3. @N INT
    4. )
    5. RETURNS INT
    6. AS
    7. BEGIN
    8. RETURN @N;
    9. END;
    10. GO

    然后在更新语句中调用此函数:

    1. SET @n =1
    2. UPDATE @t SET a=@n,@n=@n+1,b=dbo.getn(@n),c=(SELECT @n),e=b,d=e
    3. SELECT * FROM @t

    此时的结果如下:

     此时b列是通过函数调用生成的,c列仍然是子查询,可以看到b列的结果同样是在变量更新后调用的子查询值,如果将变更的赋值放到b列赋值的后面结果也是一样的。

    所以顺序仍然是先变量、后函数和字段。但函数和字段赋值的顺序又是什么样子呢?

    两次修改更新语句如下:

    1. DECLARE @n INT=1
    2. UPDATE @t SET a=dbo.getn(@n),@n=@n+1,b=dbo.getn(@n),c=(SELECT @n),e=c,d=a
    3. SELECT * FROM @t

    此次将d列的值更新为a列的值,e的值更新为c的值,a列的值更新为函数的值,可以看到字段的赋值在函数和子查询之前了:

    结论 

    所以优先顺序为变量>字段(所有字段同时更新)>子查询和函数。

    字段同时更新其实是因为更新是有一个Deleted临时表,里面记录了原始值,所以看上去是同时更新的。

  • 相关阅读:
    身为底层码农,你见过最无理需求是啥?
    统计软件与数据分析Lesson15----梯度下降(Gradient Descent)过程可视化
    kubernetes(6)Service
    vue2两个数组嵌套循环返回的新数组item顺序要一致
    旅游旺季,酒店要如何做好报修管理工作?
    主流的深度学习推理架构有哪些呢?
    linux安装Redis
    Thanos解码:打造企业级云原生监控解决方案
    0034【Edabit ★☆☆☆☆☆】【修改Bug4】Buggy Code (Part 4)
    【数据库】MySQL的事务特性与隔离级别
  • 原文地址:https://blog.csdn.net/apollokk/article/details/126500634