PLSQL程序設計(Oracle)

Hello Worldjava

set serveroutput on;

declare
  --說明部分
  begin
  --程序
  dbms_output.put_line('Hello World');
end;
/
什麼是PL/SQL?
  • PL/SQL是Oracle對sql語言的過程化擴展
  • 指在SQL命令語言中增長了過程處理語句(如分子、循環等),使SQL語言具備過程處理能力
 
把SQL語言的數據操縱能力與過程語言的數據處理能力結合起來,PLSQL面向過程但比過程語言簡單、高效、靈活和實用。
 
PL/SQL程序結構
declare
       說明部分   (變量說明,光標申明,例外說明)
begin
       語句序列   (DML語句)...
exception
       例外處理語句
end/

 

變量說明(char,varchar2,date,number,boolean,long)
varl                char(15); //說明變量名,數據類型和長度後用分號結束說明語句
married         boolean  :=true;
psal               number(7,2);
my_name      emp.ename%type; //引用型變量,即my_name的類型與emp表中ename列的類型同樣
emp_rec        emp%rowtype; //記錄型變量
 
引用型變量:
--查詢7839姓名和薪水
set serveroutput on 
declare
  --定義變量保存姓名和薪水
  --pname varcher2(20);
  --psal   number;
  pname emp.ename%type;
  psal  emp.sal%type;
begin 
    --into 賦值   注意查詢與賦值順序
    select ename,sal into pname,psal from emp where empno=7839;

    --打印
    dbms_output.put_line(pname||'的薪水是:'||psal);
end;
/

記錄型變量sql

--查詢7839姓名和薪水
set serveroutput on 
declare
  --定義記錄型變量,表明一行
  emp_rec emp%rowtype;
begin 
    select * into emp_rec from emp where empno=7839;
    --打印
    dbms_output.put_line(emp_rec.ename||'的薪水是:'||emp_rec.sal);
end;
/

if語句ide

if 條件 then 語句;
elsif 語句 then 語句;
end if
判斷用戶從鍵盤輸入的數字:

 

--接收鍵盤輸入
set serveroutput on
--num 是一個地址值,在該地址上保存了輸入的值的地址
accept num prompt '請輸入一個數字';

declare
    --定義變量保存輸入的數字
    pnum number := #
begin 
    if pnum = 0 then dbms_output.put_line('您輸入的是0');
      elsif  pnum = 1 then dbms_output.put_line('您輸入的是1');
      else dbms_output.put_line('其餘數字');
    end if;
end;
/

循環oop

loop
exit[when 條件]
...
end loop;
for i in 1..3
loop
語句序列;
end loop;

打印1~10fetch

--打印1~10
set serveroutput on

declare
    pnum number :=1;
begin
  loop
      exit when pnum>10;
      SYS.dbms_output.put_line(pnum);
      --pnum 每次+1   不能使用++
      pnum := pnum + 1 ;
  end loop;
end;
/
光標(cursor)==resultset
說明光標語法:
cursor 光標[ (參數名 數據類型[,參數名 數據類型]...)]
    is select 語句 ;
 
用於存儲一個查詢返回的多行數據
    cursor c1 is select ename from emp ;
 
打開光標: open c1 ;(打開光標執行查詢)
取一行光標的值: fetch c1 into pename;(取一行到變量中)
關閉光標:close c1;(關閉光標釋放資源)
注意:上面的pename必須與emp表中的ename列類型一致;
--查詢並打印員工的姓名和薪水
/*
  一、光標屬性
    %isopen   %rowcount(影響的行數)
    %found    %notfound
*/
set serveroutput on

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 cemp%notfound;
      SYS.dbms_output.put_line(pename||'的薪水是:'||psal);
  end loop;
  close cemp;
end;
/

給員工漲薪水:總裁PRESIDENT 漲1000,經理MANAGER漲800,普通員工漲400spa

--給員工漲薪水:總裁PRESIDENT 漲1000,經理MANAGER漲800,普通員工漲400

set serveroutput on

declare
  cursor cemp is select empno,empjob from emp;
  pempno emp.empno%type;
  pjob   emp.empjob%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;

end;
/

查詢某個部門的員工code

--查找某個部門員工
set serveroutput on

declare
  --定義光標保存某個部門的員工姓名
  cursor cemp(dno number) is select ename from emp where deptno=dno;
  pname emp.ename%type;

