现在的位置: 首页 > 综合 > 正文

回字形方阵的SQL解法

2014年04月05日 ⁄ 综合 ⁄ 共 3108字 ⁄ 字号 评论关闭

--
回字形方阵的SQL解法
--
作者:do熊
--
日期:2008-02-21
--
执行方式(参数必须为整数的平方,但大小并不是无限制的)
--
exec sp_Test 2500
--
================================================
create procedure sp_Test
   
@n int
as
begin
   
declare @layer int, @width int, @spaces varchar(16) --维度,元素宽度,元素前导空格
    set @layer=sqrt(@n)
   
if @layer*@layer<>@n
   
begin
       
raiserror('%d is not a square number!', 16, 1, @n)
       
return 1
   
end
   
select @width=len(@n)+1, @spaces=space(@width-1)

    declare @sql varchar(max), @i int, @lwidth varchar(16), @sql2 varchar(max), @sql3 varchar(max)
   
select @lwidth=rtrim(@layer*@width)
        ,
@sql='declare @1 varchar('+@lwidth+')'
        ,
@sql2=char(13)+char(10)+'select @1=SPACE('+@lwidth+')'
        ,
@sql3=char(13)+char(10)+'print @1'
        ,
@i=2
   
while @i<=@layer   
       
select @sql=@sql+', @'+rtrim(@i)+' varchar('+@lwidth+')'
            ,
@sql2=@sql2+', @'+rtrim(@i)+'=SPACE('+@lwidth+')'
            ,
@sql3=@sql3+char(13)+char(10)+'print @'+rtrim(@i)
            ,
@i=@i+1
   
set @sql=@sql+@sql2

    declare @x int, @y int, @upper int, @loop int, @ii int, @d int
   
select @x=0, @y=1, @upper=@layer, @i=1, @loop=0, @d=0
   
while @i<=@n
   
begin
       
set @ii=1
       
if @d=0 -- down
        begin
           
select @x=@x+1
                ,
@sql=@sql+char(13)+char(10)+'select @'+rtrim(@x)
                       
+'=stuff(@'+rtrim(@x)+', '+rtrim(@y)+', '+rtrim(@width)+', right('''+@spaces+rtrim(@i)+''', '+rtrim(@width)+'))'
                ,
@i=@i+1, @ii=@ii+1
           
while @ii<=@upper
               
select @x=@x+1
                    ,
@sql=@sql+', @'+rtrim(@x)+'=stuff(@'+rtrim(@x)+', '+rtrim(@y)+', '+rtrim(@width)+', right('''+@spaces+rtrim(@i)+''', '+rtrim(@width)+'))'
                    ,
@i=@i+1, @ii=@ii+1       
       
end
       
else if @d=1 -- right
        begin
           
select @sql2='', @y=@y+@width
           
while @ii<=@upper
               
select @sql2=@sql2+right(@spaces+rtrim(@i), @width)
                    ,
@i=@i+1, @ii=@ii+1
           
select @sql=@sql+char(13)+char(10)+'select @'+rtrim(@x)
                       
+'=stuff(@'+rtrim(@x)+', '+rtrim(@y)+', '+rtrim(@width*@upper)+', '''+@sql2+''')'
                ,
@y=@y+@width*(@upper-1)   
       
end
       
else if @d=2 -- up
        begin
           
select @x=@x-1
                ,
@sql=@sql+char(13)+char(10)+'select @'+rtrim(@x)
                       
+'=stuff(@'+rtrim(@x)+', '+rtrim(@y)+', '+rtrim(@width)+', right('''+@spaces+rtrim(@i)+''', '+rtrim(@width)+'))'
                ,
@i=@i+1, @ii=@ii+1
           
while @ii<=@upper
               
select @x=@x-1
                    ,
@sql=@sql+', @'+rtrim(@x)+'=stuff(@'+rtrim(@x)+', '+rtrim(@y)+', '+rtrim(@width)+', right('''+@spaces+rtrim(@i)+''', '+rtrim(@width)+'))'
                    ,
@i=@i+1, @ii=@ii+1       
       
end
       
else if @d=3 -- left
        begin
           
select @sql2=''
           
while @ii<=@upper
               
select @sql2=right(@spaces+rtrim(@i), @width)+@sql2
                    ,
@i=@i+1, @ii=@ii+1
           
select @y=@y-@width*@upper
                ,
@sql=@sql+char(13)+char(10)+'select @'+rtrim(@x)
                       
+'=stuff(@'+rtrim(@x)+', '+rtrim(@y)+', '+rtrim(@width*@upper)+', '''+@sql2+''')'            
       
end
       
       
select @d=(@d+1)%4, @upper=@upper-@d%2       
   
end

--    print @sql+@sql3
    exec(@sql+@sql3)
   

end
go

exec sp_Test 6400

 

抱歉!评论已关闭.