我们使用一个小的sql函数,它通过某个分隔符拆分字符串并在表中返回这些值。
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
);
问题是,这是否可以改变字符串中元素的顺序?
实施例。
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服务器上重现相同的错误,但没有任何运气。你的评论和回答让这个蠢货更加内疚。
答案 0 :(得分:1)
通常,select语句将始终返回未排序的结果集。所以你问的一般答案是:是的,你的select语句可以返回任何元素的顺序。这将确认SQL标准。 (最好不要相信任何其他事情。)
但是:你在你的函数中放了一个隐含的顺序。此顺序由XML-Fragment中的-elements顺序生成。此XML按照您构造转换为XML的字符串的顺序进行处理。这被用作交叉申请的右侧(您不能使用此处并且不需要任何订单)。因此,您的问题的答案是:不,您的select语句将始终返回给定的元素顺序。
答案 1 :(得分:1)
更多信息,不适合评论:
该问题的最小陈述类似于
SELECT x.i.value('(./text())[1]', 'varchar(100)') as Item
FROM
(SELECT CONVERT(XML, '<i>1</i><i>2</i>') as [XML]) AS a
CROSS APPLY [XML].nodes('i') AS x(i);
问题归结为:结果可能按此顺序排列吗?
2
1
此查询的执行计划如下所示:
|--Compute Scalar(DEFINE:([Expr1011]=[Expr1010]))
|--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1000], XML Reader with XPath filter.[id]))
|--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1000]))
| |--Constant Scan(VALUES:((CONVERT(xml,'<i>1</i><i>2</i>',0))))
| |--Filter(WHERE:(STARTUP EXPR([Expr1000] IS NOT NULL)))
| |--Table-valued function
|--Stream Aggregate(DEFINE:([Expr1010]=MIN(CASE WHEN [Expr1000] IS NULL THEN NULL ELSE CASE WHEN datalength(XML Reader with XPath filter.[value])>=(128) THEN CONVERT_IMPLICIT(varchar(100),XML Reader with XPath filter.[lvalue],0) ELSE CONVERT_IMPLICIT(varchar(100),XML Reader with XPath filter.[value],0) END END)))
|--Top(TOP EXPRESSION:((1)))
|--Compute Scalar(DEFINE:([Expr1009]=0x58))
|--Filter(WHERE:(XML Reader with XPath filter.[id]=getancestor(XML Reader with XPath filter.[id],(1))))
|--Table-valued function
也许有理由使用来自XML Reader的数据对嵌套循环中的元素进行排序,但这不确定,也没有关于此的文档。
甚至没有找到关于这个问题的文档:如何在不改变XML结构的情况下正确保持排序(即在XML中添加排序键)?