日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

本文介紹了局部程序(subprogram)的聲明和使用方法等相關(guān)內(nèi)容。

簡介

程序包括函數(shù)和過程。在PL/SQL塊中創(chuàng)建的程序被稱作嵌套子程序。您可以在PL/SQL塊(可以是另一個子程序)、包或全局級別創(chuàng)建子程序。您可以同時聲明和定義程序,也可以先聲明,然后在同一個塊中后續(xù)定義(即前向聲明)。可以使用 CREATE FUNCTIONCREATE PROCEDURE聲明一個全局程序,或是在一個包中聲明和定義程序(通常是在包頭聲明程序,在包體定義程序)。這兩種程序會被存儲在系統(tǒng)表中。此外,其他嵌套子程序在這里將其稱作局部程序。它不會被存入系統(tǒng)表,當嵌套塊中調(diào)用局部程序的時候,局部程序才會被編譯和執(zhí)行。

局部程序的聲明

您可以通過以下語法聲明局部程序。

DECLARE -- 外層匿名塊,當然也可以是全局過程

  [FUNCTION] -- 局部函數(shù)
      name ( [ [ argmode ] [ argname ] argtype [ { DEFAULT | = } default_expr ] [, ...] ] )
  {RETURNS | RETURN} rettype 
  {AS | IS}
  [DECLARE] -- 局部函數(shù)聲明段
    ...
  BEGIN -- 局部函數(shù)程序段
    ...
    RETURN ...
  END;

BEGIN -- 外層的程序段

END;
說明

您也可以將 FUNCTION替換為 PROCEDURE來聲明一個局部過程,并且不需要返回任何值。

局部程序的使用

以下為一個簡單的使用局部程序的示例。

DECLARE
  a INT;
  FUNCTION local_func RETURN INT -- 聲明局部函數(shù)
  IS
  BEGIN
    RETURN 10;
  END;
BEGIN
  a := local_func(); -- 調(diào)用局部函數(shù)
  RAISE NOTICE 'a: %', a;
END;

由于函數(shù)可以被重載(同一個函數(shù)名,不同的參數(shù)列表),通常情況下,系統(tǒng)將會使用 local_func這個名稱去系統(tǒng)表中找到一系列候選函數(shù),然后從中選擇參數(shù)列表最為匹配的來執(zhí)行(當然,也可能沒有任何函數(shù)被匹配到)。在此之前,系統(tǒng)會優(yōu)先嘗試尋找匹配的局部函數(shù)。由于函數(shù)可以嵌套,系統(tǒng)將會一層一層的向上查找匹配的局部函數(shù),如下所示:

DECLARE
    PROCEDURE local_proc1 IS
    BEGIN
        RAISE NOTICE 'call outer local_procedure1';
    END;

    PROCEDURE local_proc2 IS
        proc2_str VARCHAR(50);
        FUNCTION local_func RETURN VARCHAR IS
            func_str VARCHAR(50) := 'raise inner local_func';
        BEGIN
            local_proc1(); -- 尋找到外層的 local_proc1
            RETURN func_str;
        END;
    BEGIN
        proc2_str := local_func();
        raise notice '%', proc2_str;
    END;
BEGIN
    local_proc2();
END;

結(jié)果顯示如下:

NOTICE:  call outer local_procedure1
NOTICE:  raise inner local_func

如果在某一層尋找到至少一個同名的局部函數(shù)后,將會停止繼續(xù)向上搜索,并在當前層的所有局部函數(shù)中選擇出一個優(yōu)勝者函數(shù)來執(zhí)行。此時,如果已經(jīng)找到同名的局部函數(shù)但無法選出優(yōu)勝者,那么將直接報錯。

DECLARE
    PROCEDURE local_proc1 IS
    BEGIN
        RAISE NOTICE 'call outer local_procedure1';
    END;

    PROCEDURE local_proc2 IS
        proc2_str VARCHAR(50);
        FUNCTION local_func RETURN VARCHAR IS
            func_str VARCHAR(50) := 'raise inner local_func';
        BEGIN
            local_proc1(1); -- 尋找到外層的 local_proc1, 但無法匹配
            RETURN func_str;
        END;
    BEGIN
        proc2_str := local_func();
        raise notice '%', proc2_str;
    END;
BEGIN
    local_proc2();
END;

結(jié)果顯示如下:

ERROR:  wrong number or types of arguments in call to local function local_proc1

前向聲明

如果同一個PL/SQL塊中的嵌套子程序相互調(diào)用,則需要前向聲明,因為必須先聲明子程序,然后才能調(diào)用子程序。如果聲明后沒有在同一個PL/SQL塊中定義子程序,系統(tǒng)會檢查出這種錯誤。

DECLARE
    FUNCTION func_test(id INT) return INT;  -- 只聲明,未定義
BEGIN
END;

結(jié)果顯示如下:

ERROR:  subroutine body must be defined for forward-declared function "func_test"

以下示例展示如何正確使用前向聲明。

DECLARE
  PROCEDURE proc1(number1 NUMBER); -- 前向聲明 proc1

  PROCEDURE proc2(number2 NUMBER) IS -- 聲明并定義 proc2
  BEGIN
    proc1(number2); -- 調(diào)用 proc1
  END;

  -- Define proc 1:
  PROCEDURE proc1(number1 NUMBER) IS -- 定義 proc1
  BEGIN
    proc2 (number1); -- 調(diào)用 proc2
  END;

BEGIN
  NULL;
END;
說明

您必須保證嵌套調(diào)用有正確的退出條件,否則會在反復(fù)嵌套調(diào)用中超過最大調(diào)用棧而報錯。

使用外層程序的變量

局部程序的使用中,給出了一個使用外層局部函數(shù)的示例。同理,在局部程序之前聲明的所有變量、游標、自定義異常等等都是可以直接使用的。您可以對這些變量取值、賦值,開啟游標并從中取行,或是使用外層的自定義異常來拋出一個異常。以下是一個說明變量可見性的示例。

DECLARE
    a INT := 1; -- 可以使用 a
    PROCEDURE local_proc IS
    BEGIN
        RAISE NOTICE 'call outer local_procedure';
        RAISE NOTICE 'inner raise a: %', a;
        a := 10;
    END;
    b INT; -- 無法使用 b
BEGIN
    RAISE NOTICE 'outer raise a: %', a;
    local_proc();
    RAISE NOTICE 'outer raise a: %', a;
END;

結(jié)果顯示如下:

NOTICE:  outer raise a: 1
NOTICE:  call outer local_procedure
NOTICE:  inner raise a: 1
NOTICE:  outer raise a: 10

如果您嘗試使用在 local_proc之后聲明的變量,則會出現(xiàn)語法錯誤。

DECLARE
    a INT := 1; -- 可以使用 a
    PROCEDURE local_proc IS
    BEGIN
        RAISE NOTICE 'call outer local_procedure';
        RAISE NOTICE 'inner raise a: %', a;
        a := 10;
    END;
    b INT; -- 無法使用 b
BEGIN
    local_proc();
END;

結(jié)果顯示如下:

ERROR:  "b" is not a known variable