PL/SQL練習範例

以下是學習PL/SQL入門級別的練習範例,進攻初學者參考。 
 /*測試程序的增刪改查*/

  --測試插入
  /*declare
     v_deptno number(2):=50;
     v_dname   varchar2(10):='service';
     v_loc   varchar2(20):='beijing';
     begin 
     insert into dept(deptno,dname,loc) values(v_deptno,v_dname,v_loc);
     commit;
  end;*/

  -- 測試刪除
  /*declare
     v_deptno number(2):=90;
     begin 
     delete from dept where deptno=v_deptno;
     commit;
  end;*/

  -- 測試查詢
  /*declare
    v_info   varchar2(30);
    v_deptno number(2) := 40;
  begin
    select to_char(deptno) || dname || loc
      into v_info
      from dept
     where deptno = v_deptno;
    dbms_output.put_line(v_info);
  end;*/

  -- 測試修改
  /*declare
    v_deptno number(2) := 40;
    v_loc    varchar2(30) := 'boston';
  begin
    update dept set loc = v_loc where deptno = v_deptno;
    commit;
  end;*/

  -- 測試returning
  /*declare
  row_id urowid; --注意這裏 使用number行不通
  info varchar2(30);
  begin
  update dept set loc='beijing' where deptno=40
  returning rowid,to_char(deptno)||loc into row_id,info;
  dbms_output.put_line(row_id);
  dbms_output.put_line(info);
  end; */

  -- 測試%type
  /*declare
    v_info   varchar2(30);
    v_deptno dept.deptno%type;
  begin
    v_deptno:=40;
    select to_char(deptno) || dname || loc
      into v_info
      from dept
     where deptno = v_deptno;
    dbms_output.put_line(v_info);
  end;*/

  -- 測試輸入參數
  /*declare
    v_info   varchar2(30);
    v_deptno dept.deptno%type:=&deptno;
  begin
    select to_char(deptno) || dname || loc
      into v_info
      from dept
     where deptno = v_deptno;
    dbms_output.put_line(v_info);
  end;*/

  --測試%rowtype
  /*declare
  v_record dept%rowtype;
  begin
  select * into v_record from dept where deptno=40;
  dbms_output.put_line('部門號'||to_char(v_record.deptno)||'部門名稱'||v_record.dname);
  end;*/

  --變量variable
  /* declare
  variable v_info varchar2;
  begin
  select '部門編號:'||to_char(deptno)||'部門名稱:'||dname||'部門地址:'||loc  
  into :v_info
  from dept
  where deptno=40;
  end;
  print v_info;*/

  -- index by table  根據條件查詢原表得到的數據生成新表
  /*declare
    --定義表的類型
    type new_dept is table of dept%rowtype index by binary_integer;
    --創建新表
    my_dept new_dept; --注意該表只是臨時的
  begin
    for int in 1 .. 4 loop
      select * into my_dept(int) from dept where deptno = int * 10;
    end loop;
    for int in 1 .. 4 loop
      dbms_output.put_line(to_char(my_dept(int).deptno) || my_dept(int)
                           .dname || my_dept(int).loc);
    end loop;
  exception
    when others then
      dbms_output.put_line('出現異常啦');
  end;*/

  /*==================程序流程控制====================*/
  --if then
  --elsif   then
  --else   then
  -- 漲工資計劃
  -- 設置最低工資1500 低於1500的工資都漲到1500
  -- 1500-300間漲300
  -- 工資3000以上漲500
  -- 工資5000以上漲1000
  /*declare
    v_empno number(4) := &empno;
    v_sal   emp.sal%type;
  begin
    select sal into v_sal from emp where empno = v_empno;
    dbms_output.put_line(to_char(v_empno)||'號員工原工資是'||v_sal);
    if v_sal < 1500 then
      update emp set sal = 1500 where empno = v_empno;
      dbms_output.put_line(to_char(v_empno) || '號員工,漲工資到1500');
    elsif v_sal > 1500 and v_sal < 3000 then
      update emp set sal = sal + 300 where empno = v_empno;
      dbms_output.put_line(to_char(v_empno) || '號員工,漲工資500');
    elsif v_sal >= 3000 and v_sal < 5000 then
      update emp set sal = sal + 500 where empno = v_empno;
      dbms_output.put_line(to_char(v_empno) || '號員工,漲工資500');
    elsif v_sal >= 5000 then
      update emp set sal = sal + 1000 where empno = v_empno;
      dbms_output.put_line(to_char(v_empno) || '號員工,漲工資1000');
    else
      dbms_output.put_line('該員工不存在');
    end if;
    commit;
    exception
    when others then
      dbms_output.put_line('程序出異常啦');
  end;*/

  -- case用法
  -- 根據員工職位漲工資

  -- manager +1000
  --analyst  +800
  --saleman +600
  --clerk  +400
  --其他不加

  -- 循環

  -- exit when
  /*declare 
  v_number number(2):=0;
  begin
  loop
  v_number:=v_number+1;
  dbms_output.put_line(v_number);
  exit when v_number=10;
  end loop;
  end;*/

  -- while
  /*declare 
  v_number number(2):=0;
  begin
  while v_number<10 loop
  v_number:=v_number+1;
  dbms_output.put_line(v_number);
  end loop;
  end;*/

  -- for循環
  -- ++
  /*declare 
  v_number number(2):=0;
  begin
  for v_number in 1..10 loop
  dbms_output.put_line(v_number);
  end loop;
  end;*/
  -- --
  /*declare 
  v_number number(2):=0;
  begin
  for v_number in reverse 1..10 loop
  dbms_output.put_line(v_number);
  end loop;
  end;*/

  -- go to 
  /*declare 
  v_number number(2):=0;
  begin
  for v_number in  1..10 loop
  dbms_output.put_line(v_number);
  if v_number=5 then
   goto show_out;
  end if;
  end loop;
  <<show_out>>
  dbms_output.put_line('直接跳轉到show_out');
  end;*/

  /*======================遊標的使用========================*/
  -- 使用遊標處理多行記錄的事物

  --顯式遊標
  /*  declare
  v_deptno dept.deptno%type;
  v_dname dept.dname%type;
  v_loc dept.loc%type;
  v_record dept%rowtype;
  -- 定義遊標
  cursor c1 is
  select deptno,dname,loc from dept;
  
  cursor c2 is
  select * from dept;
  begin
  --打開遊標
  open c1;
  loop 
  fetch c1 into v_deptno,v_dname,v_loc; --獲取遊標數據
  dbms_output.put_line('遊標1--'||to_char(v_deptno)||v_dname||v_loc);
  exit when c1%notfound;
  end loop;
  --關閉遊標
  close c1;
  
  open c2;
  loop 
  fetch c2 into v_record;
  dbms_output.put_line('遊標2--'||to_char(v_record.deptno)||v_record.dname||v_record.loc);
  exit when c2%notfound;
  end loop;
  close c2;
  end;*/

  --帶參數遊標
  --例給工資低於特定值的員工加薪100
  /*declare
    v_record emp%rowtype;
  
    cursor c1(v_sal number default 1000) is
      select * from emp where sal < v_sal;
  begin
    for v_record in c1(3000) loop --注意這裏遊標都是隱式打開關閉
      dbms_output.put_line('員工號' || to_char(v_record.empno) || '原工資' ||
                           v_record.sal);
    end loop;
  
    for v_record in c1(3000) loop
      update emp set sal = sal + 100 where empno = v_record.empno;
    end loop;
  
    for v_record in c1(3000) loop
      dbms_output.put_line('員工號' || to_char(v_record.empno) || '現工資' ||
                           v_record.sal);
    end loop;
  
  end;*/

  -- 遊標修改或者刪除操作的時候  對遊標進行鎖定

  -- 設定某部門最低工資
  /*declare
   v_deptno dept.deptno%type:=&deptno;
   v_record emp%rowtype;
   cursor c1 is 
   select * from emp where deptno=v_deptno for update of sal nowait; -- 對sal列進行鎖定
   begin
   for v_record in c1 loop
   if v_record.sal<1500 then
   update emp set sal=1500 where current of c1; -- 遊標當前行對應的數據庫數據行
   end if;
   end loop;
   
  end;*/

  /* =====================異常處理========================*/
  /*
  1、oracle預定義異常24個 ——自動觸發
  2、oracle非預定義異常——用戶手動觸發
  3、用戶自定義異常
  */

  -- 1預定義異常
  /*DECLARE
    v_empno emp.empno%TYPE := &empno;
    v_sal   emp.sal%TYPE;
  BEGIN
    SELECT sal INTO v_sal FROM emp WHERE empno = v_empno;
    IF v_sal <= 1500 THEN
      UPDATE emp SET sal = sal + 100 WHERE empno = v_empno;
      DBMS_OUTPUT.PUT_LINE('員工號爲' || v_empno || '員工工資已更新!');
    ELSE
      DBMS_OUTPUT.PUT_LINE('員工號爲' || v_empno ||
                           '員工工資已經超過規定值!');
    END IF;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      DBMS_OUTPUT.PUT_LINE('數據庫中沒有員工號爲' || v_empno || '的員工');
    WHEN TOO_MANY_ROWS THEN
      DBMS_OUTPUT.PUT_LINE('程序運行錯誤!請使用遊標');
    WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE('發生其它錯誤!');
  END;*/

  -- 用戶自定義異常
  /*DECLARE
    v_empno  emp.empno%TYPE := &empno;
    v_record emp%rowtype;
    no_result exception;
  BEGIN
    UPDATE emp SET sal = sal + 100 WHERE empno = v_empno;
    if sql%notfound then
      --注意notfound是指影響了多少行 對查詢不適用
      raise no_result;
    end if;
  EXCEPTION
  
    WHEN no_result THEN
      DBMS_OUTPUT.PUT_LINE('捕獲到自定義異常,找不到數據');
    WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE('發生其它錯誤!');
  END;*/

  /*=======================存儲過程與函數=========================*/

  -- 函數——獲取某部門的工資總量
  /*  create or replace function get_salary_sum_of_dept(v_deptno number default 10, --參數默認值
                                                      v_count  out number)
    return number is
    v_salary_sum number;
  begin
    select count(*), sum(sal)
      into v_count, v_salary_sum
      from emp
     where deptno = v_deptno return v_salary_sum;
  exception
    when no_data_found then
      dbms_output.put_line('找不到數據');
    when others then
      dbms_output.put_line('出現異常啦');
  end get_salary_sum_of_dept;*/

  /*DECLARE
    V_num     NUMBER;
    V_sum     NUMBER;
    v_deptno_in dept.deptno%type:=&deptno;
  BEGIN
    --調用函數
    V_sum := get_salary(v_deptno_in, v_num);
    dbms_output.put_line('30號部門工資總和:' || v_sum || ',人數:' ||
                         v_num);
  END;*/

  --- 存儲過程
  -- 刪除某員工記錄
  /*  create or replace procedure delete_emp_by_id(v_empno in emp.empno%type) is
  begin
    delete from emp where empno = v_empno;
    exception
    when no_data_found  then
    dbms_output.put_line('員工號爲'||to_char(v_empno)||'不存在');
    when others  then
    dbms_output.put_line('出現異常啦');
  end delete_emp_by_id;
  
  -- 調用存儲過程
  execute delete_emp_by_id(30);*/



/*
  create or replace procedure proc_get_salary_sum_of_dept(v_deptno     number default 10, --參數默認值
                                                          v_count      out number,
                                                          v_salary_sum out number) is --注意存儲過程與函數的區別就是函數能有返回值,而存儲過程只能有輸出值而不能有返回值
begin
  select count(*), sum(sal)
    into v_count, v_salary_sum
    from emp
   where deptno = v_deptno;
exception
  when no_data_found then
    dbms_output.put_line('找不到數據');
  when others then
    dbms_output.put_line('出現異常啦');
end proc_get_salary_sum_of_dept;

  DECLARE
  V_num NUMBER; 
  V_sum NUMBER; 
  v_deptno_in dept.deptno%type := &deptno;
BEGIN
  --調用存儲過程
  proc_get_salary_sum_of_dept(v_deptno_in, v_num,v_sum); --注意與函數調用的差別
   dbms_output.put_line(to_char(v_deptno_in) || '號部門工資總和:' || v_sum || ',人數:' || v_num);
END;*/

以下是學習PL/SQL入門級別的練習範例,進攻初學者參考。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章