前言
好长时间没摸数据库了,周末在家写了个报表的存储过程,一时间对使用存储过程实现分页的同时并计算出记录总数不知道怎么更好的去实现。按照我们正常的业务逻辑,存储过程数据首先是分页,其次接受若干查询条件,返回分页结果集的同时还需要返回记录总数给客户端。
我对于这样一个业务存储过程总结如下:1、内核层,通常也就是要查询的字段或者要计算的字段,这部分单独拿出来。 2、查询条件层。 如果内核只是查询一些字段的话,条件可以放在查询条件层拼接。 如果内核层完全是统计业务逻辑,那么查询条件则必须要放在内核层,像我们常用的SUM、GROUPBY 业务。 3、添加分页参数(也就是我们现在多数用的ROW_NUMBER添加rn参数)。 存储过程里我们一般会单独声明每个部分的变量用于执行时拼接。
存储过程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
CREATE proc [dbo].[usp_manyidu] ( @seatno nvarchar(30), @pageIndex int , @pageSize int , @rsCount int out ) as begin declare @sql nvarchar( max ) --拼接内核SQL declare @ where nvarchar( max )= ' where 1=1' --查询条件拼接字符串 declare @cols nvarchar( max ) --查询字段、计算字段 declare @sort nvarchar(50) --排序 set @sql= ' from dbo.log where seatno is not null and seatno<>' '' ' group by seatno ' set @cols= 'seatno,SUM(case when manyidu=0 then 1 else 0 end) as manyi, SUM(case when manyidu=1 then 1 else 0 end) as yiban, SUM(case when manyidu=2 then 1 else 0 end) as bumanyi, SUM(case when manyidu IS null or manyidu=' '' ' then 1 else 0 end) as weipingjia' set @sort= 'order by seatno' if(@seatno <> '' ) set @ where += ' and seatno=' +@seatno declare @strSQL nvarchar( max ) set @strSQL=N 'select * from (select ROW_NUMBER() over(' +@sort+ ') as tmpid,* from( select * from (select ' +@cols+@sql+ ') as tmpTable1' +@ where + ') as tmpTable2) as tmpTable3' + ' where tmpid between ' +STR((@pageIndex-1)*@pageSize+1)+ ' and ' +STR(@pageIndex*@pageSize) print @strSQL exec (@strSQL) set @strSQL= 'select @total=count(*) from (select ' +@cols+@sql+ ') as tmpTable' +@ where print @strSQL exec sp_executesql @strSQL,N '@total int out' ,@total=@rsCount out end GO |