Oracle 中的PL/SQL基礎、存儲過程、觸發器、函數、包(學習筆記)

    一、PL/SQL是什麼?

    PL/SQL(procedural language/SQL)是oracle在sql上的擴展,pl/sql不僅允許嵌入sql語言,而且可以定義常量和變量,允許使用條件語句和循環語句,允許使用例外處理各種錯誤,這使得它的功能十分強大。但是移植性不好。

1. 實例1 只包括執行部分的PL/SQL塊

set serveroutput on;
begin
dbms_output.put_line('asdasdasdas');
end;
/

set serverout 選項爲打開顯示。

dbms_output爲oracle提供的包


2. 實例2 包含輸入的PL/SQL塊

declare 
v_name varchar2(10);
v_sal number(7,2);
begin
  select ename,sal into v_name,v_sal from emp where empno=&no;
  dbms_output.put_line('僱員名:'||v_name);
  dbms_output.put_line('薪水:'||v_sal);
  end;
  /

說明:首先聲明瞭類型爲varchar2的v_name變量和number的v_sal,在pl/sql語句塊中執行搜索,用empno搜索出emp表的ename和sal字段的值,&no表示要在執行過程中輸入empno這個參數。把查詢的ename值存入v_name中,sal放入v_sal中,然後再顯示出來。


3. 實例3 包含異常處理的PL/SQL塊

declare 
v_name varchar2(10);
v_sal number(7,2);
begin
  select ename,sal into v_name,v_sal from emp where empno=&no;
  dbms_output.put_line('僱員名:'||v_name);
  dbms_output.put_line('薪水:'||v_sal);
exception
when no_data_found then
  dbms_output.put_line('輸入數據有誤!');
  end;
  /

這個例子前面與實例2完全相同,只是加上了異常處理部分。這是一個完整的PL/SQL塊。

二、過程(存儲過程)

    存儲過程用於執行特定的操作。建立過程時,既可以指定輸入參數(in),也可以指定輸出參數(out)。通過在過程中使用輸入參數,可以將數據傳遞到執行部分;通過使用輸出參數,可以將執行部分數據傳遞到應用環境中。在sqlplus中使用create procedure命令 創建過程。

create procedure procedure_name(name varchar2,sala number) is
begin
  update emp set sal=sala where ename=name;
  end;
  /

說明: 創建一個名爲procedure_name的過程,它又2個輸入參數,varchar2類型的name和number類型的sala,begin與end之間的是plsql塊。

三、函數

    函數用於返回特定的數據,在建立函數時,頭部必須包含return子句,而函數體內必須包含return返回的數據,可以用create function 命令建立函數。實例:

create function function_name(name varchar2)
return number is
salary number(7,2);
begin
  select sal*12 into salary from emp where ename=name;
  return salary;
  end;
  /

四、包

    包用於在邏輯上組合函數和過程,由包規範和包體組成。可以用create package 命令創建包。

實例:

create package package_name is
procedure procedure_name(name varchar2,sal number);
function function_name(name varchar2) return number;
end;
/

    包的規範只包含對函數和過程的說明,但是沒有函數和過程的實現代碼,包體用於實現包規範中的函數和過程,建立包體使用create package body命令。

create package body package_name is 
procedure procedure_name(name varchar2,sala number) is  --創建過程
begin
  update emp set sal=sala where ename=name;
  end;
function function_name(name varchar2)    --創建函數
return number is
salary number(7,2);
begin
  select sal*12 into salary from emp where ename=name;
  return salary;
  end;
  end;
  /  --結束

    使用包內的函數或者過程:

exce package_name.procedure_name('SMITH',500); --調用過程
var sal number;  --聲明變量
call package_name.function_name('SMITH') into:sal;  --調用函數

五、觸發器

觸發器指隱含執行的過程,當創建觸發器時,必須指定觸發的條件和觸發的操作。常用的觸發事件包括insert、update、delete,而觸發操作實際就是一個PL/SQL塊,可以使用create trigger命令來創建一個觸發器。

六、變量

    在編寫PL/SQL程序時可以定義變量和常量,主要包括:

1.標量類型(scalar)

2.複合類型(composite)

3.參照類型(reference)

4.lob(large object)

   (1) 標量定義案例:

定義一個變長字符串:v_name varchar2(10);

定義一個小數,範圍-9999.99到9999.99: v_num number(6,2);

定義一個小數並賦值: v_num number(5,2):=10.6; ":="相當於“=”,是賦值符號

定義一個日期類數據: v_date date;

定義一個布爾變量,不能爲空,初始值爲true:v_bool boolean not null default true;

    (2)複合變量介紹:

用於存放多個值的變量,類似於高級語言的結構體,主要包括:PL/SQL記錄,PL/SQL表、嵌套表、varray。

自定義一個record類型

type type_name is record( name varchar2(10),sal number(5,2) );

自定義一個PL/SQL表類型

type type_name is table of table_name.field_name%type index by binary_integer;

    (3)參照類型:

參照變量是指用於存放數值指針的變量,通過使用參照變量,可以使應用程序共享相同的對象,從而降低內存佔用的空間。在編寫PL/SQL程序時,可以使用遊標變量和對象類型變量2種參照變量類型。

    遊標變量:使用遊標時,當定義遊標時不需要指定相應的selec語句但是當使用遊標時(open時)需要指定select語句,這樣一個遊標就與select語句結合了。

declare  --聲明
type type_name is ref cursor;  --自定義type_name爲遊標類型
cursor_name type_name ;        --聲明一個名爲cursor_name的type_name遊標
v_ename emp.ename%type;        --聲明一個與emp表中的ename類型相同的變量v_ename
v_sal emp.sal%type;            --聲明一個與emp表中的sal類型相同的變量v_sal
begin --執行
open cursor_name for select ename,sal from emp where deptno=&no; 
    --打開遊標,並指向select語句
loop  --循環
    fetch cursor_name into v_ename,v_sal;--取出遊標中的數據到變量
    dbms_output.put_line('名字:'||v_name||'工資:'||v_sal);  --顯示
    exit when cursor_name%notfound; --判斷遊標是否爲空,爲空就退出
    end loop;
    end;
    /

或者這樣聲明遊標:

declare
cursor cus is   --聲明遊標並指向
select ename,sal from emp where deptno=&no; 
v_ename emp.ename%type;
v_sal emp.sal%type;
begin
open cus;
loop
fetch cus into v_ename,v_sal;
dbms_output.put_line('name:'||v_ename||'sal:'||v_sal);
exit when cus%notfound;
end loop;
end;
/


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章