PL/SQL

PL/SQL

PL/SQL是一種高級數據庫程序設計語言,該語言專門用於在各種環境下對ORACLE數據庫進行訪問。由

於該語言集成於數據庫服務器中,所以PL/SQL代碼可以對數據進行快速高效的處理。除此之外,可以在

ORACLE數據庫的某些客戶端工具中,使用PL/SQL語言也是該語言的一個特點。

PL/SQL是對SQL語言存儲過程語言的擴展。

PL/SQL程序由三個塊組成,即聲明部分,執行部分,異常處理部分。

declare 
    /*聲明部分  聲明PL/SQL用到的變量,類型及遊標,以及局部的存儲過程和函數*/
begin
    /*執行部分  過程及SQL語句*/
exception
    /*異常處理部分  錯誤處理*/
end;

其中執行部分是必須有的 (begin…..end;)

PL/SQL塊可以分爲三類

  • 無名塊:動態構造,只能執行一次
  • 子程序:存儲在數據庫中的存儲過程、函數及包等。在數據庫建立之後可在其他程序調用它們。
  • 觸發器:當數據庫發生操作時,會觸發一些事件,從而自動執行相應的程序。
    declare 
    v_name varchar2(20) := 'zhangsan';
    v_age number := 33;
    begin 
      dbms_output.put_line(v_name||'  '||v_age);
    end;

命名:

標識符 命名規則
程序變量 v_name
程序常量 c_name
記錄類型 name_record
遊標變量 name_cursor
異常標識 e_name

:= 賦值號 => 關係號

||連接字符 null+<數字>=null null+<字符串>=<字符串>

boolean : true,false,null

記錄類型

記錄類型是把邏輯相關的數據作爲一個單元存儲起來,稱爲PL/SQL record的域(field),其作用是存放互不相同但邏輯相關的信息。

記錄類型是把邏輯相關的數據作爲一個單元存儲起來,稱爲PL/SQL record的域(field),其作用是存放互不相同但邏輯相關的信息。

語法: (在 declare 中定義)

type name_record is record(

field1 type ( := exp1),

field2 type ( := exp2)

);

declare 
type test_record is record(
v_name varchar2(20),
v_sal number
);
v_emp test_record;
v_id number := 100;
begin 
  select last_name,salary into v_emp from employees where employee_id=v_id;
  dbms_output.put_line(v_emp.v_name||' id:'||v_id||'  salary:'||v_emp.v_sal);
end;

%rowtype 各行數據類型

%type 對於數據類型

使用%rowtype 特性的優點在於:

  • 所引用的數據庫中列的個數和數據類型可以不必知道

  • 所引用的數據庫中列的個數和數據類型可以實時改變

 declare 
    emp_record employees%rowtype;
    v_id employees.employee_id%type := 100;
    v_pay number;
    begin
      select * into emp_record from employees where employee_id=v_id;
      dbms_output.put_line(emp_record.last_name||' id:'||emp_record.employee_id||'  salary:'||emp_record.salary);

      v_pay:=emp_record.salary*(1+emp_record.commission_pct);
      ---- number + null = null          varchar2 + null = varchar2     ----------
      dbms_output.put_line(v_pay);
      dbms_output.put_line('voer!!!');

      v_pay:=emp_record.salary*(1+nvl(emp_record.commission_pct,0));
      dbms_output.put_line(v_pay);
      dbms_output.put_line('really voer!!!');
    end;

這裏注意1+emp_record.commission_pct與1+nvl(emp_record.commission_pct,0)結果的區別

– number + null = null varchar2 + null = varchar2

–if 條件 then

– sql 和 pl/sql

– end if;

declare 
  v_id employees.employee_id%type;
  v_sal employees.salary%type;
  v_comment varchar2(50);
begin
  v_id := 104;
  select salary into v_sal from employees where employee_id=v_id;

  if v_sal<1500 then
    v_comment := 'fairly less';
    elsif v_sal<3000 then
      v_comment :='a little more';
      else
        v_comment :='good';
  end if;

  dbms_output.put_line(v_comment);
end;

–case selector when 條件1 then 結果1

– when 條件2 then 結果2

– else 結果3

–end;