begin
  --光標傳實參部門id爲10
  open cemp(10);
  loop
    fetch cemp into pname;
    exit when cemp%notfound;

    SYS.dbms_output.put_line(pname);
  end loop;
  close cemp;

end;
/
例外:
java例外機制:向上拋,不處理,最終拋給虛擬機。
 
Oracel 的異常處理
系統定義例外
no_data_found :沒有找到數據
too_many_rows :select ...into語句匹配多個行
zero_divide:算術或轉換錯誤
timeout_on_resource:在等待資源時,發生超時
 
PLSQL中應該處理全部例外
--被0除
set serveroutput on

declare
  pnum number;

begin 
  pnum :=1/0;

exception
  when zero_divide then dbms_output.put_line('0不能被整除');
  when others then dbms_output.put_line('其餘例外');
end;
/

自定義例外server

--查詢50號部門的員工姓名

set serveroutput on

declare
  cursor cemp is select ename from emp where deptno=50;
  pname emp.ename%type;
  --自定義例外
  no_emp_found exception;

begin
  open cemp;
  fetch cemp into pname;
  if cemp%notfound then
    --拋出異常
    raise no_emp_found;
  end if;
  close cemp;

exception
  when no_emp_found then dbms_output.put_line('沒有找到員工信息');
  when others then dbms_output.put_line('其餘例外');
end;
/


統計每一年入職的員工人數blog

--使用PLSQL統計每一年入職的員工
/*
SQL語句:select to_char(hiredate,'yyyy') from emp
--> 光標--->循環  --->退出條件,notfound

變量:一、初始值;二、如何獲得?
count80 number :=0;
....
*/

set serveroutput on 

declare
  cursor cemp is select to_char(hiredate,'yyyy') from emp;
  phiredate varchar2(4);
  count80 number :=0;
  count81 number :=0;
  count82 number :=0;
  count87 number :=0;

begin
  open cemp;
  loop
      --取出一個員工信息
      fetch cemp into phiredate;
      exit when cemp%notfound;
      --判斷
      if phiredate='1980' then count80 := count80+1;
        elsif phiredate='1981' then count81 := count81+1;
        elsif phiredate='1982' then count81 := count82+1;
        else count87 := count87+1;
      end if;
  end loop;
  close cemp;
  --輸出
  SYS.dbms_output.put_line('1980:'||count80);
  SYS.dbms_output.put_line('1981:'||count81);
  SYS.dbms_output.put_line('1982:'||count82);
  SYS.dbms_output.put_line('1987:'||count87);
end;
/

 

使用PLSQL根據部門號統計各個部門員工薪水在3000如下、3000~6000、6000以上的人數,並計算各部門工資總額。將結果存入msg表中。

 

/*
SQL語句
部門:select deptno from dept;  --> 光標
部門中員工的薪水: select sal from emp where deptno=??  --> 帶參數的光標

變量:1. 初始值  2. 如何獲得
每一個段的人數
count1 number; count2 number; count3 number;

部門的工資總額: salTotal number;
1. select sum(sal) into salTotal from emp where deptno=??  
2. 累加
*/
set serveroutput on
declare
  --部門
  cursor cdept is select deptno from dept; 
  pdeptno dept.deptno%type;

  --部門中員工的薪水
  cursor cemp(dno number) is select sal from emp where deptno=dno;
  psal emp.sal%type;
  --每一個段的人數
  count1 number; count2 number; count3 number;
  --部門的工資總額: 
  salTotal number;
begin
  open cdept;
  loop
    --取一個部門
    fetch cdept into pdeptno;
    exit when cdept%notfound;

    --初始化
    count1:=0;count2:=0;count3:=0;
    --獲得部門的工資總額
    select sum(sal) into salTotal from emp where deptno=pdeptno;

    --取部門中員工的薪水
    open cemp(pdeptno);
    loop
      --取一個員工的薪水
      fetch cemp into psal;
      exit when cemp%notfound;

      --判斷薪水的範圍
      if psal < 3000 then count1:=count1+1;
        elsif psal>=3000 and psal<6000 then count2:=count2+1;
        else count3:=count3+1;
      end if;

    end loop;
    close cemp;

    --保存結果
    insert into msg values(pdeptno,count1,count2,count3,nvl(salTotal,0));

  end loop;
  close cdept;

  commit;
  dbms_output.put_line('完成');

end;
/
相關文章
相關標籤/搜索