利用存储过程进行分页

在开发中我们经常以列表的方式进行数据的访问,当访问的数据量非常的大的时候

我们就要进行分页,其中的一种方式就是利用存储过程进行分页。

环境:netbeans7.1 ,jdk 1.7 ,sqlserver 2008,tomcat 7

1.       存储过程的编写:

CREATE PROCEDUREproduce

@sqlstrnvarchar(4000),--查询字符串

@currentpageint,--N

@pagesizeint--每页行数

AS

BEGIN

         SETNOCOUNTON;

         declare--声明变量

         @P1int,-- 游标的ID

         @rowcountint,--总行记录

         @totalpageint--总页数

execsp_cursoropen@P1output,@sqlstr,@scrollopt=1,@ccopt=1,@rowcount=@rowcountoutput

set@totalpage=CEILING(1.0*@rowcount/@pagesize)--计算总页数

select@currentpageascurrpage,@totalpageastotalpage,@rowcountastotalrow--查出需要的值

if@currentpage>@totalpageset@currentpage=@totalpage--当前页码不能大于总页数

set@currentpage=(@currentpage-1)*@pagesize+1

execsp_cursorfetch@P1,16,@currentpage,@pagesize

execsp_cursorclose@P1

setnocountoff

END

系统参数说明:

 

/**

sp_cursoropen

系统参数,打开游标。sp_cursoropen定义与游标和游标选项相关联的 SQL 语句,然后填充游标。

sp_cursoropen等效于 Transact-SQL 语句 DECLARE_CURSOR OPEN 的组合。

此过程通过在表格格式数据流 (TDS) 数据包中指定 ID = 2 来调用。

参数说明:

cursor:@P1 游标 id SQL Server 生成的游标标识符 cursor 是一个具有int返回值的必需参数。

stmt:@sqlstr定义游标结果集的必需参数

scrollopt:@scrollopt滚动选项。scrollopt是一个可选参数.需要int输入值  0x0001 对应 KEYSET

ccopt @ccopt并发控制项 0x0001 对应 READ_ONLY

rowcount@rowcount要用于 AUTO_FETCH 的提取缓冲区行数。默认值为 20 行。

**/

/**

sp_cursorfetch

从数据库中提取由一行或多行组成的缓冲区。此缓冲区中的行组称为游标的提取缓冲区。可通过在表格格式数据流 (TDS) 包中指定 ID = 7 来调用sp_cursorfetch

参数说明:

cursor@P1 游标的ID

fetchtype : 16

rownum: @currentpage

nrows :@pagesize

**/

/**

sp_cursorclose:

关闭游标并取消游标分配,以及释放所有关联资源;

**/

Java代码:

package Service;

 

importjava.sql.*;

 

public class Procedure {

         private Connection con;

         publicResultSetrs;

         privateCallableStatementcallsta;

         private String use = "sa";

         private String pwd = "123";

 

         public Procedure() {

                   try {

                            // 连接数据库驱动

                            Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");

                            String str = "jdbc:sqlserver://localhost:1433;databasename=tutorial";

                            con = DriverManager.getConnection(str, use, pwd);

                            // 设置存储过程参数

                            String st = "{call produce(?,?,?)}";

                            callsta = con.prepareCall(st);

                            callsta.setString(1, "select * from product");

                            callsta.setInt(2, 1);

                            callsta.setInt(3, 3);

                            // 循环输出调用存储过程的记录结果

                            StringBuffersb=new StringBuffer();

                            intrsNum=0;//统计结果集的数量

                            intupdateCount = -1;

                            boolean flag = callsta.execute();// 这个而尔值只说明第一个返回内容是更新计数还是结果集。

                            do {

                                     updateCount = callsta.getUpdateCount();

                                     if (updateCount != -1) {// 说明当前行是一个更新计数

                                               // 处理.

                                               System.out.println("..说明当前行是一个更新计数..");

                                               callsta.getMoreResults();

                                               continue;// 已经是更新计数了,处理完成后应该移动到下一行

                                               // 不再判断是否是ResultSet

                                     }

                                     rs = callsta.getResultSet();

                                     if (rs != null) {// 如果到了这里,说明updateCount == -1

                                               // 处理rs

                                               rsNum++;

                                               System.out.println("统计结果集的数量:"+rsNum);

                                               if (rs != null) {

                                                        ResultSetMetaDatarsmd = rs.getMetaData(); // 获取字段名

                                                        intnumberOfColumns = rsmd.getColumnCount(); // 获取字段数

                                                        inti = 0;

                                                        while (rs.next()) { // 将查询结果取出

                                                                 for (i = 1; i<= numberOfColumns; i++) {

//                                                                        System.out.println(rs.getInt("总页数"));

                                                                           String date = rs.getString(i);

                                                                           sb.append(date+" ");

                                                                 }

                                                        }

                                                        rs.close();

                                               }

                                               callsta.getMoreResults();

                                               continue;

                                               // 是结果集,处理完成后应该移动到下一行

                                     }

                                     // 如果到了这里,说明updateCount == -1 &&rs == null,什么也没的了

                                     System.out.println(sb.toString());

                            } while (!(updateCount == -1 &&rs == null));

                            // callsta.getXXX(int);//获取输出参数

                   } catch (Exception e) {

                            e.printStackTrace();

                   }

         }

         public static void main(String[] age) {

                   Procedure pro = new Procedure();

         }

}

转载于:https://my.oschina.net/u/249616/blog/42795

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值