即使在 VB.NET 中使用 ORDER BY 子句,Oracle DataReader 也会被排序

Posted

技术标签:

【中文标题】即使在 VB.NET 中使用 ORDER BY 子句,Oracle DataReader 也会被排序【英文标题】:Oracle DataReader get sorted even with an ORDER BY clause in VB.NET 【发布时间】:2020-03-03 16:38:17 【问题描述】:

我有一个简单的 SELECT 查询:

SELECT id, name FROM myTable ORDER BY id

当我在 Oracle 中执行它时,我首先得到它的排序字母。

ID         NAME

A          ValueA                                       
B          ValueB                                       
C          ValueC                                       
1          Value1                                       
2          Value2                                       
3          Value3                                      

当我在我的 VB 项目中执行它时,即使使用 ORDER BY,数据读取器也会根据我的 CultureInfo 对其进行排序

Dim dictio As New Dictionary(Of String, String)
strQuery = "SELECT id, name FROM myTable ORDER BY id"
rs = New OracleCommand(strQuery, myConnection).ExecuteReader()
Do While (rs.Read())
   dictio.Add(rs.Item(0), rs.Item(1))
Loop

我在字典中的行排序如下:

ID         NAME

1          Value1                                       
2          Value2                                       
3          Value3
A          ValueA                                       
B          ValueB                                       
C          ValueC                        

我猜这个问题来自 .NET 本身,将行放入列表并使用我的 CultureInfo 对行进行排序。

你知道如何摆脱它并告诉它使用原始数据吗?

【问题讨论】:

呃.. 除非您告诉它,否则 VB 不会对数据进行排序,并且您的 VB 中没有任何内容正在排序。 Dictionary(Of T,T) 不是排序集合。您确定您的查询工具和您的 VB 使用相同的 NLS_SORT 吗?在查询工具和 VB 中运行select * from nls_session_parameters where parameter='NLS_SORT'; 并告诉我们结果。在我看来,Oracle 以一种顺序为您的查询工具和另一种顺序为您的 VB 提供数据 【参考方案1】:

无论您的查询的实际技术性以及为什么数据以不同的顺序出现,具体取决于您运行查询所采用的路径,排序数据通常是前端/可视化策略而不是数据库的权限

以任何顺序将您的数据从数据库中提取出来,没有 ORDER BY,然后在您的 VB 中将其排序为您希望向用户显示的任何顺序:

Dim dictio As New SortedDictionary(Of String, String)
                  ^^^^^^
                sort by key


strQuery = "SELECT id, name FROM myTable"
rs = New OracleCommand(strQuery, myConnection).ExecuteReader()
Do While (rs.Read())
   Dim id as String = rs.Item(0).ToString()
   id = Char.IsDigit(id(0)).ToString()(0) + id
   dictio.Add(, rs.Item(1))
Loop

我没有在这里创建自己的比较器,而是选择了修改用于排序的键的廉价而讨厌的方法;所有的字母都会从 Char.IsDigit 返回 False,并且在 ID 前面加上 F 意味着它们在数字前面的 T 之前排序

【讨论】:

【参考方案2】:

感谢您的回答。

我真的不想在我的应用程序中对数据进行排序。 事实上,这个应用程序是一个从 ASP(VB6) 迁移到 ASP.NET(VB.NET) 的应用程序,并且有很多这样的数据读取器。所以我希望找到一个一次性解决所有案例的解决方案。

我试过你给我的查询,它有很大帮助。现在,我很确定我的问题来自于此。

结果如下:

在 Oracle 本身中:法语 在 VB 中,文化设置为 en-US:BINARY 在 VB 中,文化设置为 fr-FR:FRENCH

我的梦想目标是保持我的主要文化为 en-US(主要用于应用程序中的日期),并像执行 fr-FR 一样执行我的查询。

您知道我是否可以通过某种方式执行具有指定文化的查询吗?我找不到一个简单的解决方案...

【讨论】:

这不是答案。请edit您的问题并将此信息添加到其中。然后删除这个答案。

以上是关于即使在 VB.NET 中使用 ORDER BY 子句,Oracle DataReader 也会被排序的主要内容,如果未能解决你的问题,请参考以下文章

子查询中不允许用order by子句,那么应该怎么办?

在 JPA Criteria API 的子查询中使用 ORDER BY 的替代方法是啥?

子查询中的 Order By 的 SQL 错误

在带有 ORDER BY 的子选择中使用 JSON_ARRAYAGG 会出错

UNION ALL、UNION与ORDER BY

mysql使用带有子查询的临时表,但不是group by和order by