关闭

《oracle pl/sql programming》 第三章 pl/sql语言基础

标签: oracle语言exceptionnestedinsertnull
1808人阅读 评论(0) 收藏 举报
分类:
第三章 語言基礎
1. pl/sql代碼塊結構
Header部分
Hdader部分包含函數或過程或包的名稱及參數
 
Declaration部分
Declare部分用來聲明局部變量或常量、類型定義、異常定義。
 
Excution部分
執行部分,包含執行代碼
 
Exception部分
異常處理部分,用來處理異常。
 
如下圖:
 
匿名塊
匿名塊指的是沒有過程或函數頭的塊結構,它的標準的結構如下:
    [ DECLARE
       ... declaration statements ... ]
    BEGIN
       ... one or more executable statements ...
    [ EXCEPTION
       ... exception handler statements ... ]
    END;
DECLARE和EXCEPTION部分都不是必須的,因此,一個最簡單的匿名塊可能是這樣的:
    BEGIN
       DBMS_OUTPUT.PUT_LINE(SYSDATE);
    END;
 
命名的塊
命名的塊指的是包含函數或過程頭的塊結構,過程頭的語法格式如下:
    PROCEDURE [schema.]name [ ( parameter [, parameter ... ] ) ]
       [AUTHID {DEFINER | CURRENT_USER}]
函數頭的語法格式如下:
    FUNCTION [schema.]name [ ( parameter [, parameter ... ] ) ]
       RETURN return_datatype
       [AUTHID {DEFINER | CURRENT_USER}]
       [DETERMINISTIC]
       [PARALLEL ENABLE ...]
       [PIPELINED [USING...] | AGGREGATE USING...]
 
其中 parameter的格式為: parametername[,param1,param2...] IN DATATYPE
如下圖:
 
嵌套塊
顧名思義,塊中的塊,如下代碼:
    PROCEDURE calc_totals
    IS
       year_total NUMBER;
    BEGIN
       year_total := 0;
 
       /* 開始一個嵌套塊 */
       DECLARE
          month_total NUMBER;
       BEGIN
          month_total := year_total / 12;
       END set_month_total;
       /* 嵌套塊結束 */
 
    END;
嵌套塊的結構圖如下:
 
作用域、可見度
作用域的規則是,內部塊定義的元素在塊的外部是無法引用的,而塊外部定義元素,在內部塊中是可以引用的,當塊的內部出現同名元素是,塊內的代碼直接對該元素的引用指向的是塊內的元素,若有引用塊外部的同名元素,就要通通 外部標識.元素名 的方式來引用。這個外部標識可以是LABEL塊名(函數/過程名),如下:
    PROCEDURE calc_totals
    IS
       salary NUMBER;
    BEGIN
       ...
       DECLARE
          salary NUMBER;
       BEGIN
          salary := calc_totals.salary;
       END;
       ...
    END;
另外,有一種很常見的手法是,利用一個內部塊來專門處理一個功能點,包括他的異常處理如:
    BEGIN
       ...
 
       BEGIN /* nested block */
             INSERT INTO book_copies (isbn, qty)
             VALUES (:newisbn, :copies);
       EXCEPTION
          WHEN DUP_VAL_ON_INDEX
          THEN
             UPDATE book_copies SET qty = :copies
              WHERE isbn = :newisbn;
       END; /* nested block */
 
       books.distribute_inventory_report;
 
    END;
 
嵌套程序
舉例如下:
    PROCEDURE calc_totals (fudge_factor IN NUMBER)
    IS
       subtotal NUMBER := 0;
 
      
       /* Beginning of nested block (in this case a procedure). Notice
       | we're completely inside the declaration section of calc_totals.
       */
       PROCEDURE compute_running_total
       IS
       BEGIN
         
          /* subtotal, declared above, is both in scope and visible */
          subtotal := subtotal + subtotal * fudge_factor;
       END;
       /* End of nested block */
    BEGIN
       FOR mth IN 1..12
       LOOP
          compute_running_total;
       END LOOP;
       DBMS_OUTPUT.PUT_LINE('Fudged total for year: ' || subtotal);
    END;
 
 
2. pl/sql字符集
pl/sql中的有效ASCII字符
-------------------------------------------------------------
類型             字符
字母             A-Z, a-z
數字             0-9
符號             ~ ! @ # $ % * ( ) _ - + = | : ; " ' < > , . ? / ^
空白字符         Tab, space, newline, carriage return
-------------------------------------------------------------
 
