所以,我发现了一些有趣的事情。我在玩 TOP 命令并在 select 语句中分配变量。我发出了以下查询,发现变量 (@a) 值是从 Top 命令返回的最后一个值。似乎对于每个返回的值,该值被分配给变量,然后结果集中的每一行随后被分配,几乎就像一个循环。
declare @a nvarchar(max)
select top 10 DisplayName
from dbo.Users
select top 10 @a = DisplayName
from dbo.Users
select @a as Results
Run Code Online (Sandbox Code Playgroud)
结果:
这让我很好奇。我修改了查询以再次测试并执行以下操作:
declare @a nvarchar(max)
declare @b int = 0
select TOP 10 @a = DisplayName, @b = @b + 1
from dbo.Users
select @a as DisplayName, @b as Number
Run Code Online (Sandbox Code Playgroud)
结果:
这真的很有趣。从这两个查询来看,由于@b 上发生的累积总和以及上面发生的分配,TOP 命令似乎正在执行某种循环。有人可以解释发生了什么吗?使用 TOP 命令时,SQL 是否会执行 RBAR 操作?
编辑:
我也在没有 TOP 命令的情况下执行此操作,并查看结果,因此它不仅仅是 TOP 命令。似乎在 SELECT 语句中分配变量执行 RBAR 命令?
declare @a nvarchar(max)
declare @b int = 0
select @a = DisplayName, @b = @b + 1
from dbo.Users
select @a as DisplayName, @b as Number
Run Code Online (Sandbox Code Playgroud)
结果:
似乎对于每个返回的值,该值被分配给变量,然后结果集中的每一行随后被分配,几乎就像一个循环。
是的。这就是发生的事情。这是最初实现 SELECT 查询中的变量分配方式的副作用。但它被使用得足够多,以至于无法真正改变,甚至被记录在案:
如果 SELECT 语句返回多行并且该变量引用了一个非标量表达式,则该变量将设置为为结果集最后一行中的表达式返回的值。
和
出于向后兼容性的原因,SQL Server 支持在最顶层范围内的 SELECT @p = @p + 1 ... ORDER BY 类型的赋值。