2016年7月22日 星期五

學習初級Oracle PL/SQL (二)

Procedures
PL/SQL procedures don’t return a value. They just perform their instructions and return. Of course, this
means that you can’t use procedures on the right-hand side of an assignment statement like a function.
PL/SQL procedure只是執行而不會像function一樣 return返回值.



Create Procedure
procedure的語法: ( [ ] ) 為非必要
CREATE [OR REPLACE] PROCEDURE <procedure_name> [(
<parameter_name_1> [IN] [OUT] <parameter_data_type_1>,
<parameter_name_2> [IN] [OUT] <parameter_data_type_2>,...
<parameter_name_N> [IN] [OUT] <parameter_data_type_N> )] IS
--the declaration section
BEGIN
-- the executable section
EXCEPTION
-- the exception-handling section
END;
/


建立procedure的語法有以下幾個重點:
語法是CREATE PROCEDURE,可加入OR REPLACE來自動取代現有的procedure. IS or AS為保留字.跟合法的BLOCK語法一樣,BEGINEND也是必須的,但不用DECLARE來宣告,只要在CREATE PROCEDURE...IS AS 之後宣告即可.

以下是一個非常簡單的procedure例子. 它將調用sys.dbms_lock package內的sleep(sec in number) procedure. 這個procedure 將停止執行CPU為指定( )內的秒數

例子:
create or replace procedure cpu_wait(        -- 創建一個名叫cpu_waitprocedure
input1 in number) as                                  -- 宣告一個v_input1輸入值為IN參數,類型為Number

begin                                                        -- 執行區
sys.dbms_lock.sleep(input1);                    -- 調用sys.dbms_lock package內的sleep( ) procedure
end cpu_wait;                                            -- 結束 procedure
/

執行效果
SQL> exec cpu_wait(5);                                     ß sqlplus 將等待5

PL/SQL procedure successfully completed.

例子, 創建一個調用dbms_output.put_lineprocedure. 顯示( ) 輸入的值. 這個procedure日後的練習將經常使用.
create or replace procedure pl(
text1 in varchar2) as
begin
sys.dbms_output.put_line(text1);
end pl;
/

執行效果
SQL> exec pl('Hello World');
Hello World

PL/SQL procedure successfully completed.



PL/SQLFOR Loop
在很多情況下,跟其他程式語言一樣,PL/SQL中我們也需要Loop來反覆地執行某些動作.
暫時先使用簡單的FOR LOOP
語法如下:

FOR i IN 1..10 LOOP 
/* statements */
END LOOP;

簡單2個例子
declare
input1 varchar2(10);

begin
input1 := 'Hello';
for i in 1..3 loop
pl(input1);
end loop;
end;
/
begin
for i in 1..3 loop
sys.dbms_output.put_line('Hello');
end loop;
end;
/
執行效果

Hello
Hello
Hello

PL/SQL procedure successfully completed.



Exceptions
PL/SQL程序執行的時候Exception允許您捕捉錯誤,所以你可以控制回應哪些錯誤的Message. PL/SQL預定義了20多個exceptions,但你可能只使用幾個.

Reference: http://blog.csdn.net/leshami/article/details/6080119
ORACLE異常分為兩種類型:
1. System exception
2. Custom exception
其中system exception又分為: common exceptionnon-common exception.

1.1    common exception: ORACLE定義了他們的error numberexception name,以下是常見的common exception處理,Oracle常見的錯誤.
   
        NO_DATA_FOUND                                                    SELECT ... INTO ...   ,沒有找到數據
        DUL_VAL_ON_INDEX                                                試圖在一個一的列上存儲重複值
        CURSOR_ALREADY_OPEN                                      試圖打開一個已經打開的cursor
        TOO_MANY_ROWS                                                  SELECT ... INTO ...   ,查詢的結果是多

1.2    non-common exception: ORACLE為它定義了error number,但沒有定義exception.我們使用的時候,declare一個exception name, 通過PRAGMA EXCEPTION_INIT,將異常名與錯誤號關聯起來.
2.     custom exception: 就是由程序員自己定義的一個錯誤,是通過raise_application_error語句引發的,可以使用OTHERS子程序進行捕獲.

調用anonymous Blocks + loop + procedure pl( ) + exception 的例子:
declare
  max_line varchar2(32767); --varchar2有兩個最大長度: 一個字段類型4000,一個是PL/SQL中變量類型32767
begin
  for i in 1..32767 loop
        max_line := max_line||'-';
  end loop;
  pl('test a number, 1');
  pl(1);
  pl('test date, 20/07/2016');
  pl(to_date('20072016','DD-MM-YYYY'));
  pl('test a line over 32767');
  pl(max_line);
  pl('test max_line over 32767');
  pl(max_line||'+');
  pl('finish test');
end;
/
執行效果
test a number, 1
1
test date, 20/07/2016
20-JUL-16
test a line over 32767
--------------------------------------------------------------------------------
-----------------------------------------------………………………….
test max_line over 32767
declare
*
ERROR at line 1:
ORA-20000: ORU-10028: line length overflow, limit of 32767 bytes per line
ORA-06512: at "SYS.DBMS_OUTPUT", line 32
ORA-06512: at "SYS.DBMS_OUTPUT", line 91
ORA-06512: at "SYS.DBMS_OUTPUT", line 112
ORA-06512: at "RPS.PL", line 4
ORA-06512: at line 14

出現ORA-20000: ORU-10028: line length overflow, limit of 32767 bytes per line, 可以看到最後2pl 並沒有執.
因為 >32767 的測試沒有比exception處理,讓我們來看看如可以用代碼解決這個問題.



Nested Blocks
Nested block是指PL/SQL block嵌入另一個PL/SQL block,Nesting PL/SQL blocks可以讓你在更好的控制你的PL/ SQL程序的exception.

-- 承接上一個例子:
.
..
  pl('test max_line over 32767');
 begin                                              -- nested block以關鍵字BEGIN開始,PL/SQL語句大於 > 32767.
  pl(max_line||'+');
 exception                                        --關鍵字EXCEPTIONnested block創建一個例外的處理部.
  when others then pl(SQLERRM);     -- when OTHERS then 捕獲所有nested block 產生的異常.
 end;
  pl('finish test');
end;
/


執行效果
test a number, 1
1
test date, 20/07/2016
20-JUL-16
test a line over 32767
--------------------------------------------------------------------------------
-----------------------------------------------................

test max_line over 32767
ORA-20000: ORU-10028: line length overflow, limit of 32767 bytes per line
finish test

PL/SQL procedure successfully completed.
太好了!現在我的測試順利完成, 並報告我期望看到的exception.


學習初級Oracle PL/SQL (三)
學習初級Oracle PL/SQL (一)

沒有留言:

張貼留言