一个跟同事闲谈写出来的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;