我们使用一个小的sql函数,它通过一些分隔符分割字符串,并将这些值返回到表中。ORDER BY(SELECT NULL)
ALTER FUNCTION [shark].[SplitStrings]
(
@List VARCHAR(MAX),
@Delimiter VARCHAR(255)
)
RETURNS TABLE
AS
RETURN (SELECT [Item], ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS [Id] FROM
(SELECT Item = x.i.value('(./text())[1]', 'varchar(max)')
FROM (SELECT [XML] = CONVERT(XML, '<i>'
+ REPLACE(@List, @Delimiter, '</i><i>') + '</i>').query('.')
) AS a CROSS APPLY [XML].nodes('i') AS x(i)) AS y
WHERE Item IS NOT NULL
);
问题是,如果这可以改变从字符串中的元素的顺序?
Ex。
SELECT * FROM [shark].[SplitStrings] ('1,2,3,4,5', ',')
可这一回的
1
5
3
4
2
代替
1
2
3
4
5
?
更多信息: 经过几个月的正常工作,我们在其中一个组件中发现了一个错误,并且唯一的来源是我们可以找到并且可能导致此错误的是上述过程。它以某种方式改变了包含65 000个元素的字符串数组的顺序(带分隔符的字符串的总长度为65 000 * 11)。我们试图在同一个sql服务器上重现相同的错误,但没有任何运气。你的意见和答案使这个问题更加有罪。
所有'ORDER BY'子句的用途是定义将什么'ROW_NUMBER()'值分配给行。但是由于所有行在该子句中都被赋予相同的值,所以分配的行号无法得到保证。并且这些保证都不影响*返回结果的顺序*。 –
我同意@Damien_The_Unbeliever。缺乏逻辑顺序可能导致任何顺序。我有一个查询按照我想要的顺序返回了多年的数据,在SQL Server升级后,它开始以不同的顺序提供它,因为没有明确的顺序。我们使得我们的函数具有相似的循环来提供准确的行编号;没有效率,但是正确。 – UnhandledExcepSean
XQuery *按顺序处理元素,所以如果想要使其更加健壮,请在其中实现一个计数器(XQuery也具有本地节点计数函数,但SQL Server不会实现它们)。 XML节点确实有一个订单。 'ROW_NUMBER()'没有。在实践中,我不知道你是否可以观察到优化器在这里轮流出现 - 如果可能的话,那么可能对于大集合,如果选择了并行计划,但是你的字符串可能太小而不能触发那。 –