MS SQL更新时变量函数子查询及字段计算顺序探索
Posted Hello World,
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MS SQL更新时变量函数子查询及字段计算顺序探索相关的知识,希望对你有一定的参考价值。
思考
如果在更新语句中引用到变量,并且在更新语句中对变量赋值,更新后的值将如何变化?另外变量与字段的更新顺序又是怎样的呢?
探索
创建表并插入数据,声明变量,在更新语句中对变量及字段进行变更:
DECLARE @t TABLE(seq INT IDENTITY, a INT,b INT,c INT, d INT,e INT)
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)
SELECT * FROM @t
DECLARE @n INT=1
UPDATE @t SET a=@n,@n=@n+1,b=@n,c=(SELECT @n),d=e,e=d
SELECT * FROM @t
结果如图所示:
此时发现a、b两列的值是一样的,更新语句中对变量的赋值位置不会影响到更新的值,而d、e两列的内容互换了。但是采购子查询更新的c列内容全部是变量的初始值。说明子查询被优化了,只计算了一次?
通过此次示例可以看到计算的顺序是先算子查询,而且子查询中的变量不会改变,然后每行会先更新变量值,再更新字段值。
那如果子查询中要根据不同的变量值来获取不同的值怎么办呢?
根据实践,只有采用函数来处理,才会实现针对不同变更值获取不同返回内容。
先创建函数,示例中仅简单地返回原来的值:
CREATE FUNCTION GetN
(
@N INT
)
RETURNS INT
AS
BEGIN
RETURN @N;
END;
GO
然后在更新语句中调用此函数:
SET @n =1
UPDATE @t SET a=@n,@n=@n+1,b=dbo.getn(@n),c=(SELECT @n),e=b,d=e
SELECT * FROM @t
此时的结果如下:
此时b列是通过函数调用生成的,c列仍然是子查询,可以看到b列的结果同样是在变量更新后调用的子查询值,如果将变更的赋值放到b列赋值的后面结果也是一样的。
所以顺序仍然是先变量、后函数和字段。但函数和字段赋值的顺序又是什么样子呢?
两次修改更新语句如下:
DECLARE @n INT=1
UPDATE @t SET a=dbo.getn(@n),@n=@n+1,b=dbo.getn(@n),c=(SELECT @n),e=c,d=a
SELECT * FROM @t
此次将d列的值更新为a列的值,e的值更新为c的值,a列的值更新为函数的值,可以看到字段的赋值在函数和子查询之前了:
结论
所以优先顺序为变量>字段(所有字段同时更新)>子查询和函数。
字段同时更新其实是因为更新是有一个Deleted临时表,里面记录了原始值,所以看上去是同时更新的。
以上是关于MS SQL更新时变量函数子查询及字段计算顺序探索的主要内容,如果未能解决你的问题,请参考以下文章
MySQL进阶8 分页查询(limit) - SQL查询语法顺序及大致结构- 子查询的3个经典案例
库存 SQL 查询出现歧义错误,其中两个字段应相等以进行计算。 MS-ACCESS
oracle sql 转换成 hive sql -子查询转关联查询(十七),子查询中有2个表外字段关联写法,round函数与power函数的运用