直接执行语句和从存储过程执行语句时输出不同?

时间:2011-04-04 15:35:01

标签: sql-server sql-server-2008

Sql Server 2008表现得很奇怪。当我执行存储过程时,输出的顺序与我直接为相同参数执行语句时的顺序不同。我不确定我做错了什么。请帮忙!!!

这是一个简单的查询结构,并解释它的作用。

Top 10 Query1
Union all
Top 10 Query2
Order by name

一个。当你在proc中运行它时: 从查询1获取前10名,然后从查询2获取前10名,然后最终获得订单

湾当您打开查询时: 从查询1开始,它应用订单,然后获取前10名,而从查询2中,它也应用订单,然后获取前10名

奇怪的是,它使用相同的查询做了两件不同的事情。

Output from Procedure
Name                                          Cost Price
A2 Bag Stickerss DO NOT STOCKTAKES               24
aaaaaa                                           5
aaaaaa                                           7.5


Output from Query
Name                                          Cost Price
A2 Bag Stickerss DO NOT STOCKTAKES               24
A2 Bag Stickerss DO NOT STOCKTAKES               27
aaaaaa                                           5
aaaaaa                                           7.5
aaaaaa                                           9

1 个答案:

答案 0 :(得分:4)

没有TOP

ORDER BY不具有确定性。

它只是意味着“选择任意10条记录”。因此,您从查询1中选择一组10个任意结果,从查询2中选择10个任意记录,然后按名称对这20个记录进行排序。

您最终得到的TOP 10取决于所选择的计划(存储过程可能会有所不同)您需要在每个查询中添加一个订单(在一组没有关系的列上)使其具有确定性。

您当前的查询就像

SELECT TOP 10 * 
FROM master..spt_values
UNION ALL
SELECT TOP 10 * 
FROM master..spt_values
ORDER BY name

Plan 1

您看到SQL Server只是向计划的两个分支添加了TOP迭代器,以限制两个查询的输出,然后将这些请求输入到Union中,然后按名称排序。 SQL Server为此选择了聚簇索引扫描,因此结果可能是聚簇索引顺序type,number,name中的TOP 10(尽管不应该依赖于此,没有指定的顺序来指示{{1引用任意 10行的集合是有效的。在这里使用advanced scanning功能并给你一个它知道的任意10行是完全有效的。缓存,因为它们刚刚被其他查询的扫描读取。)

要为每个元素指定TOP重写查询,可以使用CTE,如下所示。

TOP...ORDER BY

Plan 2