數據庫學習11-PLSQL語法

1.pl/sql
  1.1  pl/sql是什麼;
       pl/sql(Procedural Language extensions to the Strutured Query Language)過程化語言和結構化查詢語言結合的編程語言;
  1.2  pl/sql和sql的不同;
       1.2.1  pl/sql支持更多的數據類型和操作符;
       1.2.2  可以過程化邏輯控制編程;
  1.3  pl/sql怎麼過程化;
       1.3.1 條件控制
       1.3.2 循環控制
       1.3.3 順序
2.pl/sql塊
  2.1  pl/sql塊是什麼;
       2.1.1 pl/sql是塊結構語言,pl/sql程序由邏輯塊組成;
       2.1.2 邏輯塊包括函數、過程、匿名塊;
  2.2  pl/sql匿名塊和格式;
       沒有名字,格式:
       [declare declarations] --聲明部分(不是必須)
       begin 
           --executable statments;  (必須)可執行部分 數據操作語句、事務控制語句
       [exception handlers]   --異常處理部分(不是必須的)
       end;   --(必須)
3.介紹pl/sql
  3.1  和sql一樣不區分大小寫
  3.2  變量和常量的聲明
       3.2.1 變量的聲明和初始化;
             變量名 數據類型[(範圍)] := 初始值;
             變量名 數據類型[(範圍)] default 初始值;
       3.2.2 常量的聲明
             常量名 constant 數據類型[(範圍)] := 初始值;
  3.3  數據類型和操作符
       3.3.1 數據類型說明 個數,開始;
             3.3.1.1 數字類型 number
             3.3.1.2 字符類型 char,varchar,varchar2
             3.3.1.3 時間類型 date,timestamp
             3.3.1.4 大文本類型 clob,blob
             3.3.1.5 布爾類型 boolean(true,false,null)
             3.3.1.6 屬性類型 %type,%rowtype
       3.3.2 操作符說明 (賦值:=,乘方**,範圍..,標識<< >>,連接||,--,/**/,關係運算符=,<>,!=,>,<,>=,<=);
  3.4  打印語句;
       set serveroutput on開始  以'/'結束來執行語句塊;
       DBMS_OUTPUT.PUT_LINE('comment');
  3.5  過程控制 (&varname);
       3.5.1 條件 
       3.5.2 循環
       3.5.3 順序
4.異常
  4.1  預定義異常
  4.2  自定義異常
       4.2.1 raise 聲明異常出現在什麼情況
       4.2.2 raise_application_error() -- (-20000 .. -20999);創建一個用戶定義的錯誤信息提示






預定義異常:
異常名                        說明
--------------------------------------------------------------------------------
ACCESS_INTO_NULL          未初始化對象時出現
CASE_NOT_FOUND            在CASE語句中的選項與輸入的數據不匹配時出現
COLLECTION_IS_NULL       給尚未初始化的表或數組賦值時出現
CURSOR_ALREADY_OPEN  試圖重新打開已打開的遊標時出現,重新打開遊標
                                         前必須先關閉
DUP_VAL_ON_INDEX        試圖將重複的值存儲在使用唯一索引的列中時出現
INVALID_CURSOR             執行非法遊標運算時出現,比如打開一個尚未打開
                                         的遊標
INVALID_NUMBER            將字符串轉換爲數字時出現
LOGIN_DENIED                輸入的用戶名或密碼無效時出現
NO_DATA_FOUND            表中不存在請求的行時出現或者引用已刪除的元素時
STORAGE_ERROR             內存損壞或PL/SQL耗盡內存時出現
TOO_MANY_ROWS            執行select into語句後返回多行時出現
VALUE_ERROR                  產生大小限制錯誤時出現

ZERO_DIVIDE                   除數爲零時出現


/*
  回顧
declare
  --聲明部分
begin
  --可執行部分
exception
 
end;

*/
--變量
declare
  a number default 1;  --初始化第一種方式
  --a number := 1;     --初始化第二中方式
  var_col emp.ename%type;
  var_col2 NUMBER;
  var_const CONSTANT VARCHAR2(10); --常量
begin
  a := 2;  --給變量賦值
  select ename,sal into var_col,var_col2 from emp 
    WHERE empno = 7788;
    
end;

--順序、條件、循環結構
/* 
 if 條件表達式 then
 elsif 條件表達式 then
 else  
 end if;
 */
/*
  case 變量
    when 值1 then 
    when 值2 then 
    ...
    else
  end case;
*/
/*
  循環體
  loop 
  end loop;
  
  第一種循環:
  loop 
    exit when 表達式;
  end;  
  第二種:
  while 表達式 
  loop
  end loop;
  第三種:
  for 變量 in 範圍 
  loop
  end loop;
*/
DECLARE
  salary NUMBER;
  e_count NUMBER;
