要求将一张用户数据清单表,首先按照分公司进行分开,然后将这些以分公司为单位的集合,再平均分到若干张表中去。
按照分公司分开是很简单的,不管是按照区域列来分类,还是按照HLR码表来匹配,一句话可以解决。关键就是按照分公司分开后,怎么将一张表的数据平均分配到若干张表中去。
思路如下:
如果这若干张表,若干为素数,例如若干为13,增加一列序号,将序号除13取余,余0的记录行插入表0,余1的记录行插入表,…………,余12的记录行插入表12,那么通过稍复杂的sql语句组合,也可以得到想要的结果。
如果这若干张表,假如有6张表,10张表呢,上述办法就行不通了,这时候,自然也就想到了利用游标来实现。
其中关键部分如下:
declare cursor_1001 cursor keyset for
select number from t_1001 **定义游标
open cursor_1001 **打开游标
declare @i varchar(11) **定义变量i
fetch first from cursor_1001 into @i **将游标指向第一行,并将该行游标内容赋值给i
while (@@fetch_status=0) **开始循环(条件为判断游标所处是否为最后一行)
begin
insert into temp_1001 values(@i) **将i值插入临时表temp_1001
fetch from cursor_1001 into @i **将游标指向下一行,并将下一行游标内容赋值给i
if @@fetch_status=0 **判断游标所处是否为最后一行
insert into temp_1002 values(@i) ** 将i值插入临时表temp_1003
fetch from cursor_1001 into @i ……………………………………
if @@fetch_status=0 ……………………………………
insert into temp_1003 values(@i) ……………………………………
fetch from cursor_1001 into @i ……………………………………
……
……
……
end **结束循环
close cursor_1001 **关闭游标
deallocate cursor_1001 **删除游标
在调试过程中遇到一个很头疼的问题,因为最开始,循环体的写法是:
fetch first from cursor_1001 into @i
while (@@fetch_status=0)
begin
insert into temp_1001 values(@i)
fetch from cursor_1001 into @i
insert into temp_1002 values(@i)
fetch from cursor_1001 into @i
……
……
……
这种写法比上述写法优化不少,因为在每行操作前少了一个判断,事实上经大批量数据测试,性能大概可以提高30%。但是可惜调试结果证明这种写法存在一定问题,因为是在insert fetch 体系外做的@@fetch_status判断,所以当最后一行出现在段落中间的时候,下一个赋值行为将会把@i参数的值一直传递下去,直到该循环结束。
为避免这种现象发生,在每一个插入表数据的行为之前,均将最后一行的判断执行一遍,这样不管最后一行落在哪里,均可以正常跳出。
在性能测试中,该段代码还是表现较为正常,20万的数据,分成17张表,然后将17张表的数据一一平均分配给17张临时表,整个过程耗时100秒左右。
整个程序体基本也没啥可圈可点,但是作为第一次游标使用,作为存念,哈哈哈哈哈。