存儲過程|細節|要點
一. 語法聲明
創建存儲過程語法:
CREATE[OR REPLACE]PROCEDURE [存儲過程名稱]
[ (argment [ { IN | IN OUT }] Type,
argment [ { IN | OUT | IN OUT } ] Type ]
{ IS | AS}
<類型.變量的說明>
BEGIN
<執行部分>
EXCEPTION
<可選的異常錯誤處理程序>
END;
PS:紅色必須、灰色可選、藍色表示內容區域
二. 細節/要點
1. 過程參數:輸入參數(IN) / 輸出參數(OUT) / 輸入輸出參數(IN OUT)
這裏值得注意的是,OUT返回值除了基礎數據類型,還可以是一個集合,如:OUT sys_refcursor
2. 過程內部<類型.變量的說明>:
第一種方式:
[變量名] [變量類型](長度) --例如:l_user_name varchar2(50);
第二種方式:
[變量名] [變量類型](長度) := 值 --例如:l_user_name varchar2(50):= 'weiwei';
第三種方式【自定義變量類型】:
create or replace type t_vc is table of varchar2(100); -- 創建自定義變量類型
[變量名] [自定義變量類型] -- 例如:l_array t_vc;
遊標聲明:
第一種方式:顯示遊標 (CURSOR)
CURSOR 遊標名稱 IS 查詢語句; 例如:
CURSOR account_cursor IS select user_account, ORG_ID from auth_user;
第二種方式:動態遊標 (Ref CURSOR)
TYPE 類型名 IS REF CURSOR;
別名 類型名;
例如:
TYPE cur_recyle IS REF CURSOR;
c_cursor cur_recyle;
3. 過程內部<執行部分>:
根據項目實例,分析執行部分中通常使用的技術要點:
【INTO 的用法】
select myconvert(v_staffAccs,',') into l_array from dual;
-- 這裏用到了myconvert拆分函數、以及l_array自定義變量類型,作用是將過程的傳入參數v_staffAccs以逗號分隔賦值到l_array自定義變量中。
-- dual是一張系統虛擬表,用來構成select的語法規則,用處例如:
select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;--獲得當前系統時間
【循環的用法】
FOR語法: for 變量名 in 開始數值...結束數值 loop
<執行內容>
end loop;
WHILE語法:while 條件 loop
<執行內容>
end loop;
【控制流語句用法】
if 條件 then
<邏輯處理>
elsif 條件 then
<邏輯處理>
else
<邏輯處理>
end if;
-- IF ELSIF ELSE例子:
declare
num number := 2;
begin
if num = 1 then
dbms_output.put_line('==> 1');
elsif num = 2 then
dbms_output.put_line('==> 2');
else
dbms_output.put_line(num);
end if;
end;
case
when 條件 then
<邏輯處理>
when 條件 then
<邏輯處理>
else
<邏輯處理>
end case;
-- case例子:
declare
case
when num = 1 then
dbms_output.put_line('==> 1');
when num = 2 then
dbms_output.put_line('==> 2');
else
dbms_output.put_line(num);
end case;
end;
【執行動態的SQL語句】
語法:execute immediate 'SQL語句' 例子:execute immediate 'select DUMMY from dual';
爲何要這樣動態執行?請看這個例子:select * from 'tsm_record_call'||'_20131121';這樣執行會告訴你表名不存在。
從動態語句檢索值(INTO子句):execute immediate 'SQL語句' into 變量名;
例子:execute immediate 'select DUMMY from dual' into str_content;
給動態語句傳值(USING 子句):execute immediate 'SQL語句' (or (into 變量名)) using 需要替換的值或變量;
例子:execute immediate 'select DUMMY from dual where DUMMY =:1' into str_content using '123';
例子:如果參數是多個 execute immediate 'select DUMMY from dual where DUMMY =:1 or DUMMY =:2' into str_content using '123','234';
execute immediate參考網頁地址:點擊打開鏈接
【遊標的生命週期】
OPEN c_cursor FOR -- 打開遊標 FOR指向查詢語句
sqlStr USING v_groupId,v_org_id,v_plansum; -- 動態查詢語句 USING 加入動態參數
Loop -- 打開一個循環
FETCH c_cursor into l_res_cust_id; -- 調用遊標結果 賦值到 指定變量,此時,Loop循環每次循環FETCH只取NEXT數據,這裏遊標集合將會一條一條執行
EXIT WHEN c_cursor%NOTFOUND; -- 如果當前結果集沒有內容 則跳出Loop循環
if 1=1 then
<邏輯內容>
else
goto startmark; -- 跳出循環
end Loop; -- 結束循環
close c_cursor; -- 循環執行結束,果斷關閉遊標
<<startmark>> -- 跳出循環處
IF c_cursor%ISOPEN = TRUE THEN -- 如果遊標打開 則關閉
CLOSE c_cursor;
END IF;
【遊標的屬性】
屬性遊標提供了屬性,用來判斷遊標目前所處狀態和遊標的一些相關信息。
%isopen 判斷遊標是否處於打開狀態(true|false);
%found %notfound 查看遊標中是否還有數據行或者是沒有數據行(ture|false);
%rowcount 返回遊標中數據行的當前行數;
這些屬性可以幫助在使用顯示遊標的時候去判斷遊標的打開和關閉狀態,存在數據和不存在數據的狀態,還可以取得當前遊標數據集中的行數。
【異常處理】
異常裏主要是進行回滾操作,返回錯誤自定義區分錯誤類型的錯誤編碼,以及回滾事務rollback;
在存儲過程begin塊中執行UPDATE或INSERT操作後需要commit提交事務;
例如如下代碼片段:
exception
when no_data_found then
v_code := '0002';
v_result := '沒有找到相應數據!';
rollback;
when others then
v_code := '1111';
v_result := '系統異常';
rollback;
【其他】
%TYPE 和 %ROWTYPE用法:點擊打開鏈接