1、存儲過程
存儲過程的參數
形式參數和實際參數,例如,有如下一個存儲過程,該過程接收一個作家代碼和一個工資值,將該作家的工資改為接收到的工資值。
Java代碼
Java代碼
v_authorcode、v_salary作為參數傳遞到存儲過程updateauths中,這些參數是實際參數,簡稱實參。
p_authscode、p_authssalary就是形式參數,簡稱形參。
參數定義中,IN、OUT和IN OUT代表參數的三種不同模式:
IN:當調用存儲過程時,該模式的形參接收對應實參的值,并且該是只讀的,即不能被修改。默認為IN。
OUT:該形參被認為只能寫,既只能為其賦值。在存儲過程中不能讀它的值。返回時,將該形參值傳給相應的實參。
IN OUT:都允許。
Java代碼
在定義一個存儲過程參數時,不能指定CHAR類型和VARCHAR2類型形參的長度,也不能指定NUMBER形參的精度和標度。這些約束由實參來傳遞。
例如,下面的存儲過程定義不合法,將產生一個編譯錯誤:
Java代碼
Java代碼
p_code的長度約束和p_salary的精度,標度約束由實參傳遞。
Java代碼
Java代碼
(2)參數的傳值方式
位置表示法、名稱表示法
如有這樣的存儲過程
Java代碼
Java代碼
(3)參數的缺省值
如可以這樣:
p_entry_date_time auths.entry_date_time%type:sysdate,
p_sex auths.sex%type default 1
2、創(chuàng)建函數
函數與存儲過程非常類似,都有三種模式的參數。它們都可以存儲在數據庫中(當然過程與函數也可以不在于數據庫中),并且在塊中調用。
與存儲過程不同,存儲過程只能作為一個PL/SQL語句調用,而函數作為表達式的一部分調用。并且它們的定義、可執(zhí)行、異常處理部分是不同的。
例如,如作家表中男作家或女作家的工資在200元以上的人數大于百分之七十,則下面的函數返回TRUE,否則返回FALSE:
Java代碼
Java代碼
return也可以用在存儲過程中。在這種情況下,它沒有參數。當執(zhí)行了不帶參數的return語句后,立刻將控制返回到調用環(huán)境,并將OUT和IN OUT模式的形參的當前值傳給實參,然后繼續(xù)執(zhí)行調用存儲過程后的語句。
在使用函數與存儲過程時,一般情況下,如果只有一個返回值,則使用函數;如果有多個返回值則使用存儲過程。盡管函數的參數可以是OUT模式,但是一般不這樣使用。
3、刪除過程與函數
drop procedure procedurename;
drop function functionname;
4、庫存子程序和局部子程序
前面的子程序都是存儲在數據庫中的子程序,即庫存子程序。這些子程序是由ORACLE命令創(chuàng)建的,并可在其它的PL/SQL塊中調用。它們在創(chuàng)建時要進行編譯,并將編譯后的代碼存儲在數據庫中。當子程序被調用時,編譯后的代碼從數據庫中讀出并執(zhí)行。
一個子程序也可以在塊的定義部分創(chuàng)建,這樣的子程序被叫作局部子程序。
下面定義了一個局部函數formatname:
Java代碼
局部子程序只能在定義部分的最后被創(chuàng)建,如果將formatname函數移到上面,將會出現編譯錯誤。子程序必須先定義再引用。
存儲過程的參數
形式參數和實際參數,例如,有如下一個存儲過程,該過程接收一個作家代碼和一個工資值,將該作家的工資改為接收到的工資值。
Java代碼
- create or replace procedure updateauths(??
- ?? p_authscode auths.author_code%type,??
- ?? p_authssalary auths.salary%type)??
- as??
- begin??
- ?? update auths set salary=p_authssalary where author_code=p_authscode;??
- ?? commit;??
- end updateauths;??
Java代碼
- declare??
- ?? v_authorcode auths.author_code%type:='A00011';??
- ?? v_salary auths.salary%type:=350;??
- begin??
- ?? updateauths(v_authorcode,v_salary);??
- end;??
v_authorcode、v_salary作為參數傳遞到存儲過程updateauths中,這些參數是實際參數,簡稱實參。
p_authscode、p_authssalary就是形式參數,簡稱形參。
參數定義中,IN、OUT和IN OUT代表參數的三種不同模式:
IN:當調用存儲過程時,該模式的形參接收對應實參的值,并且該是只讀的,即不能被修改。默認為IN。
OUT:該形參被認為只能寫,既只能為其賦值。在存儲過程中不能讀它的值。返回時,將該形參值傳給相應的實參。
IN OUT:都允許。
Java代碼
- create or replace procedure updateauthssalary(??
- ?? p_author_code in out auths.author_code%type,??
- ?? p_salary in number,??
- ?? p_name out auths.name%type) is??
- ?? v_salary_temp number; --定義存儲過程中的局部變量??
- begin??
- ?? select salary into v_salary_temp from auths where author_code=p_author_code;??
- ??if v_salary_temp<300 then??
- ???? update auths set salary=p_salary where author_code=p_author_code;??
- ?? end if;??
- ?? select name into p_name from auths where author code=p_author_code;??
- end updateauthssalary;??
在定義一個存儲過程參數時,不能指定CHAR類型和VARCHAR2類型形參的長度,也不能指定NUMBER形參的精度和標度。這些約束由實參來傳遞。
例如,下面的存儲過程定義不合法,將產生一個編譯錯誤:
Java代碼
- create or replace procedure proc_auths(??
- ?? --參數定義了類型長度,將產生編譯錯誤。??
- ?? p_code in out varchar2(6),??
- ?? p_salary out number(8,2)) as??
- begin??
- ?? select salary into p_salary from auths where author_code=p_code;??
- end proc_auths;??
Java代碼
- create or replace procedure proc_auths(??
- ?? --參數定義了類型長度,將產生編譯錯誤。??
- ?? p_code in out varchar2,??
- ?? p_salary out number) as??
- begin??
- ?? select salary into p_salary from auths where author_code=p_code;??
- end proc_auths;??
p_code的長度約束和p_salary的精度,標度約束由實參傳遞。
Java代碼
- delcare??
- ?? v_code varchar2(6);??
- ?? v_salary number(8,2);??
- begin??
- ?? v_code:='A00001';??
- ?? proc_auths(v_code,v_salary);??
- end;??
Java代碼
- create or replace procedure query_salary(??
- ?? p_code in out auths.author_code%type,??
- ?? p_salary out auths.salary%type) as??
(2)參數的傳值方式
位置表示法、名稱表示法
如有這樣的存儲過程
Java代碼
- create or replace procedure insert_auths(??
- ?? p_code auths.author_code%type,??
- ?? p_name auths.name%type,??
- ?? p_sex auths.sex%type,??
- ?? p_birthdate auths.birthdate%type) as??
Java代碼
- declare??
- ?? v_code varchar2(6);??
- ?? v_name varchar2(12);??
- ?? v_sex number(1);??
- ?? v_birthdate date;??
- begin??
- ?? v_code:='A00021';??
- ?? v_name:='張';??
- ?? v_sex:=1;??
- ?? v_birthdate:='5-seq-70';??
- ?? --實參的位置順序與形參的位置順序相對應。---位置表示法??
- ?? insert_auths(v_code,v_name,v_sex,v_birthdate);??
- ?? --實參名與形參名對應,這樣就可以重新排列參數的先后順序。---命名表示法??
- end;??
(3)參數的缺省值
如可以這樣:
p_entry_date_time auths.entry_date_time%type:sysdate,
p_sex auths.sex%type default 1
2、創(chuàng)建函數
函數與存儲過程非常類似,都有三種模式的參數。它們都可以存儲在數據庫中(當然過程與函數也可以不在于數據庫中),并且在塊中調用。
與存儲過程不同,存儲過程只能作為一個PL/SQL語句調用,而函數作為表達式的一部分調用。并且它們的定義、可執(zhí)行、異常處理部分是不同的。
例如,如作家表中男作家或女作家的工資在200元以上的人數大于百分之七十,則下面的函數返回TRUE,否則返回FALSE:
Java代碼
- create or replace function salarystat(??
- ?? p_sex auths.sex%type)??
- ??return boolean is??
- ?? v_currentsexauthors number;??
- ?? v_maxauthors number;??
- ?? v_returnvalue boolean;??
- ?? v_percent constant number:=70;??
- begin??
- ?? --獲得滿足條件的作家的最大數。??
- ?? select count(author_code) into v_maxauthors from auths where sex=p_sex and salary>=200;??
- ?? select count(author_code) into v_currentsexauthors from auths where sex=p_sex;??
- ??if(v_maxauthors/v_currentsexauthors*100)>v_percent then??
- ???? v_returnvalue:=true;??
- ??else??
- ???? v_returnvalue:=false;??
- ?? end if;??
- ??return v_returnvalue;??
- end salarystat;??
Java代碼
- declare??
- ?? cursor c_auths is??
- ???? select distinct sex from auths;??
- begin??
- ??for v_authsrecord in c_auths loop??
- ????if salarystat(v_authsrecord.sex) then??
- ?????? update auths set salary=salary-50 where sex=v_authsrecord.sex;??
- ???? end if;??
- ?? end loop;??
- end;??
return也可以用在存儲過程中。在這種情況下,它沒有參數。當執(zhí)行了不帶參數的return語句后,立刻將控制返回到調用環(huán)境,并將OUT和IN OUT模式的形參的當前值傳給實參,然后繼續(xù)執(zhí)行調用存儲過程后的語句。
在使用函數與存儲過程時,一般情況下,如果只有一個返回值,則使用函數;如果有多個返回值則使用存儲過程。盡管函數的參數可以是OUT模式,但是一般不這樣使用。
3、刪除過程與函數
drop procedure procedurename;
drop function functionname;
4、庫存子程序和局部子程序
前面的子程序都是存儲在數據庫中的子程序,即庫存子程序。這些子程序是由ORACLE命令創(chuàng)建的,并可在其它的PL/SQL塊中調用。它們在創(chuàng)建時要進行編譯,并將編譯后的代碼存儲在數據庫中。當子程序被調用時,編譯后的代碼從數據庫中讀出并執(zhí)行。
一個子程序也可以在塊的定義部分創(chuàng)建,這樣的子程序被叫作局部子程序。
下面定義了一個局部函數formatname:
Java代碼
- declare??
- ?? cursor c_allauthors is??
- ???? select name,sex from auths;??
- ?? v_formattedname varchar2(60);??
- ?? function formatname(p_name in varchar2,p_sex in number)??
- ????return varchar2 is??
- ???? v_sex varchar2(16);??
- ?? begin??
- ????if p_sex=1 then??
- ?????? v_sex:='男';??
- ????else??
- ?????? v_sex:='女';??
- ???? end if;??
- ????return p_name||'('||v_sex||')';??
- ?? end formatname;??
- begin??
- ??for v_authsrecord in c_allauthors loop??
- ???? v_formattedname:=??
- ?????? formatname(v_authsrecord.name,v_authsrecord.sex);??
- ???? dbms_output.put_line(v_formattedname);??
- ?? end loop;??
- end;??
局部子程序只能在定義部分的最后被創(chuàng)建,如果將formatname函數移到上面,將會出現編譯錯誤。子程序必須先定義再引用。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
