通用分页使用函数获取牛
中医保健 2021年09月06日 浏览:6 次
通用分页?SQL2005使用CLR函数获取行号
SQL2005使用Row_Number来获取,但这个需要配合Order来处理,数据量大的情况下可能会影响性能。如果你还不知道CLR函数如何使用,到上去搜索一下,或者参考我以前的文章
CLR的C#代码
C# code
using System;
using ta;
using lClient;
using lTypes;
using rver;
/// summary
/// 引用请保留以下信息:
///
/// 用户自定CLR函数,用来生成一个序列
/// by:jinjazz(近身剪)
///
///
/// /summary
public partial class UserDefinedFunctions
{
/// summary
/// 初始化查询标识
/// /summary
public static ctionarystring, long rnList =
new ctionarystring, long();
/// summary
/// 根据标识获取序列
/// /summary
/// param name=\"key\"查询标识/param
/// returns/returns
[lFunction]
public static SqlInt64 GetRowNum(SqlString key)
{
try
{
if (rnList == null)
rnList = new ctionarystring, long();
if (ntainsKey(lue) == false)
d(lue, 1);
return rnList[lue]++;
}
catch
{
return -1;
}
为确保安全 }
/// summary
/// 销毁查询标识
/// /summary
/// param name=\"key\"/param
[lProcedure]
public static void GetRowNumEnd(SqlString key)
{
try
{
if (rnList == null || ntainsKey(lue) == false) return ;
move(lue);
return ;
}
catch
{
}
}
};
部署上面的CLR函数可以运行如下SQL语句,我们在测试环境中部署
SQL codeexec sp_configure \'show advanced options\', \'1\';
go
reconfigure;
go
exec sp_configure \'clr enabled\', \'1\'
go
reconfigure;
exec sp_configure \'show advanced options\', \'1\';
go
--测试数据库
create database testDB
go
use testDB
go
ALTER DATABASE testDB SET TRUSTWORTHY On
go
CREATE ASSEMBLY testAss FROM \'E:\\l\' WITH PERMISSION_SET = UnSAFE;
--
go
CREATE FUNCTION tRowNum
(
@key nvarchar(100)
)
RETURNS bigint
AS EXTERNAL NAME testAss.[UserDefinedFunctions].GetRowNum
go
CREATE proc tRowNumEnd
(
@key nvarchar(100)
)
AS EXTERNAL NAME testAss.[UserDefinedFunctions].GetRowNumEnd
接下来我们做个简单测试,如下sql语句
SQL code--获取带行号的结果
select *,rn=tRowNum(1) from sysobjects
--清理结果
exec GetRowNumEnd 1
你就能看到一行带行号的结果了,当然别忘了查询之后把key清理掉,否则下次的1为key的序列行号就不是从1开始了。
是不是这个语法比row_number函数简练而且方便了很多呢?
下面我们来看一个具体测试用例,比如分页。分页就是看行号在某个范围内,但是这里不推荐用where 行号 between and,因为这个是函数,用where会引起全表计算,改为 top和where 行号起始 就可以了,这样效率只和起始值有关系。
我们测试用系统表syscolumns,数据太少多做几次全交叉就可以了,比如
SQL codeselect count(*) from syscolumns a,syscolumns b,syscolumns c
--
这个数据量算是比较bt了,7千500万...最关键的是他没有主键,没有排序规则定义,这么一个东西用以前的分页方法是很难处理的。现在却很简单
SQL codedeclare @key varchar(100)
set @key=newid()
select top 10 * from(
select a.* ,tRowNum(@key) as rn
from syscolumns a,syscolumns b,syscolumns c)t
where rn 200000
exec tRowNumEnd @key
返回第200001到200010之间的10条数据,只需要1秒。当然如果用这个方法返回的是7千万的最后几条数据还是比较慢的。
总结一下这个方法:
优点是:
性能和表结构无关,而且还是比较可靠。
代码简单易懂。
通用性比较很好,任何查询,只要在字段后面把函数调用一下,再在外部嵌套一个top n和where 就可以了。
值得商榷的环节:
因为不能反过来计算序列,所以大量数据的后面页会比较慢。
序列是通过key来控制的,key的初始化代码必须严格控制,否则并发会有问题,不过guid是一定保险的
CLR的部署问题,不过你可以把他部署到类似master库中,其他库都去master引用,这样可以方便些。
因为没有经过实际使用的考验,所以还有可能考虑不周到的地方,希望大家提出指正,个人觉得这个方法还是很有潜力可挖的。
乌鲁木齐治疗妇科哪家好吃什么止泻快
重庆不孕不育医院

- 上一篇: 通用数据库查询语句精华使用简介覆盖
- 下一篇 通用分页存储过程呢
-
鬼臼叶的功效与作用
2019-07-16
-
王伯岳百年诞辰学术研讨会召开
2019-07-15
-
国务院办公厅发文促健康医疗大数据应用
2019-07-12
-
临床基地激发中医院活力
2019-07-12
-
中医是一些减肥方案
2019-07-12
-
中医脐疗减肥法安全有效吗
2019-07-07