1、定義
所謂存儲過程(Stored Procedure),就是一組用於完成特定數據庫功能的SQL語句集,該SQL語句集經過
編譯后存儲在數據庫系統中。在使用時候,用戶通過指定已經定義的存儲過程名字並給出相應的存儲過程參數
來調用並執行它,從而完成一個或一系列的數據庫操作。
2、存儲過程的創建
Oracle存儲過程包含三部分:過程聲明,執行過程部分,存儲過程異常。
(1)無參存儲過程語法
create or replace procedure NoParPro
as //聲明
;
begin // 執行
;
exception//存儲過程異常
when too_many_rows then
***
when no_data_found then
***
when others then
***
;
end;
(2)帶參存儲過程實例
create or replace procedure queryempname(sfindno emp.empno%type)
as
sName emp.ename%type;
sjob emp.job%type;
begin
....
exception
....
end;
(3)帶參數存儲過程含賦值方式
create or replace procedure runbyparmeters
(isal in emp.sal%type,
sname out varchar,
sjob in out varchar)
as
icount number;
begin
select count(*) into icount from emp where sal>isal and job=sjob;
if icount=1 then
....
else
....
end if;
exception
when too_many_rows then
DBMS_OUTPUT.PUT_LINE('返回值多於1行');
when others then
DBMS_OUTPUT.PUT_LINE('在RUNBYPARMETERS過程中出錯!');
end;
其中參數IN表示輸入參數,是參數的默認模式。
OUT表示返回值參數,類型可以使用任意Oracle中的合法類型。
OUT模式定義的參數只能在過程體內部賦值,表示該參數可以將某個值傳遞回調用他的過程
IN OUT表示該參數可以向該過程中傳遞值,也可以將某個值傳出去。
(4)存儲過程中游標定義使用
as //定義(游標一個可以遍歷的結果集)
CURSOR cur_1 IS
SELECT area_code,CMCODE,SUM(rmb_amt)/10000 rmb_amt_sn,
SUM(usd_amt)/10000 usd_amt_sn
FROM BGD_AREA_CM_M_BASE_T
WHERE ym >= vs_ym_sn_beg
AND ym <= vs_ym_sn_end
GROUP BY area_code,CMCODE;
begin //執行(常用For語句遍歷游標)
FOR rec IN cur_1 LOOP
UPDATE xxxxxxxxxxx_T
SET rmb_amt_sn = rec.rmb_amt_sn,usd_amt_sn = rec.usd_amt_sn
WHERE area_code = rec.area_code
AND CMCODE = rec.CMCODE
AND ym = is_ym;
END LOOP;
(5)游標的定義
--顯示cursor的處理
declare
---聲明cursor,創建和命名一個sql工作區
cursor cursor_name is
select real_name from account_hcz;
v_realname varchar2(20);
begin
open cursor_name;---打開cursor,執行sql語句產生的結果集
fetch cursor_name into v_realname;--提取cursor,提取結果集中的記錄
dbms_output.put_line(v_realname);
close cursor_name;--關閉cursor
end;
3、在Oracle中對存儲過程的調用
(1)過程調用方式一
declare
realsal emp.sal%type;
realname varchar(40);
realjob varchar(40);
begin //過程調用開始
realsal:=1100;
realname:='';
realjob:='CLERK';
runbyparmeters(realsal,realname,realjob);--必須按順序
DBMS_OUTPUT.PUT_LINE(REALNAME||' '||REALJOB);
END; //過程調用結束
(2)過程調用方式二
declare
realsal emp.sal%type;
realname varchar(40);
realjob varchar(40);
begin //過程調用開始
realsal:=1100;
realname:='';
realjob:='CLERK';
--指定值對應變量順序可變
runbyparmeters(sname=>realname,isal=>realsal,sjob=>realjob);
DBMS_OUTPUT.PUT_LINE(REALNAME||' '||REALJOB);
END; //過程調用結束
(3)過程調用方式三(SQL命令行方式下)
1、SQL>exec proc_emp('參數1','參數2');//無返回值過程調用
2、SQL>var vsal number
SQL> exec proc_emp ('參數1',:vsal);// 有返回值過程調用
//或者:call proc_emp ('參數1',:vsal);// 有返回值過程調用
相當與do while ........先執行一次再循環
循環基本語法
1. while total <= 100
loop
.......
total := total + 1;
end loop;
例
declare
var number:=1;
begin
while var <= 100
loop
dbms_output.put_line(var);
var := var + 1;
end loop;
end;
這個就相當於 JAVA里的while循環。
2. for i in 1..100
loop
語句序列;
end loop;
例
declare
begin
for i in 1..100
loop
dbms_output.put_line(i);
end loop;
end;
進階小例子
declare
var number;
begin
select count(1)
into var
from test_procedure;
for i in 1..var
loop
dbms_output.put_line(i);
end loop;
end;
就相當於for 循環。
3. loop
語句;
exit when 條件;
語句;
end loop;
例
declare
var number :=1;
begin
loop
dbms_output.put_line(var);
exit when var > 1;
var := var + 1;
end loop;
end;
語法:
cursor 游標名 [ (參數名 數據類型,參數名 數據類型,...)] is select 語句;
例:
cursor c1 is select ename from emp;
游標的屬性:
%isopen 是否打開 boolean類型
%rowcount 影響的行數 不是總行數,例如總數100,已經取了10條,那么這個數為10
%found 是否找到 boolean類型
%notfound 是否沒找到 boolean類型
簡單實例1:
declare
cursor p is select t.name,t.money from test_procedure t;
pname test_procedure.name%type;
pmoney test_procedure.money%type;
begin
--使用前要開啟光標
open p;
loop
--取當前記錄
fetch p into pname,pmoney;
exit when p%notfound;
dbms_output.put_line(pname||'薪水是'||pmoney);
end loop;
--結束要關閉光標
close p;
end;
簡單實例2:
declare
cursor p is select * from test_procedure t;
var test_procedure%rowtype;
begin
--使用前要開啟光標
open p;
loop
--取當前記錄
fetch p into var;
exit when p%notfound;
dbms_output.put_line(var.name||'薪水是'||var.money);
end loop;
--結束要關閉光標
close p;
end;
簡單實例3:
declare
cursor p is select * from test_procedure t;
var test_procedure%rowtype;
begin
--使用前要開啟光標
open p;
loop
--取當前記錄
fetch p into var;
if var.job = '后端工程師'
then update test_procedure set money = money+10000 where name = var.name;
elsif var.job = '前端工程師'
then update test_procedure set money = money+5000 where name = var.name;
else
update test_procedure set money = money+50000 where name = var.name;
end if;
exit when p%notfound;
dbms_output.put_line(var.name||'薪水是'||var.money);
end loop;
--結束要關閉光標
close p;
--提交事務
commit;
dbms_output.put_line('完成');
end;
帶參數的游標用法
--查詢某個部門員工的姓名
declare
--形參
--在游標定義一個參數
cursor temp(pjob varchar2) is select name from test_procedure where job = pjob;
pname test_procedure.name%type;
begin
--傳參
--開啟游標傳遞參數
open temp('后端工程師');
loop
fetch temp into pname;
exit when temp%notfound;
dbms_output.put_line(pname);
end loop;
close temp;
end;
