Oracle存儲過程經常使用語法及其使用

一、什麼是存儲過程

存儲過程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 ();

三、數據類型

3.1 %type 數據類型:

當使用%TYPE屬性定義變量時,Oracle會自動地按照數據庫表中相應的列來肯定新變量的類型和長度。
以下,將emp表的ename字段的數據類型(如 ‘varchar(2)’)賦給變量 v_ename索引

v_ename emp.ename%type

3.2 %ROWTYPE數據類型:

若是一張表中包含較多的列,則能夠使用%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;

3.3 %record數據類型:

自定義記錄的數據類型,聲明一個行數據類型,將每列的數據類型進行自定義。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

3.4 TABLE數據類型:

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;

四、帶參數的存儲過程

4.1 輸入參數 (IN) :當爲過程定義參數時,若是不指定參數模式,則默認爲輸入參數

(注:使用輸出語句以前應提早運行打開輸出環境變量語句’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)

4.2 輸出參數 (OUT) :將查詢結果賦值給輸入參數 out_sql中

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;

4.3 輸入輸出參數 (IN OUT):既做輸入參數,又做輸出參數

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=>'軟件部');

六、流程控制語句

6.一、條件控制語句 IF THEN

基本格式

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;

6.二、條件控制語句 CASE

基本格式

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;

6.三、LOOP 循環

基本格式:

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;

6.三、While循環

基本格式:

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;

6.4 FOR循環

基本格式:
(注:如加上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;
相關文章
相關標籤/搜索