SQLDataReader 排序顺序与存储过程顺序

Posted

技术标签:

【中文标题】SQLDataReader 排序顺序与存储过程顺序【英文标题】:SQLDataReader sort order versus Stored procedure order 【发布时间】:2015-11-22 06:07:26 【问题描述】:

我有一个存储过程,其中包含用于返回我的记录的ORDER BY 子句。 当我在 SQL 中执行时,我会看到适当的顺序。

但是,当我从客户端执行并加载到 SqlDataReader 时,顺序发生了变化。这不是预期的结果。我得到了相同的记录,但是顺序(或者可能是它排序的列)发生了变化。

是什么在操纵这个?或者,我该怎么做才能在客户端的阅读器上应用ORDER BY

SP 中最后的 SELECT 是:

SELECT DISTINCT
     TotalMatchCount 
    ,ExampleDescription as Description 
    ,ExampleMatchCount 
    ,ExampleLevenshtein 
    ,Code6 as Code
    ,Tier1Code 
    ,Tier1Description 
    ,Tier1MatchCount 
    ,Tier1Levenshtein 
    ,Tier2Code 
    ,Tier2Description 
    ,Tier2MatchCount 
    ,Tier2Levenshtein 
    ,Tier3Code 
    ,Tier3Description 
    ,Tier3MatchCount 
    ,Tier3Levenshtein 
FROM  
    @SearchResults 
Order by 
     ExampleMatchCount Desc 
    ,ExampleLevenshtein ASC 
    ,Tier3MatchCount DESC 
    ,Tier3Levenshtein ASC 
    ,Tier2MatchCount DESC 
    ,Tier2Levenshtein ASC 
    ,Tier1MatchCount DESC 
    ,Tier1Levenshtein ASC 

结果可能在哪里(仅给出主要描述字段):

getting hh child ready for school helping hh child with a school project waiting for school bus with hh child etc.

在调用 SP 的客户端上:

Private SearchRDR As System.Data.SqlClient.SqlDataReader

Dim db As DBAccess = New DBAccess
Dim rdr As System.Data.SqlClient.SqlDataReader

    Try
        db.AddParameter("@pSearchText", _SearchText)
        rdr = db.ExecuteReader("sprc_SEL_Search")

        If rdr.HasRows Then
            'Get the data into the reader object
            SearchRDR = rdr

此时我已经检查了rdr 中的值,它们已经出现故障。但是在我的代码中,当我去加载一个数据网格视图时,我从它的类中拉出rdr 并加载值:

Dim rdr As System.Data.SqlClient.SqlDataReader
rdr = cSearch.SearchRDR

Try
    If rdr.HasRows Then

        While rdr.Read()
            dgvSearch.Rows.Add(rdr("mycolumn").ToString() 
. . . . . . . .

但如前所述,它在到达这里之前已经出现故障。我看到的结果类似于:

waiting for school bus with nonhh child dropping off nonhh child at friend's house waiting for school bus with hh child

这不是上面显示的顺序。事实上,SQL 中的第一项显示在阅读器中大约位置 4(第 4 行)。然后第二个 SQL 项出现在第 6 行。

最终,客户的订单不会发生变化。它只是没有使用服务器指定的顺序。

【问题讨论】:

请贴出代码、想要的结果和你得到的实际结果。 存储过程中的ORDER BY 子句会影响SqlDataReader 读取它们的顺序。如果它不以这种方式工作,那将是一个意外行为,如果没有一个重复该行为的代码的工作示例,就无法诊断。 阅读器不会改变记录的顺序。 “最终选择”是什么意思?存储过程可以有很多选择,它们都将传递给阅读器。您可以通过reader.NextResult 访问它们。那么,如果您有多个selects,您可能会访问错误的结果吗? 在您检查阅读器中的行顺序时,它们已经错了,但在您开始阅读结果之前......这是不可能的。这并不是说我怀疑你的顺序是错误的。这是不可能的,因为数据读取器没有要检查的行。 它只是一次从服务器读取行,直到没有更多要读取的行。它只对单个记录和一个迭代器进行建模。 在这种情况下,很多时候,当您测试应用程序与直接执行 SP 时,您可能只是连接到不同的数据库,或者在您的情况下 - 表。这种可能性我已经看过太多次了。 【参考方案1】:

ADO DB 对象具有内置的 RowFilter 和 Sort 属性,可以在将对象分配给数组之前直接将其应用于 SQLDataReader 对象。因此,即使 SQL 存储过程未按预期顺序返回行,您也可以在获取从 ADO DB 对象返回的记录集后获得正确的顺序。

rdr.Sort = "ExampleMatchCount Desc"

【讨论】:

以上是关于SQLDataReader 排序顺序与存储过程顺序的主要内容,如果未能解决你的问题,请参考以下文章

列表查找及二分查找

数据结构与算法:树 顺序存储二叉树

动图演示堆排序

查找和排序的基本操作:查找排序算法大集合

顺序表A和B的合并与排序

MySQL错误的排序顺序 - 忽略第一列