需要编写一个程序来获取给定的rownums

时间:2013-10-27 16:04:37

标签: oracle stored-procedures plsql

我需要编写一个过程来选择给定行的记录

例如

procedure test1
(
start_ind number,
end_ind number,
p_out ref cursor
)

begin
opecn p_out for
select * from test where rownum between start_ind and end_ind;
end;

当我们传递start_ind 1和end_ind 10时它正在工作。但是当我们将start_ind更改为5时

然后查询看起来像

select * from test where rownum between 5 and 10;

并且失败并且不显示输出。

请协助解决此问题。谢谢!

3 个答案:

答案 0 :(得分:2)

分配rownum,然后评估where条件。因为你的结果集中永远不会有rownum 1-4,所以你永远不会得到rownum 5.你需要这样的东西:

SELECT * FROM ( 
    SELECT rownum AS rn, t.* 
      FROM (
        SELECT t.*
          FROM test t
         ORDER BY t.whatever
      )
     WHERE ROWNUM <= 10
)
WHERE rn >= 5

您还需要内部选择中的order by子句,或者您获得的行将是未定义的。

Tom Kyte的这篇文章几乎告诉你需要知道的一切:http://www.oracle.com/technetwork/issue-archive/2006/06-sep/o56asktom-086197.html

答案 1 :(得分:1)

SELECT *
  from (SELECT rownum AS rn, t.*
          FROM MyTable t
         WHERE ROWNUM <= 10
        ORDER BY t.NOT-Whatever 
       -- (its highly important to use primary or unique key of MyTable)        
 WHERE rn > 5

作为提示 ,:
通常,我们使用store-procedures进行数据验证,访问控制,需要执行多个SQL语句的大量或复杂处理。存储过程可能返回结果集,即SELECT语句的结果。可以使用游标,其他存储过程,关联结果集定位器或应用程序来处理此类结果集。

我认为您将使用ruw-number来获取分页查询 尝试根据上述想法创建generic select query

答案 2 :(得分:0)

两种可能性:

1)您的表是一个索引组织表。所以它的数据是排序的。您可以选择要避免的第一行,并根据这些行获取您要查找的下一行:

create or replace procedure get_records
(
  vi_start_ind     integer,
  vi_end_ind       integer,
  vo_cursor    out sys_refcursor
) as
begin
  open vo_cursor for
    select * 
    from test
    where rownum <= vi_end_ind - vi_start_ind + 1 
    and rowid not in
    (
      select rowid 
      from test
      where rownum < vi_start_ind
    )
  ;
end; 

2)你的表没有索引组织,通常就是这种情况。然后它的记录没有排序。要获取记录m到n,您必须告诉系统您的记录顺序:

create or replace procedure get_records
(
  vi_start_ind     number,
  vi_end_ind       number,
  vo_cursor    out sys_refcursor
) as
begin
  open vo_cursor for
    select * 
    from test
    where rownum <= vi_end_ind - vi_start_ind + 1 
    and rowid not in
    (
      select rowid from
      (
        select rowid 
        from test
        order by somthing
      )
      where rownum < vi_start_ind
    )
    order by something
  ;
end;

所有这些都说,想想你想要实现的目标。如果要使用此过程来读取块的块,请记住它将一次又一次地读取相同的数据。要知道1,000,001到1,000,100的行是什么,dbms必须先读取一百万行。