在oracle中有一個很重要的東東---包,package。(本文中的代碼都是在SCOTT中emp表中實現的)
引用他人的定義--包是一種資料庫物件,將邏輯上相關的PL/SQL類型、對象和子程式組合成一個更大的單位。包有兩個部分:包說明(specification)和包體(body)。說明部分是為應用程式的介面,它申明類型、常量、例外、遊標和可用的子程式。體定義遊標和子程式,實現說明。應用程式僅對包說明中的申明是可見的和可存取。如果ORACLE具有Procedure選件,包可以編譯、存貯在ORACLE資料庫中,其內容可為許多應用共用。當使用者第一次調用一封裝的子程式時,整個封裝入到記憶體,所以在以後對包中子程式調用時,不再需要I/O操作,故包可提高效率和改進效能。
我個人的理解是--我們可以在包中寫預存程序、函數,這是我們最常用的。那麼包中到底可以有什麼東西了,如,這是在oracle資料庫中截取的,應該更有說服力。
在oracle中有一個包 dbms_output,我們就可以調用在這個包中的函數 put_line。
包分為包說明和包體,下面就分別建立一個包說明和包體,
create or replace package sp_package is --注意,這裡包的名字是 sp_package,後面要用關鍵字 is
procedure update_sal(name emp.ename%type,newsal emp.sal%type); --定義了一個預存程序
function income(name emp.ename%type) return number; --定義了一個函數,傳回值資料類型是整形的
end;
包體
create or replace package body sp_package is
procedure update_sal(name emp.ename%type,newsal emp.sal%type) is --具體實現包說明中的預存程序
begin
update emp set sal=newsal where ename=name;
end;
function income(name emp.ename%type) --具體說明包說明中的函數
return number is salary number;
begin
select sal*12 into salary from emp where ename=name;
return salary;
end;
end;
call sp_package.update_sal('MILLER',1500); --調用這個包中的預存程序,當然如果要訪問其他方案的包,還要在包的前面加上方案名。
如果有異常,則自己處理吧。
在以上的sql語句,我們返回的都是一個值,沒有返回多個值,如果返回的是多個值呢,我們應該用什麼容器去承載它,oracle有一個概念,叫做複合變數,用於存放多個值的變數,包括pl/sql 記錄,pl/sql 表,巢狀表格,varray;
PL/SQL 記錄:下面的sql語句就定義了一個record(記錄) emp_record_type,他可以承載姓名,工資,工作類型,是一個記錄喔!定義一個記錄的格式是
declare type 記錄名 is record(...);這和C語言中的結構定義比較相像。
declare
type emp_record_type is record( --這裡你需要注意書寫的格式是什麼
name emp.ename%type,
salary emp.sal%type,
title emp.job%type);
emp_record emp_record_type; --定義了一個emp_record_type類型的變數 emp_record
begin
select ename,sal,job into emp_record from emp where empno=7782;
dbms_output.put_line(emp_record.name);
end;
PL/SQL記錄表相當於數組,進階語言裡的數組的下表不能為負數,但此時的數組的下標可以是負數,只是沒有值罷了。定義記錄表的格式是
declare type 記錄表名 is table of 承載內容 index by binary_integer;
declare
type sp_table_type is table of emp.ename%type index by binary_integer;
sp_table sp_table_type;
begin
select ename into sp_table(0) from emp where empno=7788;
dbms_output.put_line(sp_table(0));
end;
參照變數是指用於存放數值指標的變數,通過使用參照變數,可以使得應用程式共用相同對象,從而降低使用空間,在編寫的時候,可以使用遊標變數(ref cursor)和物件類型變數(ref obj_type) 兩種參照變數類型。使用遊標 當定義遊標時不需要指定相應的select語句,但是當使用遊標時需指定select語句,這樣就和select語句結合了。
declare
2 --定義遊標類型
3 type sp_emp_cursor is ref cursor;
4 --定義遊標變數
5 test_cursor sp_emp_cursor;
6 --定義變數
7 v_ename emp.ename%type;
8 v_sal emp.sal%type;
9 begin
10 --執行
11 open test_cursor for select ename,sal from emp where deptno=&no; ---格式 open 遊標變數名 for sql語句
12 loop ---迴圈讀取遊標中的值 注意loop的用法 loop....end loop。
13 fetch test_cursor into v_ename,v_sal; --讀取內容,放在變數裡面,注意這裡存放的順序,v_ename to ename,v_sal to sal
14 exit when test_cursor%notfound; --如果沒有資料,退出迴圈
15 dbms_output.put_line(v_ename||v_sal);
16 end loop;
17 --close test_cursor; --這裡關閉遊標和開啟遊標時不同的,在Java裡面調用,我測試的是如果有這句,則不能讀取資料,你可以試試
18 end;