Sql server Sql Server聚合连接CLR根据记录数返回不同的字符串序列
我有一个clr聚合连接函数,类似于。当行数较少时,串联字符串的序列跟随输入数据集。当行数较大(几十行或更多行)时,序列似乎不确定。执行计划有所不同,但我不太熟悉优化器以及应用什么提示(我尝试了MAXDOP 1,但没有成功)。从一个与下面的示例不同的测试中得到了类似的结果,这似乎是计划中的不同之处——单独的排序,然后是合并联接。它翻到这里的排数是60 取得了预期成果: 产生了意想不到的结果: 以下是使用上述clr(重命名为TestConcatenate)演示AdventureWorks2014示例数据库中问题的查询。预期结果是一个数据集,其中每个订单有一行,该列按数量顺序为该订单的产品列表设置了分隔符Sql server Sql Server聚合连接CLR根据记录数返回不同的字符串序列,sql-server,clr,Sql Server,Clr,我有一个clr聚合连接函数,类似于。当行数较少时,串联字符串的序列跟随输入数据集。当行数较大(几十行或更多行)时,序列似乎不确定。执行计划有所不同,但我不太熟悉优化器以及应用什么提示(我尝试了MAXDOP 1,但没有成功)。从一个与下面的示例不同的测试中得到了类似的结果,这似乎是计划中的不同之处——单独的排序,然后是合并联接。它翻到这里的排数是60 取得了预期成果: 产生了意想不到的结果: 以下是使用上述clr(重命名为TestConcatenate)演示AdventureWorks2014
;with cte_ordered_steps AS (
SELECT top 100000 sd.SalesOrderID, SalesOrderDetailID, OrderQty
FROM [Sales].[SalesOrderDetail] sd
--WHERE sd.SalesOrderID IN (53598, 53595)
ORDER BY sd.SalesOrderID, OrderQty
)
select
sd.SalesOrderID,
dbo.TestConcatenate(' QTY: ' + CAST(sd.OrderQty AS VARCHAR(9)) + ': ' + IsNull(p.Name, ''))
FROM [Sales].[SalesOrderDetail] sd
JOIN [Production].[Product] p ON p.ProductID = sd.ProductID
JOIN cte_ordered_steps r ON r.SalesOrderID = sd.SalesOrderID AND r.SalesOrderDetailID = sd.SalesOrderDetailID
where sd.SalesOrderID IN (53598, 53595)
GROUP BY sd.SalesOrderID
当SalesOrderID在53598、53595的cte中受约束时,序列是正确的(顶部集合);当SalesOrderID在53598、53595的主选择中受约束时,序列不是正确的(底部集合)。
那么我的问题是什么?如何使用提示或其他更改构建查询,以返回与行数无关的一致(且正确)序列连接值 与普通查询一样,如果没有ORDERBY子句,则不能保证返回顺序。如果我没记错的话,SQL92规范允许通过over子句将ORDERBY子句传递到聚合中,SQLServer没有实现它。因此,无法保证CLR函数中的顺序(除非您自己通过收集
Accumulate
和Merge
方法中的所有内容来实现它,然后在返回之前在Terminate
方法中对列表进行排序。但是您将支付内存授予方面的成本,因为现在需要序列化集合
至于为什么会根据结果集的大小看到不同的行为,我注意到在这两个结果集之间使用了不同的连接运算符。循环连接和合并连接遍历两个不同的连接集,因此这可能会解释您看到的差异。就像普通查询一样,如果没有order by子句,不保证返回顺序。如果我没记错的话,SQL 92规范允许通过over子句将order by子句传递到聚合中,SQL Server没有实现它。因此无法保证CLR函数中的顺序(除非您自己通过收集
Accumulate
和Merge
方法中的所有内容来实现它,然后在返回之前在Terminate
方法中对列表进行排序。但是您将支付内存授予方面的成本,因为现在需要序列化集合
至于为什么会根据结果集的大小看到不同的行为,我注意到在这两个结果集之间使用了不同的连接运算符。循环连接和合并连接遍历两个不同的连接集,因此这可能会解释您看到的差异。为什么不尝试聚合dbo.GROUP_CONCAT_S available at.S用于排序输出。它完全符合您的要求。为什么不尝试在上提供的聚合dbo.GROUP\u CONCAT\u S.S用于排序输出。它完全符合您的要求。虽然此答案没有解决方案,但Ben和Orlando提供的附加信息(谢谢!)我将采用Orlando指出的方法,这也是我的计划B,即在clr中进行排序。虽然这个答案没有解决方案,但Ben和Orlando提供的附加信息(谢谢!)我将采用奥兰多指出的方法,这也是我的B计划,即在clr中排序