declare 
v_garde char(1);
v_comment varchar2(50);
begin
  v_garde := 'A';

    v_comment:=
    case v_garde when 'A' then 'excellent'
                 when 'B' then 'good'
                 else 'so so'
    end;

    dbms_output.put_line(v_comment);
end;

–loop

–要執行語句;

–exit when 條件; 條件滿足,立即直接退出循環

–end loop;

declare 
i number :=0;
begin

  loop
    exit when i =10;
    i := i+1;
    dbms_output.put_line(i);
  end loop;

end;

–whlie 條件 loop

– 要執行語句;

–end loop;

declare 
i number := 0;
begin

  while i <10 loop
    i := i+1;
    dbms_output.put_line(i);
  end loop;

end;

–for 循環計數器 in (reverse)下限 .. 上限 loop

– 要執行語句;

–end loop;

–每循環一次,循環變量自動加1。in 後面的 下限,上限必須從小到大。可以使用exit退出循環

注意:for後面的循環變量相當於新聲明的變量,且可以和declare裏的同名,與declare裏的變量無關

declare 
i number :=0;
minnum number :=3;
maxnum number :=7;
begin 
  dbms_output.put_line(i);

  for i in minnum..maxnum loop
    dbms_output.put_line(i);
  end loop;

  dbms_output.put_line(i);
  --for後面的循環變量相當於新聲明的變量,且可以和declare裏的同名,與declare裏的變量無關

  for ii in minnum..maxnum loop
    dbms_output.put_line(i);
  end loop;

end;

標號和GOTO

PL/SQL中的GOTO語句:無條件跳轉到指定的標號去

goto label;

……

<< label >>

declare
i number := 0;
begin
  loop
    i:=i+1;
    dbms_output.put_line(i);
    if i=10 then
      goto test_label;
    end if;
  end loop;
  <<test_label>>
  dbms_output.put_line('end!!!');
end;

異常處理

異常情況處理(EXCEPTION)是用來處理正常執行過程中未預料的事件,程序塊的異常處理預定義的錯誤和自定義錯誤,由於 PL/SQL 程序塊一旦產生異常而沒有指出如何處理時,程序就會自動終止整個程序運行。

三種類型的異常錯誤

  • 預定義錯誤
    ORACLE 預定義的異常情況大約有 24 個。對這種異常情況的處理,無需在程序中定義,由 ORACLE 自動
    將其引發。
  • 非預定義錯誤
    即其他標準的 ORACLE 錯誤。對這種異常情況的處理,需要用戶在程序中定義,然後由 ORACLE 自動將
    其引發。
  • 用戶定義錯誤
    程序執行過程中,出現編程人員認爲的非正常情況。對這種異常情況的處理,需要用戶在程序中定義,
    然後顯式地在程序中將其引發。

預定義錯誤處理:只需在 PL/SQL 塊的異常處理部分,直接引用相應的異常情況名

begin ....
exception
  when no_data_found then dbms_output.put_line('沒找到數據');
  when others then dbms_output.put_line('不明原因');
end;

非預定義錯誤處理:

1.在PL/SQL塊定義部分定義異常

異常名 exception;

2.將定義好的異常與標準的ORACLE錯誤聯繫起來

pragma exception_init ( 異常名, 錯誤代碼 );

3.在 PL/SQL 塊的異常處理部分對異常情況做出相應的處理

declare
v_deptno number :=&deptno;
deptno_remaining exception ;
pragma exception_init(deptno_remaining,-2292);
begin
  delete from departments where department_id=v_deptno;
exception
  when deptno_remaining then dbms_output.put_line('不讓刪');
  when others then dbms_output.put_line('不明原因');
end;

用戶定義錯誤處理

1.在 PL/SQL 塊的定義部分定義異常情況:

異常名 exception;

2.raise 異常;

3.在 PL/SQL 塊的異常處理部分對異常情況做出相應的處理

declare
v_empno number := &empno;
no_result exception;
begin
  update employees set salary=6666 where employee_id=v_empno;
  if sql%notfound then
    raise no_result;
  end if;
exception
  when no_result then dbms_output.put_line('沒找到員工');
  when others then dbms_output.put_line('不明原因');
end;
發佈了42 篇原創文章 · 獲贊 2 · 訪問量 7939
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章