oracle分页查询并返回总记录数据存储过程
### Oracle 分页查询并返回总记录数据存储过程 在数据库应用开发中,为了提高用户体验以及减少服务器负担,分页查询成为了一种常见的技术手段。Oracle 数据库提供了多种方法来实现分页查询,其中使用存储过程是一种高效且灵活的方式。本文将详细介绍如何在 Oracle 中创建一个用于分页查询并返回总记录数的存储过程。 #### 核心概念 1. **存储过程**:存储在数据库中的可编程对象,可以接受参数、执行操作、返回结果。 2. **分页**:通过限制查询结果集的大小来实现对数据的分段显示。 3. **ROWNUM**:Oracle 提供的一个特殊伪列,用来标识查询结果中的行号。 #### 实现步骤 1. **定义存储过程**:创建一个名为 `PageQuery` 的存储过程,接收四个输入参数和两个输出参数。 2. **计算总记录数**:使用 `EXECUTE IMMEDIATE` 动态执行 SQL 语句获取总记录数。 3. **动态生成分页查询语句**:根据当前页码和每页记录数计算出行号范围,并构造分页查询语句。 4. **执行分页查询**:使用动态生成的分页查询语句打开游标返回查询结果。 #### 存储过程代码详解 ```sql CREATE OR REPLACE PACKAGE BODY "PageQuery" IS PROCEDURE UP_PAGEQUERY( p_PageSize IN INT, -- 每页记录数 p_PageNo IN INT, -- 当前页码,从 1 开始 p_SqlSelect IN VARCHAR2, -- 查询语句 p_OutRecordCount OUT INT, -- 总记录数 p_OutCursor OUT refCursorType ) AS v_sql VARCHAR2(3000); v_count INT; v_highRownum INT; v_lowRownum INT; BEGIN -- 获取总记录数 v_sql := 'SELECT COUNT(*) FROM (' || p_SqlSelect || ')'; EXECUTE IMMEDIATE v_sql INTO v_count; p_OutRecordCount := v_count; -- 执行分页查询 v_highRownum := p_PageNo * p_PageSize; v_lowRownum := v_highRownum - p_PageSize + 1; v_sql := 'SELECT * ' || 'FROM ( ' || ' SELECT A.*, ROWNUM rn ' || ' FROM ( ' || p_SqlSelect || ' ) A ' || ' WHERE ROWNUM <= ' || TO_CHAR(v_highRownum) || ' ) B ' || 'WHERE rn >= ' || TO_CHAR(v_lowRownum); -- 打开游标返回查询结果 OPEN p_OutCursor FOR v_sql; END UP_PAGEQUERY; END PageQuery; ``` #### 参数说明 - **p_PageSize**:每页显示的记录数。 - **p_PageNo**:当前页码,默认从 1 开始计数。 - **p_SqlSelect**:原始 SQL 查询语句,不包含 LIMIT 或 OFFSET 关键字。 - **p_OutRecordCount**:输出参数,返回查询到的总记录数。 - **p_OutCursor**:输出参数,返回分页后的查询结果。 #### 使用示例 假设我们有一个 `employees` 表格,并希望实现一个分页查询: ```sql DECLARE l_cursor refCursor; l_total_records INT; BEGIN PageQuery.UP_PAGEQUERY( p_PageSize => 10, p_PageNo => 1, p_SqlSelect => 'SELECT * FROM employees', p_OutRecordCount => l_total_records, p_OutCursor => l_cursor ); -- 处理查询结果 -- ... -- 关闭游标 CLOSE l_cursor; END; ``` #### 注意事项 1. **ROWNUM 的限制**:ROWNUM 仅在查询结果的第一行进行计算,因此需要先使用子查询为每一行添加行号。 2. **性能优化**:在实际应用中,如果查询涉及复杂的连接或过滤条件,考虑使用索引来优化查询性能。 3. **安全性**:当存储过程接收外部输入时,需注意防止 SQL 注入攻击。 通过以上介绍,我们可以看到使用存储过程进行分页查询不仅能够有效提高查询效率,还能够简化应用程序的逻辑处理,是一种非常实用的技术方案。
IS
PROCEDURE UP_PAGEQUERY (p_PageSize INT, --每页记录数
p_PageNo INT, --当前页码,从 1 开始
p_SqlSelect VARCHAR2, --查询语句,含排序部分
p_OutRecordCount OUT INT, --返回总记录数
p_OutCursor OUT refCursorType)
AS
v_sql VARCHAR2 (3000);
v_count INT;
v_heiRownum INT;
v_lowRownum INT;
BEGIN
----取记录总数
v_sql := 'select count(*) from (' || p_SqlSelect || ')';
EXECUTE IMMEDIATE v_sql INTO v_count;
p_OutRecordCount := v_count;
----执行分页查询
v_heiRownum := p_PageNo * p_PageSize;
v_lowRownum := v_heiRownum - p_PageSize + 1;
v_sql :=
'SELECT *
FROM (
SELECT A.*, rownum rn
FROM ('
|| p_SqlSelect
|| ') A
- 码上有财-柏杉科技2014-08-19不错,正是我需要的
- ny0008882013-12-04是一个具体的小例子,如果楼主附加详细说明就OK了
- 粉丝: 0
- 资源: 3
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助