【问题标题】:Implement Oracle Paging For ANY Query?为任何查询实施 Oracle 分页?
【发布时间】:2011-07-29 07:50:28
【问题描述】:

我在 Oracle 中找到了很多分页示例。我现在正在使用的特定的看起来像这样:

SELECT * FROM (
  SELECT a.*, ROWNUM RNUM FROM (
    **Select * From SomeTable**) a 
  WHERE ROWNUM <= 500) b 
WHERE b.RNUM >= 1

粗体线代表“原始”查询。其余的 SQL 用于实现分页。我遇到的问题是一个本身完全有效的查询;当我将它放在我的分页代码中时会失败。

举个例子——这个查询会失败:

SELECT TABLE1.*, TABLE1.SomeValue FROM TABLE1

出现不明确的列错误。但是,没有我的额外代码;它会运行得很好。我有大量“已保存”查询,但我必须确保我的分页解决方案不会使它们无效。

我使用 SQL Developer 作为我的 Oracle 查询工具,它设法实现了分页,即使上述查询在我将其包装在分页代码中时也会失败。谁能告诉我他们是怎么做到的?

【问题讨论】:

  • 无论如何,您通常不应该在生产代码中使用“SELECT *”。枚举内部查询中的所有列以消除歧义,从而使查询对架构更改具有弹性(例如,将列添加到表中时)。

标签: database oracle pagination paging


【解决方案1】:

首先,原始查询需要有一个 ORDER BY 子句才能使分页解决方案合理工作。否则,Oracle 为第一页、第二页和第 N 页返回相同的 500 行是完全有效的。

SQL Developer 不会更改您的查询来实现分页。它只是将完整的查询发送到 Oracle 并使用 JDBC 对结果本身进行分页。 JDBC 客户端应用程序可以指定一个fetch size,它控制一次从数据库返回到客户端的行数。然后,客户端应用程序可以等待用户决定转到下一页或执行其他操作,在这种情况下光标关闭。

SQL Developer 方法是否有意义在很大程度上取决于您的应用程序的架构。如果您尝试在无状态 Web 应用程序中对数据进行分页,它可能不起作用,因为您不会在多个页面请求之间保持数据库会话打开。另一方面,如果你有一个带有专用 Oracle 数据库连接的胖客户端应用程序,那是相当合理的。

【讨论】:

    【解决方案2】:

    首先, 这样做有什么意义

    SELECT TABLE1.*, TABLE1.someValue from TABLE1
    

    TABLE1.* 不会自动选择“someValue”,为什么要冗余查询呢?

    其次对于分页,尝试分析查询方式

    SELECT * FROM {
        SELECT col1, col2, col3
        , row_number() OVER (order by col1) position
        FROM TABLE1
    } WHERE rn >= p_seek and rn < (p_seek+p_count)
    

    p_seek 是起始位置,p_count 是要获取的行数。

    在这里,您可以使用 TABLE1.*、TABLE1.someValue 等代替 col1、col2、col3 等。

    【讨论】:

    • 这里的想法是不要通过我的操作来破坏其他有效的查询。 Oracle/SQL 允许用户选择冗余数据,所以我想要一个支持它的分页解决方案。
    猜你喜欢
    • 2019-07-04
    • 1970-01-01
    • 2015-06-07
    • 2013-09-29
    • 1970-01-01
    • 1970-01-01
    • 2011-08-27
    • 2018-10-13
    • 2013-09-24
    相关资源
    最近更新 更多