最近在用存儲過程,在網上找了很多的資料,下面就參考各種資料整理的一些小例子做些闡述:
1. Oralce TO_NUMBER() function 的改進:
用Oracle TO_NUMBER進行類型轉換的時候,如果有無效數字,將返回錯誤。遺憾的是,Oralce TO_NUMBER并不是在query運行開始就報錯,而是到碰到無效數字的紀錄才報錯,而且只是說無效輸入,并不提示是哪條紀錄,也沒有任何輸出。如果是一張大表,query運行很久才來這么一下,而且根本不知道那里出的錯,是什么值,豈不痛苦?偶就經常跟這樣的表打交道,遂自建一個函數,GET_NUM:
CREATE OR REPLACE FUNCTION GET_NUM(IN_TXT in VARCHAR2) RETURN NUMBER IS
RETRUN_VALUE NUMBER;
BEGIN
?select to_number(IN_TXT) into RETRUN_VALUE from dual;
?RETURN RETRUN_VALUE;
?
?EXCEPTION
?WHEN others
?THEN
?RETURN null;
END GET_NUM;
/
這樣無效數字全轉換成 Null,糾錯容易多了。
寫個存儲過程測試一下:
CREATE OR REPLACE PROCEDURE TestFun IS
??? v_name varchar2(10);/***** 存放cursor_para中的name *****/
??? CURSOR cursor_name IS select name from test;
??? cursor cursor_para(p_num number) is select name from test where num = p_num;
begin
? /******* t_name為循環的臨時變量******/
? FOR t_name IN cursor_name LOOP
?
? ? if (get_num(t_name.name) is not null) then
?? ?
???open cursor_para(get_num(t_name.name));
???
???fetch cursor_para into v_name;
???
???DBMS_OUTPUT.PUT_LINE('Name:'|| v_name);
???
???close cursor_para;
????? ?
?? end if;
??
? END LOOP;
END TestFun;
/
存儲過程也用到了帶參數的游標和游標For循環,稍后介紹.
其中測試表的創建:
create table test
(
???? name varchar2(10),
??? num number
)
測試數據:
insert into test(name) values ('12_');
insert into test(name) values ('123');
2.帶參數的游標
與存儲過程和函數相似,可以將參數傳遞給游標并在查詢中使用。這對于處理在某種條件下打開游標的情況非常有用。它的語法如下:
CURSOR cursor_name[(parameter[,parameter],...)] IS select_statement;
定義參數的語法如下:
Parameter_name [IN] data_type[{:=|DEFAULT} value]
與存儲過程不同的是,游標只能接受傳遞的值,而不能返回值。參數只定義數據類型,沒有大小。
另外可以給參數設定一個缺省值,當沒有參數值傳遞給游標時,就使用缺省值。游標中定義的參數只是一個占位符,在別處引用該參數不
一定可靠。
在打開游標時給參數賦值,語法如下:
OPEN cursor_name[value[,value]....];
3.游標FOR循環
在大多數時候我們在設計程序的時候都遵循下面的步驟:
1、打開游標
2、開始循環
3、從游標中取值
4、檢查那一行被返回
5、處理
6、關閉循環
7、關閉游標
可以簡單的把這一類代碼稱為游標用于循環。但還有一種循環與這種類型不相同,這就是FOR循環,用于FOR循環的游標按照正常的聲明方
式聲明,它的優點在于不需要顯式的打開、關閉、取數據,測試數據的存在、定義存放數據的變量等等。游標FOR 循環的語法如下:
FOR record_name IN
(corsor_name[(parameter[,parameter]...)]
| (query_difinition)
LOOP
statements
END LOOP;
上面的這兩個用法也在例子中提到了!
同理類推,也可以將TO_DATE()函數改進。
下面的例子自http://www.nikicn.com/bbs/dispbbs.asp?boardid=23&id=908
沒有測試,留作備份之用:
4. 將Oracle 的Last_Day()函數改寫到DB2上:
DROP SPECIFIC FUNCTION LAST_DAYDATE
;
CREATE FUNCTION LAST_DAY(D DATE)
RETURNS???? DATE
??? SPECIFIC LAST_DAYDATE
??? LANGUAGE SQL
??? DETERMINISTIC
??? CONTAINS SQL
??? CALLED ON NULL INPUT
??? NO EXTERNAL ACTION
??? RETURN
D + 1 month - day(D + 1 month) day
;
同理,DB2下的first day:
DROP SPECIFIC FUNCTION FIRST_DAYDATE
;
CREATE FUNCTION FIRST_DAY(D DATE)
RETURNS???? DATE
??? SPECIFIC FIRST_DAYDATE
??? LANGUAGE SQL
??? DETERMINISTIC
??? CONTAINS SQL
??? CALLED ON NULL INPUT
??? NO EXTERNAL ACTION
??? RETURN
D - day(D) day + 1 day