一个跟同事闲谈写出来的SQL脚本_算法循环_关系循环

--下面是实现一个99乘法表的脚本,第一种方法很常规,第二种方法我想了一个多小时,开始绕在Cross Apply连接这个功能上。

--我没打算用多重循环,但是感觉如果单靠两个表相连,另外一个表的数据又要根据前一个表的对应记录该表where条件,就必须用Cross Apply

--这是受蔡志辉的Sql CLR函数影响,那个函数是拆串成表的,其实没必要写得那么麻烦。

 

IF EXISTS(SELECT 1 FROM sysobjects WHERE name='P_9x9' AND xtype='P')
DROP PROCEDURE P_9x9
GO

--exec P_9x9 9
CREATE PROCEDURE P_9x9 (@n INT)
AS
DECLARE @i INT,@j INT,@s nvarchar(500)
CREATE TABLE #temp(sDiscription NVARCHAR(500), iOrderNo INT)
SET @i=1

WHILE @i<=@n
BEGIN
    SET @s=''
    SET @j=1
 WHILE @j<=@i
 BEGIN
     SET @s=@s+LTRIM(@j)+'*'+LTRIM(@i)+'='+LTRIM(@j*@i)+'   '
  SET @j=@j+1
 END
    INSERT #temp(sDiscription) VALUES(@s)
 SET @i=@i+1
END

SELECT sDiscription FROM #temp
DELETE #temp

--第二种写法
SET @i=1
WHILE @i<=@n
BEGIN
  INSERT #temp(iOrderNo)
  VALUES  (@i)
  SET @i=@i+1
END

/*
UPDATE A SET
     sDiscription=C.S
FROM #temp A CROSS APPLY  
     (SELECT iOrderNo,
          S=(SELECT LTRIM(D.iOrderNo)+'*'+LTRIM(A.iOrderNo)+'='+LTRIM(D.iOrderNo*A.iOrderNo)+'   '
        FROM #temp D WHERE D.iOrderNo<=A.iOrderNo FOR XML PATH ('')  )
  FROM #temp B
  WHERE A.iOrderNo>=B.iOrderNo
     ) C
*/

UPDATE A SET
     sDiscription=(SELECT LTRIM(D.iOrderNo)+'*'+LTRIM(A.iOrderNo)+'='+LTRIM(D.iOrderNo*A.iOrderNo)+'   '
        FROM #temp D WHERE D.iOrderNo<=A.iOrderNo FOR XML PATH ('')  )
FROM #temp A

SELECT sDiscription FROM #temp

 

下面我再写个DELPHI版本的,Delphi写法就比较固定,由此可以看出SQL在多记录处理上,由于其自身系统的循环设计,还是很有优势的。

var  //se1是TSpinEdit; mmo1是TMemo;
  i,j,k: Integer;
  s : string;
begin
    k := se1.Value;
    for i := 1 to k do
    begin
        s := '';
        for j:= 1 to i do
        begin
           s :=s+ IntToStr(j)+'*'+inttostr(i)+'='+inttostr(i*j)+'   ';
        end;
        mmo1.Lines.Append(s);
    end;
end;

 

posted @ 2017-03-20 09:36  莫霏  阅读(801)  评论(1编辑  收藏  举报