我需要编写一个过程来选择给定行的记录
例如
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;
并且失败并且不显示输出。
请协助解决此问题。谢谢!
答案 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必须先读取一百万行。