0

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

例如

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;

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

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

4

3 回答 3

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

于 2013-10-27T16:19:03.543 回答
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根据上面提到的想法创建一个。

于 2013-10-29T08:49:31.040 回答
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 必须首先读取一百万行。

于 2013-10-28T09:04:50.093 回答