Oracle之PL/SQL的使用

如下圖遇到這樣的問題,一般就是使用java代碼來解決,但是有了pl/sql完全可以使用它來寫這樣的邏輯代碼,它比任何語言效率都快.

準備環境:jdk,oracle,sqldeveloper4.0版本的,用高版本的打印不出結果 或者使用

PL/SQL Developer 這個軟件也可以寫plsql   連接數據庫的時候使用scott/tiger 這個賬號密碼連接,這是oracle安裝的時候就帶的

 

首先打印一個hello,world

set serveroutput on 是打開默認關閉的oracle的輸出開關

plsql語法就是declare 後面寫說明部分,比如聲明一些變量之類的東西,begin後面寫正常的邏輯代碼,end;結束語句.

dbms_output相當於java中的類,但在這叫程序包,put_line就相當於java的方法,但在這叫存儲過程,或者存儲函數.

在plsql裏面變量的定義,名字在前面,變量在後面.   

var1 char(15);  這個表示聲明一個變量爲var1  類型是char類型,長度15

married boolean := true;   聲明一個變量名爲married,boolean類型  := 表示賦值,相當於java的=.plsql中的=相當於java的==,代表比較的意思.

psal number(7,2); 定義變量psal 爲number類型 7的長度,2位小數

my_name emp.ename%type; %type表示引用型變量,引用的emp表的ename字段的類型,這個字段是啥類型,聲明的變量就是什麼類型.

emp_rec emp%rowtype;    %rowtype表示把emp表的一行的類型作爲emp_rec的類型,一行上面有多個列,可以把這種記錄型變量理解爲數組.如果要獲得一列的值,直接變量名點列名就可以了.

如果聲明常量的話在變量名和變量中間加 constant 即可 例如:var1 constant char(15); 

下面這個例子就是引用型變量,在plsql中賦值方式有兩種,一種是:=一種就是into關鍵字,into 後面的變量順序得跟sql語句前面查出來的順序一樣.||是字符串拼接符.

記錄型變量,操作跟上面的引用型變量同樣的例子

accept代表鍵盤錄入,相當於java的scanner

光標就相當於java的Resultset也就是集合,但是這兒的光標指針初始化是在第一個元素上的,但是java中的resultset是在第一個元素前的.

遍歷集合的示例

-- 查詢並打印員工的姓名和薪水
/*
光標的屬性: %isopen如果打開就是true反之是false   %rowcount(影響的行數,就是取出了多少條,取了10條它的值就是10)
          %found(還有沒有下一條記錄)    %notfound

*/
declare 
   --定義光標(遊標)
   cursor cemp is select ename,sal from emp;
   pename emp.ename%type;
   psal   emp.sal%type;
begin
  --打開光標
  open cemp;
  loop
       --取當前記錄
       fetch cemp into pename,psal;
       --exit when 沒有取到記錄;
       exit when cemp%notfound;   
       dbms_output.put_line(pename||'的薪水是'||psal);
  end loop;
  --關閉光標
  close cemp;
end;

-- 給員工漲工資,總裁1000 經理800 其他400的示例 

-- 給員工漲工資,總裁1000 經理800 其他400
declare 
  --定義光標
  cursor cemp is select empno,job from emp;
  pempno emp.empno%type;
  pjob   emp.job%type;
begin
  --打開光標
  open cemp;  
  loop
       --取一個員工
       fetch cemp into pempno,pjob;
       exit when cemp%notfound;
       --判斷職位
       if pjob = 'PRESIDENT' then update emp set sal=sal+1000 where empno=pempno;
          elsif pjob = 'MANAGER' then update emp set sal=sal+800 where empno=pempno;
          else update emp set sal=sal+400 where empno=pempno;
       end if;
  end loop;
  --關閉光標
  close cemp;
  --提交  ----> why?: 事務 ACID
  commit;
  dbms_output.put_line('完成');
end;

光標帶參數的寫法,定義的時候形參開啓的時候傳入實參 

plsql的例外,就相當於java的異常處理,每個then後面相當於個大括號,可以寫邏輯代碼,在plsql當中最好寫上other then,把剩餘的可能都寫全,不然的話這個異常可能拋到oracle數據庫中,可能造成一些問題,在java當中如果你不處理全,還有虛擬機幫你處理,在這裏卻沒有

自定義的例外使用變量的形式定義一個自定義例外,exception,使用的方式跟java中throw往外拋的形式差不多,這兒使用raise關鍵字進行拋例外.

declare 
  cursor cemp  is select ename from emp where deptno=50;
  pename emp.ename%type;
  --自定義例外
  no_emp_found exception;
begin
  open cemp;
  
  --取第一條記錄
  fetch cemp into pename;
  if cemp%notfound then
    --拋出例外  
    raise no_emp_found;
  end if;
  --進程:pmon進程(proccesss monitor)
  close cemp;
exception
  when no_emp_found then dbms_output.put_line('沒有找到員工');
  when others then dbms_output.put_line('其他例外');
end;

在plsql中沒有finally,但是拋出例外,光標關閉不了怎麼辦呢?拋出例外的時候oracle會啓動pmon進程來釋放資源

存儲過程和存儲函數的使用http://www.javashuo.com/article/p-yazonxjp-pw.html