pl/sql中的特殊符號
-------------------------------------
符號          說明
;        一行pl/sql代碼的結尾
%        類型指示器或SQL LIKE中的通配符
_        下劃線SQL LIKE中的通配符
@        遠程定位指示器
:        主機變量指示器,如 SELECT :myvar FROM DUAL
**       冪操作
< > or != or ^= or ~= 不等于
||       字符串鏈接符
<< and >>     Label 定界符
<= and >=     小于等于,大于等于
:=       賦值操作
=>       小數點移位
..       范圍操作
--       單行注釋
/* and */     多行注釋
--------------------------------------------
 
3.標識符
pl/sql中包括下列命名對象
變量或常量
異常
游標
程序名稱:過程,函數,包,對象類型,觸發器,等等。
保留字
Label
 
這些對象的命名股則一般如下
長度為30個字符以內
必須以字母開頭
可以包含$,_,#這三個符號
不可以包含空白字符
 
如下是正確的命名:
    company_id#
    primary_acct_responsibility
    First_Name
    FirstName
    address_line1
    S123456
如下是不正確的命名:
    1st_year                           -- Doesn't start with a letter
    procedure-name                     -- Contains invalid character "-"
    minimum_%_due                      -- Contains invalid character "%"
    maximum_value_exploded_for_detail -- Too long
    company ID                         -- Has embedded whitespace
 
雙引號命名法
可以通過雙引號將名稱括起來,雙引號內的名稱沒有規則限制,如:
    SQL> DECLARE
      2     "pi" CONSTANT NUMBER := 3.141592654;
      3     "PI" CONSTANT NUMBER := 3.14159265358979323846;
      4     "2 pi" CONSTANT NUMBER := 2 * "pi";
      5 BEGIN
      6     DBMS_OUTPUT.PUT_LINE('pi: ' || "pi");
      7     DBMS_OUTPUT.PUT_LINE('PI: ' || pi);
      8     DBMS_OUTPUT.PUT_LINE('2 pi: ' || "2 pi");
      9* END;
     10 /
 
    pi: 3.141592654
    PI: 3.14159265358979323846
    2 pi: 6.283185308
但是,不提倡這中命名方式。
 
保留字
保留字是pl/sql的預留的,不能用來給對象命名。保留字包括:
語言本身的關鍵字
如:
    DECLARE
       end VARCHAR2(10) := 'blip'; /* Will not work; "end" is reserved. */
    BEGIN
       DBMS_OUTPUT.PUT_LINE (end);
    END;
    /
 
被定義在STANDARD包中的關鍵字(可以通過 sql>DESC SYS.STANDARD來查看)
 
另外也應避免使用一些常用的看來像關鍵字的標識符。
 
如果是8.1.5版本以上,還可以用以下語句查詢保留字:
SQL> SELECT * FROM V$RESERVED_WORDS;
 
4. 字面值
字面值指的是不同數據類型的值的字面表示。
數值: 415, 21.6, 3.141592654f, 7D, NULL
字符串:'This is my sentence', '01-OCT-2006', q'!hello!', NULL
時間間隔:INTERVAL '25-6' YEAR TO MONTH, INTERVAL '-18' MONTH, NULL
布爾:TRUE, FALSE, NULL
 
注:以f結尾的數值表示31位浮點數 ,以D結尾的數值表示64位浮點數,q'!hello!'是字符串的另一種表示方式,它等于'hello'。
日期值的字面表示則依賴與初始化參數NLS_DATE_FORMAT的設定,如:
若設為DD-MON-YYYY,則可以用 '01-OCT-2006'表示2006年10月1日。
 
關于NULL
    '' IS NULL -- true
 
    DECLARE
       str VARCHAR2(1) := '';
    BEGIN
       IF str IS NULL   -- will be TRUE
 
    DECLARE
       flag CHAR(2) := ''; -- try to assign zero-length string to CHAR(2)
    BEGIN
       IF flag = ' '   ...   -- will be TRUE
       IF flag IS NULL ...   -- will be FALSE
 
 
5.標簽 Label
請看例子:
    <<insert_but_ignore_dups>>
    BEGIN
       INSERT INTO catalog
       VALUES (...);
    EXCEPTION
       WHEN DUP_VAL_ON_INDEX
       THEN
          NULL;
    END insert_but_ignore_dups;
 
    <<outerblock>>
    DECLARE
       counter INTEGER := 0;
    BEGIN
       ...
       DECLARE
          counter INTEGER := 1;
       BEGIN
          IF counter = outerblock.counter
          THEN
             ...
          END IF;
       END;
    END;
 
    BEGIN
       <<outer_loop>>
       LOOP
          LOOP
             EXIT outer_loop;
          END LOOP;
          some_statement ;
       END LOOP;
    END;
 
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:259895次
    • 积分:3669
    • 等级:
    • 排名:第9133名
    • 原创:102篇
    • 转载:4篇
    • 译文:0篇
    • 评论:36条
    最新评论