您的位置:首页 > 数据库

sql 学习之主键选择、简单分页存储过程

2012-02-10 16:53 555 查看
lSQLServer中两种常用的主键数据类型:int(或bigint)+标识列(又称自动增长字段);uniqueidentifier(又称Guid、UUID)
l用标识列实现字段自增可以避免并发等问题,不要开发人员控制自增。用标识列的字段在Insert的时候不用指定主键的值。将字段的“是标识列”设置为“是”,一个表只能有一个标识列。
lGuid算法是一种可以产生唯一标识的高效算法,它使用网卡MAC、地址、纳秒级时间、芯片ID码等算出来的,这样保证每次生成的GUID永远不会重复,无论是同一个计算机上还是不同的计算机。在公元3400年以前产生的GUID与任何其他产生过的GUID都不相同。SQLServer中生成GUID的函数newid(),.Net中生成Guid的方法:Guid.NewGuid(),返回是Guid类型。
l(*)Int自增字段的优点:占用空间小、无需开发人员干预、易读;缺点:效率低;数据导入导出的时候很痛苦。
l(*)Guid的优点:效率高、数据导入导出方便;缺点占用空间大、不易读。
l业界主流倾向于使用Guid。
//首先创建一个存储过程,传入两个值,@i代表的是第几页,@j代表的是一页有多少个数据行

create proc fenye @i int ,@j int

as

select * from

//通过Row_number 给每行添加行标识

(select row_number()over(order by id) as RI,* from Student) as a

//这一行主要是分页的算法

where RI>(@i-1)*@j and RI<=(@i)*@j

//执行存储过程

exec fenye 2,5

附传智播客邹老师的分页sql语句(我的是参考邹老师的,写出一个简单的)

过程一:

select top N条记录 * from 文章表 where id not in(select top M条记录 id from 文章表 order by id desc ) order by id desc

过程二:

select top N条记录 * from 文章表 where id <(select min(id) from (select top M条记录 id from 文章表 order by id desc ) as tblTmp) order by id desc

--简单通用

CREATE PROCEDURE [dbo].[PageView]

@select VARCHAR(max),

@CurrentPage INT,

@PageSize INT

AS

BEGIN

declare @sql NVARCHAR(max)

DECLARE @RecordCurrent INT

DECLARE @PageCount INT

DECLARE @RecordCount INT

SET NOCOUNT ON

set @sql='select @RecordCount=count(*) from ('+@select+') a'

exec sp_executesql @sql,N'@RecordCount int output',@RecordCount output

SET @PageCount=(@RecordCount+@PageSize-1)/@PageSize

IF ISNULL(@CurrentPage,0)<1

SET @CurrentPage=1

ELSE if ISNULL(@CurrentPage,0)>@PageCount

SET @CurrentPage=@PageCount

SELECT @CurrentPage AS CurrentPage,@RecordCount AS RecordCount,@PageSize AS PageSize,@PageCount AS PageCount

set @sql='select * from ('+@select+') a where rownumber between '+cast((@CurrentPage-1)*@PageSize+1 as varchar)+' and '+cast(@CurrentPage*@PageSize as varchar)

exec (@sql)

END

--使用not in 方式的存储过程

create PROCEDURE GetPageDataByNotIn

@PageIndex int,/**//*当前页数*/

@PageSize int/**//*每页大小*/

AS

declare @starttime datetime

set @starttime=getdate()

IF @PageIndex > 0

BEGIN

set nocount on;

DECLARE @PageLowerBound int

DECLARE @StartID int

DECLARE @sql varchar(225)

SET @PageLowerBound = @PageSize * (@PageIndex-1)

IF @PageLowerBound<1

SET @PageLowerBound=1

print @PageLowerBound

select top (@PageSize) * from table where [ar_id] not in (select top ((@PageSize)*(@PageIndex-1)) ar_id from table )

EXEC(@sql)

set nocount off;

END

print '耗时='+convert(varchar(30),datediff(ms,@starttime,getdate()))

-------------------------------------------------------------------------------------------------------

--使用ROWCOUNT的分页存储过程

create PROCEDURE GetPageData

@PageIndex int,/**//*当前页数*/

@PageSize int/**//*每页大小*/

AS

declare @starttime datetime

set @starttime=getdate()

IF @PageIndex > 0

BEGIN

set nocount on;

DECLARE @PageLowerBound int

DECLARE @StartID int

DECLARE @sql varchar(225)

SET @BeginIndex = @PageSize * (@PageIndex-1)

IF @BeginIndex<1

SET @BeginIndex=1

SET ROWCOUNT @BeginIndex

SELECT @StartID = [ar_id] FROM table ORDER BY ar_id

print @StartID

SET ROWCOUNT 0

SET @sql='select top '+str(@PageSize) +' * from table where [ar_id]>='+ str(@StartID) +' ORDER BY [ar_id] '

EXEC(@sql)

set nocount off;

END

print '耗时='+convert(varchar(30),datediff(ms,@starttime,getdate()))

-----------------------------------------------------------------------------------------------------

测试查询一张有100W条数据的表table,每页显示10条数据

存储过程 第1页 第10页 第100页 第1000页 第5000页

GetPageDataByNotIn 0 0 126 13530 等了2分多钟没耐性了....

GetPageData 0 0 0 16 76

------------------------------------------------------------------------------------------------------------

最后使用的存储过程(推荐):

create PROCEDURE GetPageData

(

@TableName varchar(30),--表名称

@IDName varchar(20),--表主键名称

@PageIndex int,--当前页数

@PageSize int--每页大小

)

AS

IF @PageIndex > 0

BEGIN

set nocount on

DECLARE @PageLowerBound int,@StartID int,@sql nvarchar(225)

SET @PageLowerBound = @PageSize * (@PageIndex-1)

IF @PageLowerBound<1

SET @PageLowerBound=1

SET ROWCOUNT @PageLowerBound

SET @sql=N'SELECT @StartID = ['+@IDName+'] FROM '+@TableName+' ORDER BY '+@IDName

exec sp_executesql @sql,N'@StartID int output',@StartID output

SET ROWCOUNT 0

SET @sql='select top '+str(@PageSize) +' * from '+@TableName+' where ['+@IDName+']>='+ str(@StartID) +' ORDER BY ['+@IDName+'] '

EXEC(@sql)

set nocount off

END

新添加的

create PROCEDURE GetPageDataOutRowPageCount

(

@PageIndex int = 1,--当前页数

@PageSize int = 7,--每页大小

@RowCount int output,--总行数(传出参数)

@PageCount int output--总页数(传出参数)

)

AS

begin

DECLARE @sql NVARCHAR(225),@sqlCount NVARCHAR(225)

select @RowCount =COUNT(SID),@PageCount=CEILING((COUNT(SID)+0.0)/@PageSize) FROM Students

SET @sql='SELECT TOP '+str(@PageSize) +' * FROM Students where SID not in(select top '+str((@PageIndex-1)*@PageSize) +' SID from Students)'

print @sql

EXEC(@sql)

end

declare @Rr int ,@Rc int

exec GetPageDataOutRowPageCount 3,3,@Rr output,@Rc output

select @Rr,@Rc
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: