游标实现表数据平均分配若干张表

来源:互联网 发布:otc焊接机器人编程 编辑:程序博客网 时间:2024/05/07 03:30

    要求将一张用户数据清单表,首先按照分公司进行分开,然后将这些以分公司为单位的集合,再平均分到若干张表中去。

    按照分公司分开是很简单的,不管是按照区域列来分类,还是按照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秒左右。

    整个程序体基本也没啥可圈可点,但是作为第一次游标使用,作为存念,哈哈哈哈哈。