在调用子程序时,必须事先在独立程序内块层次结构的某个位置声明它,但该位置必须在调用它的位置前面。换句话说,当从头到尾扫描SPL代码时,必须在调用之前找到子程序声明。
但是,有一种构造SPL代码的方式,可使子程序的完整声明(即,可选声明部分、必需可执行部分和可选异常部分)出现在调用它的代码点之后的SPL代码中。
这通过在调用之前在SPL代码中插入前置声明来完成。前置声明是子存储过程或子函数名称、形参和子函数的规格;如果是子函数,则返回类型。
完整子程序规格(由可选声明部分、可执行部分和可选异常部分组成)必须与前置声明在同一声明部分中指定,但可出现在用前置声明调用此子程序的其他子程序声明之后。
前置声明的典型用法是两个子程序相互调用,如下所示:
DECLARE
FUNCTION add_one (
p_add IN NUMBER
) RETURN NUMBER;
FUNCTION test_max (
p_test IN NUMBER)
RETURN NUMBER
IS
BEGIN
IF p_test < 5 THEN
RETURN add_one(p_test);
END IF;
DBMS_OUTPUT.PUT('Final value is ');
RETURN p_test;
END;
FUNCTION add_one (
p_add IN NUMBER)
RETURN NUMBER
IS
BEGIN
DBMS_OUTPUT.PUT_LINE('Increase by 1');
RETURN test_max(p_add + 1);
END;
BEGIN
DBMS_OUTPUT.PUT_LINE(test_max(3));
END;
子函数 test_max 调用子函数 add_one(后者也调用子函数 test_max),因此某一子程序需要前置声明,这是为匿名块声明部分开头的 add_one 实现的。
匿名块所生成的输出如下所示:
Increase by 1
Increase by 1
Final value is 5