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

本文介紹了PL/SQL的聲明信息。

簡介

在一個塊中使用的所有變量必須在該塊的聲明小節中聲明(唯一的例外是在一個整數范圍上迭代的FOR循環變量會被自動聲明為一個整數變量,并且相似地在一個游標結果上迭代的FOR循環變量會被自動地聲明為一個記錄變量)。

PL/SQL變量可以是任意SQL數據類型,例如integervarcharchar

這里是變量聲明的一些例子:

    user_id integer;
    quantity numeric(5);
    url varchar;
    myrow tablename%ROWTYPE;
    myfield tablename.columnname%TYPE;
    arow RECORD;

一個變量聲明的一般語法是:

    name [ CONSTANT ] type [ COLLATE collation_name ] [ NOT NULL ] [ { DEFAULT | := | = } expression ];

如果給定DEFAULT子句,它會指定進入該塊時分配給該變量的初始值。如果沒有給出DEFAULT子句, 則該變量被初始化為 SQL 空值。 CONSTANT選項阻止該變量在初始化之后被賦值, 這樣它的值在塊的持續期內保持不變。COLLATE 選項指定用于該變量的一個排序規則。如果指定了NOT NULL,對該變量賦值為空值會導致一個運行時錯誤。所有被聲明為NOT NULL的變量必須被指定一個非空默認值。 等號(=)可以被用來代替 PL/SQL-兼容的 :=

一個變量的默認值會在每次進入該塊時被計算并且賦值給該變量(不是每次函數調用只計算一次)。因此,例如將now()賦值給類型為timestamp的一個變量將會導致該變量具有當前函數調用的時間,而不是該函數被預編譯的時間。

例子:

    quantity integer DEFAULT 32;
    url varchar := 'http://mysite.com';
    user_id CONSTANT integer := 10;

聲明函數參數

傳遞給函數的參數被命名為標識符$1$2等等。可選地,能夠為$``n參數名聲明別名來增加可讀性。不管是別名還是數字標識符都能用來引用參數值。

有兩種方式來創建一個別名。比較好的方式是在CREATE FUNCTION命令中為參數給定一個名稱。例如:

    CREATE FUNCTION sales_tax(subtotal real) RETURN real IS
    BEGIN
        RETURN subtotal * 0.06;
    END;

另一種方式是顯式地使用聲明語法聲明一個別名。

    name ALIAS FOR $n;

使用這種風格的同一個例子看起來是:

    CREATE FUNCTION sales_tax(real) RETURN real IS
    DECLARE
        subtotal ALIAS FOR $1;
    BEGIN
        RETURN subtotal * 0.06;
    END;
說明

這兩個例子并非完全等效。在第一種情況中,subtotal可以被引用為sales_tax.subtotal,但在第二種情況中它不能這樣引用(如果我們為內層塊附加了一個標簽,subtotal則可以用那個標簽限定)。

更多一些例子:

    CREATE FUNCTION instr(varchar, integer) RETURN integer IS
    DECLARE
        v_string ALIAS FOR $1;
        index ALIAS FOR $2;
    BEGIN
        -- 這里是一些使用 v_string 和 index 的計算
    END;
    

    CREATE FUNCTION concat_selected_fields(in_t sometablename) RETURN text IS
    BEGIN
        RETURN in_t.f1 || in_t.f3 || in_t.f5 || in_t.f7;
    END;

當一個PL/SQL函數被聲明為帶有輸出參數,輸出參數可以用普通輸入參數相同的方式被給定$``n名稱以及可選的別名。一個輸出參數實際上是一個最初為 NULL 的變量,它應當在函數的執行期間被賦值。該參數的最終值就是要被返回的東西。例如,sales-tax 例子也可以用這種方式來做:

    CREATE FUNCTION sales_tax(subtotal real, OUT tax real) IS
    BEGIN
        tax := subtotal * 0.06;
    END;
說明

我們忽略了RETURNS real — 我們也可以包括它,但是那將是冗余。

