存儲過程Procedure是一組爲了完成特定功能的SQL語句集合,經編譯後存儲在數據庫中,用戶經過指定存儲過程的名稱並給出參數來執行。它能夠接受參數、輸出參數,並能夠返回單個或多個結果集以及返回值。sql
存儲過程的通常格式以下:數據庫
CREATE [OR REPLACE] PROCEDURE procedure_name IS [AS] 聲明部分 BEGIN 執行部分 EXCEPTION 異常處理部分 END;
調用存儲過程:oop
call procedure_name(); --------------------------------- exec procedure_name(); --------------------------------- begin pro_update_emp(); end;
寫一個簡單的存儲過程使emp表的sal值增長300。code
CREATE or replace procedure pro_update_emp as begin update emp set sal=sal+300; end;
調用存儲過程server
call pro_update_emp ();
當使用%TYPE屬性定義變量時,Oracle會自動地按照數據庫表中相應的列來肯定新變量的類型和長度。
以下,將emp表的ename字段的數據類型(如 ‘varchar(2)’)賦給變量 v_ename索引
v_ename emp.ename%type
若是一張表中包含較多的列,則能夠使用%ROWTYPE來表示表中一行記錄的變量的數據類型。
以下:將dept表中一行中各字段的數據類型(‘number’,’varchar2(50)’,varchar2(50))賦給v_dept_row,很是便利,能夠直接查詢後將一行數據賦值。
(注:語句中 into 執行賦值操做,將查詢結果直接賦值給 v_dept_row)字符串
CREATE or replace procedure pro_update_emp as v_dept_row dept%rowtype; begin select * into v_dept_row from dept where deptno=11; end;
自定義記錄的數據類型,聲明一個行數據類型,將每列的數據類型進行自定義。it
type emp_record_type is RECORD( //聲明自定義數據類型的名字爲 emp_record_type ename emp.ename%type, sal emp.sal%type, comm emp.comm%type, total_sal sal%type ); v_emp_record emp_record_type; //定義變量v_emp_record的數據類型爲 emp_record_type
TABLE(索引表)至關於一個鍵值集合,鍵是惟一的,用於查找對應的值。鍵能夠是整數或字符串。io
declare type dept_table_type is table of dept%rowtype index by binary_integer; //聲明table數據類型 dept_table_type v_dept_table dept_table_type; //聲明v_dept_table的數據類型爲 dept_table_type begin select * into v_dept_table(0) from dept where deptno=11; //按索引查詢並賦值 select * into v_dept_table(1) from dept where deptno=12; end;
(注:使用輸出語句以前應提早運行打開輸出環境變量語句’set serveroutput on’)編譯
create or replace procedure pro_query_emp0(v_no in emp.empno%type) //in 表明輸入參數,可省略 as v_sal emp.sal%type; begin select sal into v_sal from emp where empno=v_no; //將會有提醒輸入v_no參數的值 dbms_output.put_line('該員工薪水爲:'||v_sal); //輸出語句 exception when no_data_found then dbms_output.put_line('找不到該員工!'); end;
調用:
call pro_query_emp0(11)
create or replace procedure pro_query_emp(v_no in emp.empno%type, out_sal out number) as begin select sal into out_sal from emp where empno=v_no; exception when no_data_found then dbms_output.put_line('找不到該員工!'); end;
調用:
declare v_no emp.empno%type; v_sal emp.sal%type; begin v_no:=&no; pro_query_emp(v_no,v_sal); dbms_output.put_line('薪水是:'||v_sal); end;
create or replace procedure pro_testinout (param_num in out number) as begin select sal into param_num from emp where empno=param_num; end;
調用:
declare inout_num number; begin inout_num:=&no; pro_testinout(inout_num); dbms_output.put_line('工資是:'||inout_num); end;
先建立一個存儲過程
create or replace procedure pro_add_dept(v_deptno number,v_dname varchar2, v_loc varchar2) as begin insert into dept values(v_deptno,v_dname,v_loc); end;
按位置傳值:
exec pro_add_dept(70,'研發部','北京');
按名稱傳值:
call pro_add_dept(v_deptno=>90,v_loc=>'南京',v_dname=>'軟件部');
混合傳值:
exec pro_add_dept(100,v_loc=>'南京',v_dname=>'軟件部');
基本格式
IF 條件表達式1 THEN 語句段1 ELSIF 條件表達式2 THEN 語句段2 ...... ELSIF 條件表達式n 語句段n END IF;
實例:若是獎金comm爲空,則將其更新爲 v_emp.sal的0.1倍,若是小於1000則設爲1000,若是以上條件都不知足,則將comm在原有的基礎上加0.1倍。
if v_emp.comm is null then update emp set comm=v_emp.sal*0.1 where empno=v_emp.empno; elsIf v_emp.comm<1000 then update emp set comm=1000 where empno=v_emp.empno; else update emp set comm=comm+comm*0.1 where empno=v_emp.empno; end if;
基本格式
CASE WHEN 條件表達式1 THEN 語句段1; WHEN 條件表達式2 THEN 語句段2; ...... ELSE 語句段n; END CASE;
實例:將v_sal小於3000的評爲A級工資,在3000至5000之間的評爲B級工資,將其餘的評爲C級工資。
case when v_sal<3000 then dbms_output.put_line('A級工資'); when v_sal>=3000 and v_sal<5000 then dbms_output.put_line('B級工資'); else dbms_output.put_line('C級工資'); end case;
基本格式:
LOOP EXIT [WHEN 條件表達式] 語句段; END LOOP;
實例:循環向dept中插入數據
create or replace procedure pro_insert_dept as type dept_table_type is table of dept%rowtype index by binary_integer; i number(1):=0; v_dept_table dept_table_type; begin v_dept_table(0).deptno:='14'; v_dept_table(0).dname:='政法研發部'; v_dept_table(0).loc:='上海'; v_dept_table(1).deptno:='15'; v_dept_table(1).dname:='郵政金融部'; v_dept_table(1).loc:='北京'; v_dept_table(2).deptno:='16'; v_dept_table(2).dname:='系統集成部'; v_dept_table(2).loc:='深圳'; loop exit when i>2; insert into dept values( v_dept_table(i).deptno,v_dept_table(i).dname,v_dept_table(i).loc); i:=i+1; //每次循環i+1,當i的值大於2時結束循環 end loop; end;
基本格式:
WHILE 條件表達式 LOOP 語句段; END LOOP;
實例:
while i<=2 loop insert into dept values(v_dept_table(i).deptno,v_dept_table(i).dname,v_dept_table(i).loc); i:=i+1; end loop;
基本格式:
(注:如加上reverse表示倒敘循環執行語句)
FOR 循環變量 in [REVERSE] 初值表達式..終值表達式 LOOP 語句段; END LOOP;
實例:
for i in 0..v_dept_table.count-1 loop insert into dept values( v_dept_table(i).deptno,v_dept_table(i).dname,v_dept_table(i).loc); end loop;