我有一个复杂的select语句,我想返回到应用程序层。同时我想从这个语句中重用id。我来这样的表变量解决方案
DECLARE @Result TABLE (SortOrder int IDENTITY, Id bigint, data_columns, PRIMARY KEY (Id))
INSERT INTO @Result
SELECT Id, data_columns ...
--output to the app layer
SELECT Id, data_columns FROM @Result ORDER BY SortOrder;
--using @Result Id elsewhere
SortOrder用于保留第一个选择的原始顺序。没有它我在ms sql server 2012中遇到了一个奇怪的错误。 PRIMARY KEY(Id)用作优化器的提示,Id值是唯一的。 SortOrder与Id无关。
现在我担心内存和CPU过载问题。有没有人有更好的解决方案?
-----增加: 这可以是一个答案
DECLARE @Ids TABLE (Id bigint, PRIMARY KEY (Id));
MERGE @Ids AS ids
USING (SELECT TOP 9223372036854775807 Id, data_columns ...) AS result
ON 1=0
WHEN NOT MATCHED THEN
INSERT VALUES(result.Id)
OUTPUT result.*; --output to the app layer here
--using @Ids Id elsewhere
我可以确认它适用于我的样品并且花费的时间更少。 但我仍然担心OUTPUT的订单。
TOP hack解释MERGE INTO insertion order
MSDN也说
无法保证更改的应用顺序 到表和行插入的顺序 输出表或表变量将对应。
幸运的是我不关心@Ids表中的顺序。但是在OUTPUT子句中获得与USING()
中相同的顺序非常重要答案 0 :(得分:0)
在我看来,您试图坚持特定的排序顺序,在这种情况下,您可以使用ROW_NUMBER
来产生所需的效果:
SELECT ROW_NUMBER() OVER(ORDER BY OriginalSortingColumns) AS SortOrder
, data_columns
FROM sourcetable
但是,如果不了解您的计划的目的以及数据的结构和性质,我无法确定。非常值得一读本指南 - How do I ask a good question? - 以确保您提供我们所需的所有信息,以便您快速获得一个好的答案。
正如评论所说,你永远不能依靠密钥来订购数据,这就是ORDER BY
语句的用途。