BEGIN
  SELECT COUNT(*) INTO e_count FROM emp;
  FOR n IN 1..e_count LOOP
    SELECT sal INTO salary FROM 
     (SELECT ROWNUM rm,t.* FROM emp t)  
      WHERE rm = n;
    dbms_output.put_line(salary);  
  END LOOP;
END;

declare
  d_id number;
  d_name dept.dname%type;
  e_name emp.ename%type;
  d_count number;
  e_count number;
begin
  select count(*) into d_count from dept;
  for i in 1..d_count loop
     select deptno,dname into d_id,d_name 
       from (select rownum num,t.* from dept t)
     where num = i;
     dbms_output.put_line('部門名稱:'||d_name);
     select count(*) into e_count from emp
        where deptno=d_id;
      dbms_output.put('部門人員:');
     for j in 1..e_count loop
       select ename into e_name from 
         (select rownum num,t.* from emp t 
            where deptno = d_id)
       where num = j;
       if j<e_count then 
          dbms_output.put(e_name||',');
       else
          dbms_output.put(e_name);
       end if;
     end loop;
     dbms_output.put_line('');
     dbms_output.put_line('');
  end loop;
end;

/*
  6. 增加指定部門員工的工資10%。
    然後打印所有的最新工資,
    以及所有工資之和。
*/
DECLARE
  e_sal NUMBER;
  e_id NUMBER;
  d_id NUMBER;
  c NUMBER;
  s_sum NUMBER DEFAULT 0;
BEGIN
  d_id := &abc;
  SELECT COUNT(*) INTO c FROM emp 
    WHERE deptno = d_id;  --記錄數
  FOR i IN 1..c LOOP
    SELECT empno,sal INTO e_id,e_sal FROM 
      (SELECT ROWNUM num,t.* FROM emp t WHERE deptno=d_id)
    WHERE num = i; 
    dbms_output.put_line(e_id||'更新前的薪水是:'||e_sal);
    e_sal := e_sal*1.1;
    dbms_output.put_line(e_id||'更新後的薪水是:'||e_sal);
    UPDATE emp SET sal = e_sal WHERE empno = e_id;
    s_sum := e_sal+s_sum;
  END LOOP;
    dbms_output.put_line('薪水總和是:'||s_sum);
  COMMIT;
END;

--異常
DECLARE
  a NUMBER;
BEGIN
  SELECT sal INTO a FROM emp 
     WHERE ename = 'nimei';
  dbms_output.put_line(a);
EXCEPTION 
  WHEN no_data_found THEN
    dbms_output.put_line('未找到數據');
END;

DECLARE
  re NUMBER;
BEGIN
   re := 10/0;
EXCEPTION 
   WHEN zero_divide THEN
     dbms_output.put_line('除數不能爲0');
END;

BEGIN
 --正常的程序代碼 try
EXCEPTION 
  WHEN zero_divide THEN
     dbms_output.put_line('除數不能爲0');
  WHEN no_data_found THEN
    dbms_output.put_line('未找到數據');
  WHEN OTHERS THEN
    dbms_output.put_line('所有異常');
END;

DECLARE
  re NUMBER;
BEGIN
   re := 10/0;
EXCEPTION 
   WHEN OTHERS THEN  
     dbms_output.put_line('異常');
END;

--自定義異常 
DECLARE
  n NUMBER;
  my_exception EXCEPTION; --定義一個異常
BEGIN
  n := &hhh;
  IF n = 0 THEN 
    RAISE my_exception;  --拋出異常的情景
  END IF;
EXCEPTION
  WHEN my_exception THEN
    dbms_output.put_line('手賤....');
END;  
--根據編號查詢工作崗位job,
--如果是查詢的是Persident,就拋出系統錯誤
--‘老總不出面’ 
DECLARE
 e_job VARCHAR2(15);
 per_exception EXCEPTION;
BEGIN
  SELECT job INTO e_job FROM emp 
    WHERE empno=ⅈ
  IF upper(e_job) = 'PRESIDENT' THEN
     RAISE per_exception;
  END IF;
EXCEPTION 
  WHEN per_exception THEN
    raise_application_error(-20123,'老總不出面');
END;

--catch異常,不輸出打印語句,拋出系統錯誤
DECLARE
  re NUMBER;
BEGIN
   re := 10/0;
EXCEPTION 
   WHEN OTHERS THEN  
     --dbms_output.put_line('異常');
     raise_application_error(-20100,'系統崩潰'); -- "-20000~-20999"
END;

--動態執行
BEGIN
  EXECUTE IMMEDIATE
     'CREATE TABLE tab(t NUMBER)';
END;

BEGIN
  EXECUTE IMMEDIATE
     'drop TABLE tab cascade constraints';
END;

BEGIN
  EXECUTE IMMEDIATE
  'SELECT * FROM emp WHERE empno = :1'
  USING '7788';
END;



發佈了108 篇原創文章 · 獲贊 22 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章