當返回多個值時,輸出參數最有用。一個小例子是:

    CREATE FUNCTION sum_n_product(x int, y int, OUT sum int, OUT prod int) IS
    BEGIN
        sum := x + y;
        prod := x * y;
    END;

這實際上為該函數的結果創建了一個匿名記錄類型。如果給定了一個RETURNS子句,它必須RETURNS record

聲明一個PL/SQL函數的另一種方式是用RETURNS TABLE,例如:

    CREATE FUNCTION extended_sales(p_itemno int)
    RETURN TABLE(quantity int, total numeric) IS
    BEGIN
        RETURN QUERY SELECT s.quantity, s.quantity * s.price FROM sales AS s
                     WHERE s.itemno = p_itemno;
    END;

這和聲明一個或多個OUT參數并且指定RETURNS SETOF ``sometype完全等效。

當PL/SQL函數的返回類型被聲明為多態類型時, 一個特殊的參數 $0 已創建。它的數據類型是函數的實際返回類型,從實際輸入類型推導出來。 $0被初始化為空并且不能被該函數修改,因此它能夠被用來保持可能需要的返回值,不過這不是必須的。 $0也可以被給定一個別名。例如,這個函數工作在任何具有一個+操作符的數據類型上:

    CREATE FUNCTION add_three_values(v1 anyelement, v2 anyelement, v3 anyelement)
    RETURN anyelement IS
    DECLARE
        result ALIAS FOR $0;
    BEGIN
        result := v1 + v2 + v3;
        RETURN result;
    END;

通過聲明一個或多個輸出參數為多態類型可以得到同樣的效果。在這種情況下,不使用特殊的$0參數,輸出參數本身就用作相同的目的。例如:

    CREATE FUNCTION add_three_values(v1 anyelement, v2 anyelement, v3 anyelement,
                                     OUT sum anyelement)
    IS
    BEGIN
        sum := v1 + v2 + v3;
    END;

在實踐中,使用anycompatible類型系列聲明多態函數可能更有用,以便將輸入參數自動提升為公共類型。例如:

    CREATE FUNCTION add_three_values(v1 anycompatible, v2 anycompatible, v3 anycompatible)
    RETURN anycompatible IS
    BEGIN
        RETURN v1 + v2 + v3;
    END;

在此示例中,調用如

    SELECT add_three_values(1, 2, 4.7);

將工作,自動將整數輸入提升為數字。使用anyelement的函數需要您手動將三個輸入轉換為相同的類型。

ALIAS

    newname ALIAS FOR oldname;

ALIAS語法比前一節中建議的更一般化:你可以為任意變量聲明一個別名,而不只是函數參數。其主要實際用途是為預先決定了名稱的變量分配一個不同的名稱,例如在一個觸發器過程中的NEWOLD

例子:

    DECLARE
      prior ALIAS FOR old;
      updated ALIAS FOR new;

因為ALIAS創造了兩種不同的方式來命名相同的對象,如果對其使用不加限制就會導致混淆。最好只把它用來覆蓋預先決定的名稱。

復制類型

    variable%TYPE

%TYPE提供了一個變量或表列的數據類型。你可以用它來聲明將保持數據庫值的變量。例如,如果你在users中有一個名為user_id的列。要定義一個與users.user_id具有相同數據類型的變量:

    user_id users.user_id%TYPE;

通過使用%TYPE,你不需要知道你要引用的結構的實際數據類型,而且最重要的,如果被引用項的數據類型在未來被改變(例如你把user_id的類型從integer改為real),你不需要改變你的函數定義。

%TYPE在多態函數中特別有價值,因為內部變量所需的數據類型能在兩次調用時改變。可以把%TYPE應用在函數的參數或結果占位符上來創建合適的變量。

行類型

    name table_name%ROWTYPE;
    name composite_type_name;

一個組合類型的變量被稱為一個變量(或行類型變量)。這樣一個變量可以保持一個SELECTFOR查詢結果的一整行,前提是查詢的列集合匹配該變量被聲明的類型。該行值的各個域可以使用通常的點號標記訪問,例如rowvar.field

