Oracle 过程分页带来比预期更多的行
Posted
技术标签:
【中文标题】Oracle 过程分页带来比预期更多的行【英文标题】:Oracle procedure pagination bringing back more rows than expected 【发布时间】:2021-04-27 01:12:49 【问题描述】:这是一个用于示例目的的简化程序。我遇到的问题是,当我转到应用程序的下一页时,它会带回 5 个,然后是 10 个,然后是 15 个,然后是 10 个。我每次只想带回 5 个。它似乎发生在日期递减时。
procedure GET_DATA( p_sort_col IN VARCHAR2, p_sort_order IN VARCHAR2,
p_page_index IN NUMBER DEFAULT null,
p_page_size IN NUMBER DEFAULT null, p_cursor out l_cursor)
AS
begin
OPEN p_cursor FOR
select * from (
select* from (select rownum rn, Name, DateCol, ROW_NUMBER() Over( ORDER BY
CASE
WHEN p_sort_col = 'Name' and p_sort_order = 'asc' THEN
Name
END ASC,
CASE
WHEN p_sort_col = 'DateCol' and p_sort_order = 'asc' THEN
DateCol
END ASC,
CASE
WHEN p_sort_col = 'Name' and p_sort_order = 'desc' THEN
Name
END DESC,
CASE
WHEN p_sort_col = 'DateCol' and p_sort_order = 'desc' THEN
DateCol
END DESC) from gdpr_document_manager_audit
) where rownum < ((p_page_index * p_page_size) + 1 )
)WHERE rn >= (((p_page_index-1) * p_page_size));
END GET_DATA;
实际查询
【问题讨论】:
没有排序的分页没有什么意义。 @TheImpaler 它有排序看关键词的顺序? 我只能在ROW_NUMBER()
函数中看到ORDER BY
。但是,它不会影响结果集的排序。
@TheImpaler 实际上是。
@TheImpaler 当我进入应用程序的下一页时,它首先对结果集进行排序然后对其进行分页,感谢您的输入,关于分页问题有什么真正有用的建议吗?
【参考方案1】:
我假设
select event_type, doc_page, application_number,
document_reference, username, application_year,
full_name, date_and_time
from gdpr_document_manager_audit
ORDER BY
CASE
WHEN p_sort_col = 'EventType' and p_sort_order = 'asc' THEN event_type
WHEN p_sort_col = 'ApplicationYear' and p_sort_order = 'asc' THEN application_year
WHEN p_sort_col = 'ApplicationNumber' and p_sort_order = 'asc' THEN application_number
WHEN p_sort_col = 'DocumentReference' and p_sort_order = 'asc' THEN doument_reference
WHEN p_sort_col = 'Username' and p_sort_order = 'asc' THEN username
WHEN p_sort_col = 'Name' and p_sort_order = 'asc' THEN full_name
END ASC,
CASE
WHEN p_sort_col = 'DateAndTime' and p_sort_order = 'asc' THEN date_and_time
END ASC,
CASE
WHEN p_sort_col = 'EventType' and p_sort_order = 'desc' THEN event_type
WHEN p_sort_col = 'ApplicationYear' and p_sort_order = 'desc' THEN application_year
WHEN p_sort_col = 'ApplicationNumber' and p_sort_order = 'desc' THEN application_number
WHEN p_sort_col = 'DocumentReference' and p_sort_order = 'desc' THEN document_reference
WHEN p_sort_col = 'Username' and p_sort_order = 'desc' THEN username
WHEN p_sort_col = 'Name' and p_sort_order = 'desc' THEN full_name
END DESC,
CASE
WHEN p_sort_col = 'DateAndTime' and p_sort_order = 'desc' THEN date_and_time
END DESC
按照你想要的顺序返回你想要的数据,只是没有分页。为简单起见,我将在下面的答案中将此查询称为#base_query#
。如果是这样,并且鉴于您需要支持旧版本的 Oracle,您可以将其转换为分页查询
select *
from ( select /*+ FIRST_ROWS(n) */
a.*, ROWNUM rnum
from ( #base_query# ) a
where ROWNUM <= ((p_page_index * p_page_size) + p_page_size ) )
where rnum >= (((p_page_index-1) * p_page_size));
使用您对要返回的最小和最大行的计算。您还没有告诉我们您为各种参数传递了什么值。如果我们猜测p_page_index
是第一页的 1(有些人使用基于 0 的索引),那么您可能实际上想要
select *
from ( select /*+ FIRST_ROWS(n) */
a.*, ROWNUM rnum
from ( #base_query# ) a
where ROWNUM <= (p_page_index * p_page_size)
where rnum >= (p_page_index-1) * p_page_size + 1;
因此,如果 p_page_index
= 1 和 p_page_size
= 10,您将获得第 1 到 10 行。如果 p_page_index
= 2 和 p_page_size
= 10,您将获得第 11 到 20 行。依此类推。
【讨论】:
还是有同样的问题,问题是分页的计算。 @贾斯汀洞穴 @PaulDocks - 看起来你试图编辑我的回复说你得到了你想要的。但是后来加了评论说还是有问题。 是的,抱歉,也想删除实际的查询。我仍然有同样的问题。问题是分页逻辑。 @贾斯汀洞穴 @PaulDocks - 我对您为参数传递的值做了一些猜测,并更新了我的答案。如果您使用基于 0 的索引,那就不同了。为最小和最大行创建局部变量可能更容易,然后您可以打印出来/检查以进行调试。 1,2,3,4 等用于页面索引,5 用于页面大小每次@JustinCave以上是关于Oracle 过程分页带来比预期更多的行的主要内容,如果未能解决你的问题,请参考以下文章
Oracle SQL - 从视图中选择比在视图中运行选择更多的行