表值函数结果的保证顺序

问题描述

对于嵌入式TVF,什么都没有真正起作用。不仅如此,内联TVF甚至可能返回比您预期的 更多的 行,并且将在执行TVF 之后 对行进行修剪(基本上可以将TVF定义中的谓词从TVF中拉出并移至查询中的其他位置)树)。有关这种情况的示例,请参见T-SQL函数不暗示一定的执行顺序

将内联TVF转换为多语句会引入一些过程顺序,因为这些语句不能无序执行,但是TVF结果可能会重新排序,排序,拆分,假脱机,基本上是由优化程序生成的计划和最后打破了您对输出顺序的假设。恐怕如果您必须 按一定顺序执行,游标就是您最好的朋友。

解决方法

前提 :无法更改应用程序代码。条件是非常具体的。我正在寻找书本上的东西,如果可以的话,这是最后的解决方法。

我有一个表值函数(内联),可产生2到7条记录。有时可能只有1个或最多15个(但很少)。

该功能仅由应用程序以这种方式使用,而没有任何ORDER BY。

select * from dbo.myfunction(...)

根据您的经验,是否有任何方法 可以
确保(就您使用特定技术所观察到的)结果按第二列排序返回?列为:varchar(3),datetime,varchar(50)。不要让我开始使用
select * ,这是 故意的, 因此前端将显示不管我将来使函数显示多少列。

根据经验,使用单个索引(聚集的PK)来遍历数据,任何当前版本的SQL Server和SP级别都应始终对 <20个记录执行简单的INDEX
SCAN,而没有并行性,从而使我在选择应用程序时得到有序的结果。

你的想法?我宁愿将理论排除在讨论范围之外。如果您可以坚持实践经验并在家讲讲最佳实践,我也将不胜感激。


更新, 这是现在的样子

create function dbo.myfunction(....)
returns @RES table
    (
    [#] int identity primary key clustered,[Varchar3Col] varchar(3),[DateTimeCol] datetime,[Varchar50Col] varchar(50)
    ) as
BEGIN
declare @RES2 table
    (
    rn int,[Varchar50Col] varchar(50)
    )

insert @RES2
select rn=row_number() over (order by action_time),[Varchar3Col]
    [DateTimeCol]
    [Varchar50Col]
from (.....)
inner join (.....) ON (.....)

declare @i int
set @i = 0
while @@rowcount > 0 begin
    set @i=@i+1
    insert @RES
    select [Varchar3Col],[DateTimeCol],[Varchar50Col]
    from @RES2
    where rn=@i
end
return
END
GO
  • 如果您查看上述内容,@ RES的填充将按所需顺序手动进行。
  • @RES具有代表所插入订单的群集PK。
  • 列足够小,以至于20行应始终容纳在单个8K页面中

可以吗(使用来自应用程序层的直接SELECT)?