现象
前几天,一个客户反映说,他看到的数据顺序是乱的,不是按照日期倒排。
但是在测试环境、预生产环境,都无法重现问题,即使使用相同的程序版本。
定位
查看代码,出问题的功能使用了第三方ORM框架,无法看到实际执行的SQL。
于是,使用SQL Server Profiler(正式服务器没有权限安装软件,只能在测试环境使用)跟踪定位到具体的SQL,拿到正式服务器上运行。问题重现了。
由于数据需要分页显示,于是ORM框架实际使用了ROW_NUMBER
实现:
SELECT TOP (20) T.ROW_NUMBER_0,T.xxx FROM (SELECT xxx,ROW_NUMBER() OVER(ORDER BY DateField DESC) AS [ROW_NUMBER_0]
FROM A WHERE xxx) AS [T] WHERE [T].[ROW_NUMBER_0] > 0
而造成问题的原因就在于,返回的结果不是按ROW_NUMBER_0
排序的。
分析
查看微软官方文档,没有说明要指定排序:
对结果集的输出进行编号。具体来说,返回结果集分区内行的序列号,每个分区的第一行从 1 开始。
看它的意思,返回的编号应该是排序好的。
而且,它自己给的示例也是不指定排序的
这就造成ORM框架实现时没有考虑要指定排序。
结论
解决方案也很简单:指定按RowNumber排序。
后来检查发现,前方是Microsoft SQL Server 2012 (SP1)
,而测试环境用的是Microsoft SQL Server 2014
。同样的SQL,运行效果不一样。GOOGLE了一下,也没发现有相关Bug的内容。
顺便测试了一下EF CORE,它是用OFFSET @P_0 ROWS FETCH NEXT @P_1 ROWS ONLY
方式实现的分页,应该不会再有这个问题了。
最后,提醒大家赶快把测试和生产环境配置统一,避免踩和我同样的坑!
欢迎关注我的个人公众号”My IO“