大家知道“递归调用”吗?
所谓递归调用,是指在程序中“自己调用自己”。递归调用有很多语言支持,但并不是所有语言都可以使用。
例如,COBOL语言不能实现递归调用。当然PL/SQL语言是可以的实现递归调用的。
一般情况下,重复(循环)相同的处理内部要进行相同某个处理时,可以进行递归调用,
例如,作为例子,一个函数:求1到N的和。
通常在程序中定义一个变量,循环使用该变量进行加算,直到N为止。
例子如下:
CREATE OR REPLACE FUNCTION FUNC1 ( N IN NUMBER) RETURN NUMBER
/**************************************************************/
--在普通的循环处理中,计算1至N的求和处理
/**************************************************************/
IS
/**************************************************************/
--变量声明
/**************************************************************/
V1 NUMBER := 0;
BEGIN
/*************************************************************/
--从1到N,反复相加,每次和放到变量中。计数器I
/*************************************************************/
FOR I IN 1..N LOOP
V1 := V1 + I;
END LOOP;
/*************************************************************/
--循环处理结束后,返回该变量的值
/*************************************************************/
RETURN V1;
END FUNC1;
/
函数已创建。
那么,我们马上用这个函数,计算从1到10的相加值,即“FUNK1(10)。
该函数没有更新数据库表,因此可以用SELECT语句调用。
SELECT FUNC1(10) FROM DUAL;
FUNC1(10)
55
从1到10的合计值,1+2+3+4+5+6+7+8+9+10=55。
我们改成递归的方式:
FUNC1(10) = FUNC1(9) + 10
FUNC1(N) = FUNC1(N-1) + N
如果将此应用于程序,则FUNK1(N)的处理将返回“FUNK1(N-1)+N”。
这样一来,调用FUNK1(10)时,FUNK1(9)+10被返回;为了得到FUN1(9)的值,就会返回FUN1(8)+9;
为了得到FUN1(7)+8,就被返回……像这样反复调用,也就是说无限递归调用连锁反应。
所以我们必须设定一个递归调用停止的条件:
在上述处理中,当N=1时,即调用FUNK1(1)时,不返回“FUNKC1(0)+1”,而是返回“1”即可。
或者,N=0时,即调用FUNK1(0)时,不是返回「FUNK1(-1)+0」,而是返回「0」。
这样一来,N为1时返回“1”,N大于1时返回“FUNK1(N-1)+N”。
由此,N=1时,递归调用停止。
例子如下:
CREATE OR REPLACE FUNCTION FUNC2 ( N IN NUMBER) RETURN NUMBER
//
–通过递归调用,进行1到N求和的函数
//
IS
BEGIN
/*************************************************************/
--N为1时返回“1”,除此之外返回“FUNK2(N-1)+N”
/*************************************************************/
IF N = 1 THEN
RETURN 1;
ELSE
RETURN FUNK2(N-1)+N;--递归调用
END IF;
END FUNC2;
/
函数已创建。
通过使用递归调用,和FUNK1的代码相比,FUNK2的代码变得相当简洁。
即,当N为1时,返回“1”。除此之外的情况下,返回「FUNK2(N-1)+N」。
那么,我马上去验证一下。
SQL> SELECT FUNC1(10),FUNC2(10) FROM DUAL;
FUNC1(10) FUNC2(10)
55 55
FUNK1(10)和FUNK2(10)都是同样的结果。也就是说,1+2+3+4+5+6+7+8+9+10=55,结果是正确的。
接下来我们对递归调用的FUNK2的处理流程进行说明。
为了解释,选择了一个小点的数进行说明。
以下说明中,处理的顺序是按照箭头右侧的数字(①,②,③。。。)的顺序来进行处理的:
SELECT FUNC2(3) FROM DUAL;
FUNC2(3)
6
※上述查询处理的顺序如下:
FUNC2(3) = FUNC2(2) + 3 ↓① ↑⑥ 1+ 2+ 3 = 6
FUNC2(2) = FUNC2(1) + 2 ↓② ↑⑤ 1+ 2
FUNC2(1) = 1 ↓③ ↑④ 1
怎么样?是不是简单有趣的呢。
同样,123・*N的做法类似,如果将FUNK2的源代码第13行“RETURN FUNK2(N-1)+N;”改成
“RETURN FUNK2(N-1)*N;”,就是是计算N的阶次方(N)的函数了。
本次简单介绍一下概念。下章我们深入介绍一下递归调用的的例子。