sql 学习之主键选择、简单分页存储过程
2012-02-10 16:53
447 查看
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
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
相关文章推荐
- sql 学习之主键选择、简单分页存储过程
- 简单 sql 分页学习
- SQL 数据库 学习 007 通过一个示例简单介绍什么是字段、属性、列、元组、记录、表、主键、外键
- 非常简单的分页存储过程sql
- SQl 分页语句 和 简单的 存储过程分页
- SQL 数据库 学习 007 通过一个示例简单介绍什么是字段、属性、列、元组、记录、表、主键、外键 (上)
- SQL分页语句及简单的SQL分页存储过程
- SQL 数据库 学习 007 通过一个示例简单介绍什么是字段、属性、列、元组、记录、表、主键、外键 (上)
- SQL简单的分页存储过程
- SQL学习(时间,存储过程,触发器)
- 简单的sql分页语句,觉得好就收藏吧
- MS SQL Server 存储过程学习(2)数据库存储过程详解
- SQL -- 简单语句学习总结7条
- 简单的SQL语句学习资料 经典SQL语句(上)
- 强大的DataGrid组件[6]_调用存储过程服务端分页——Silverlight学习笔记[14]
- php入门学习知识点二 PHP简单的分页过程与原理
- sql2005 存储过程实现分页
- sql2005中的简单分页方法
- oracle 中 Procedues (存储过程) 简单的分页。
- [存档]支持DISTINCT的通用分页存储过程(SQL2005)