问题描述
对于嵌入式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)?