通過使用table_name``%ROWTYPE標記,一個行變量可以被聲明為具有和一個現有表或視圖的行相同的類型。它也可以通過給定一個組合類型名稱來聲明(因為每一個表都有一個相關聯的具有相同名稱的組合類型,所以在本數據庫中實際上寫不寫%ROWTYPE都沒有關系。但是帶有%ROWTYPE的形式可移植性更好)。

一個函數的參數可以是組合類型(完整的表行)。在這種情況下,相應的標識符$``n將是一個行變量,并且可以從中選擇域,例如$1.user_id

這里是一個使用組合類型的例子。table1table2是已有的表,它們至少有以下提到的域:

    CREATE FUNCTION merge_fields(t_row table1) RETURN text IS
    DECLARE
        t2_row table2%ROWTYPE;
    BEGIN
        SELECT * INTO t2_row FROM table2 WHERE ... ;
        RETURN t_row.f1 || t2_row.f3 || t_row.f5 || t2_row.f7;
    END;
    
    SELECT merge_fields(t.*) FROM table1 t WHERE ... ;

記錄類型

    name RECORD;

記錄變量和行類型變量類似,但是它們沒有預定義的結構。它們采用在一個SELECTFOR命令期間為其賦值的行的真實行結構。一個記錄變量的子結構能在每次它被賦值時改變。這樣的結果是直到一個記錄變量第一次被賦值之前,它都沒有子結構,并且任何嘗試訪問其中一個域都會導致一個運行時錯誤。

說明

RECORD并非一個真正的數據類型,只是一個占位符。我們也應該認識到當一個PL/SQL函數被聲明為返回類型record,這與一個記錄變量并不是完全相同的概念,即便這樣一個函數可能會用一個記錄變量來保持其結果。在兩種情況下,編寫函數時都不知道真實的行結構,但是對于一個返回record的函數,當調用查詢被解析時就已經決定了真正的結構,而一個行變量能夠隨時改變它的行結構。

PL/SQL變量的排序規則

當一個PL/SQL函數有一個或多個可排序數據類型的參數時,為每一次函數調用都會基于賦值給實參的排序規則來確定出一個排序規則。如果一個排序規則被成功地確定(即在參數之間隱式排序規則沒有沖突),那么所有的可排序參數會被當做隱式具有那個排序規則。這將在函數中影響行為受到排序規則影響的操作。例如,考慮

    CREATE FUNCTION less_than(a text, b text) RETURN boolean IS
    BEGIN
        RETURN a < b;
    END;
    

    SELECT less_than(text_field_1, text_field_2) FROM table1;
    SELECT less_than(text_field_1, text_field_2 COLLATE "C") FROM table1;

less_than的第一次使用將會采用text_field_1text_field_2共同的排序規則進行比較,而第二次使用將采用C排序規則。

此外,被確定的排序規則也被假定為任何可排序數據類型本地變量的排序規則。因此,當這個函數被寫為以下形式時,它工作將不會有什么不同

    CREATE FUNCTION less_than(a text, b text) RETURN boolean IS
    DECLARE
        local_a text := a;
        local_b text := b;
    BEGIN
        RETURN local_a < local_b;
    END;

如果沒有可排序數據類型的參數,或者不能為它們確定共同的排序規則,那么參數和本地變量會使用它們數據類型的默認排序規則(通常是數據庫的默認排序規則,但是可能不同于域類型的變量)。

通過在一個可排序數據類型的本地變量的聲明中包括COLLATE選項,可以為它指定一個不同的排序規則,例如

    DECLARE
        local_a text COLLATE "en_US";

這個選項會覆蓋根據上述規則被給予該變量的排序規則。

還有,如果一個函數想要強制在一個特定操作中使用一個特定排序規則,當然可以在該函數內部寫一個顯式的COLLATE子句。例如:

    CREATE FUNCTION less_than_c(a text, b text) RETURN boolean IS
    BEGIN
        RETURN a < b COLLATE "C";
    END;

這會覆蓋表達式中使用的表列、參數或本地變量相關的排序規則,就像在純 SQL 命令中發生的一樣。