程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle數據庫基礎 >> PL/SQL定義部分之二復合數據類型

PL/SQL定義部分之二復合數據類型

編輯:Oracle數據庫基礎

復合類型

復合類型可以存儲多個值,包括記錄和集合。集合是一維的,但是可以在集合中放入其它集合,變成多維集合。集合又分為索引表、嵌套表和變長數組三種。要使用集合,我們首先要創建集合類型,然後聲明該類型的變量。我們可以在任何PL/SQL塊、子程序或包的聲明部分使用TABLE和VARRAY關鍵字來聲明集合類型。集合的作用域和同其他類型變量一樣,在一個塊或子程序中,當程序進入塊或子程序時有效,退出時失效。在包中,集合在我們第一次引用包的時候有效,直至會話終止時才失效。

一、記錄

記錄可以包括多個成員,從而可以保存多個值。記錄中的成員的數據類型可以不同。記錄在使用時必須先聲明記錄類型,然後定義記錄變量,最後才能在PL/SQL中使用。

示例1:

DECLARE
TYPE MyRecord IS RECORD(
name VARCHAR2(10),
age  SMALLINT
);
mr MyRecord;
BEGIN
mr.name:='zhangsan';
mr.age:=20;
DBMS_OUTPUT.PUT_LINE('姓名:'||mr.name||'    年齡:'||mr.age);
END;

示例2: DECLARE
TYPE MyRecord IS RECORD(
no    NUMBER(2),
name  VARCHAR2(14),
city  scott.dept.loc%TYPE
);
deptRecord MyRecord ;
BEGIN
--SELECT 語句後列的數目與記錄中的變量數目相同
SELECT deptno,dname,loc into deptRecord FROM DEPT WHERE DEPTNO=30;
DBMS_OUTPUT.PUT_LINE(deptRecord.no||':'||deptRecord.name||':'||deptRecord.city);
END;

示例3:

DECLARE
TYPE MyRecord IS RECORD(
no    NUMBER(2),
name  VARCHAR2(14),
city  scott.dept.loc%TYPE
);
deptRecord MyRecord;
BEGIN
--SELECT 語句後列的數目少於記錄中的變量數目
SELECT dname,loc INTO deptRecord.name,deptRecord.city FROM DEPT WHERE DEPTNO=30;
deptRecord.no:=30;
DBMS_OUTPUT.PUT_LINE(deptRecord.no||':'||deptRecord.name||':'||deptRecord.city);
END;

示例4:

DECLARE

--特殊定義記錄方式,記錄中變量的類型與dept表行的類型相同

deptRecord dept%ROWTYPE;
BEGIN
SELECT * INTO deptRecord FROM DEPT WHERE DEPTNO=30;
DBMS_OUTPUT.PUT_LINE(deptRecord.deptNo||':'||deptRecord.dname||':'||deptRecord.loc);
END;

二、索引表(關聯數組)

索引表就是鍵值集合,鍵是唯一的,用於查找對應的值。鍵可以是整數或字符串。第一次使用鍵來指派一個對應的值就是添加元素,而後續這樣的操作就是更新元素。

DECLARE
TYPE MyTableTypeName IS TABLE OF ElementType [NOT NULL]
INDEX BY Key_Type;
myName MyTableTypeName;

其中:MyTableTypeName是表類型的名稱,ElementType是元素的數據類型,NOT NULL表示不允許引用NULL值,Key_Type是下標的數據類型,BINARY_INTEGER PLS_INTEGER或VARCHAR2(Oracle9i及以後版本可用)。myName是表類型變量名。

示例1

DECLARE
TYPE MyTabelType IS TABLE OF dept.dname%TYPE
NOT NULL INDEX BY BINARY_INTEGER;
my MyTabelType;
BEGIN
SELECT DNAME INTO my(-3) FROM DEPT WHERE  deptno=20;
SELECT DNAME INTO my(-1) FROM DEPT WHERE  deptno=40;
DBMS_OUTPUT.PUT_LINE('my(-3):'||my(-3));
DBMS_OUTPUT.PUT_LINE('my(-1):'||my(-1));
END;

示例2:

DECLARE
TYPE MyTableType IS TABLE OF NUMBER
NOT NULL INDEX BY VARCHAR2(20);
my MyTableType;
BEGIN
my('China'):=1;
my('Japan'):=2;
my('USA'):=3;
DBMS_OUTPUT.PUT_LINE(my.first);
DBMS_OUTPUT.PUT_LINE(my.last);
DBMS_OUTPUT.PUT_LINE(my('China'));
DBMS_OUTPUT.PUT_LINE(my(my.last));
END;

三、嵌套表

要使用嵌套表,首先要創建嵌套表類型,其次聲明嵌套表類型變量,然後初始化嵌套表變量,最後引用嵌套表變量元素值。

1、定義嵌套表類型

TYPE MyNestedTableType IS TABLE OF ElementType [NOT NULL];

其中:

MyNestedTableType是嵌套表類型的名稱。ElementType是嵌套表元素的類型,它是可以除了REF CURSOR類型之外的任何PL/SQL類型,但是對於全局嵌套表(CREATE TYPE創建)來說,以下類型也是不允許的:BINARY_INTEGER  PLS_INTEGER  BOOLEAN  LONG  LONG RAW  NATURAL   NATURALN POSITIVE  POSITIVEN  REF CURSOR  SIGNTYPE  STRING 。NOT NULL表示元素值不能為NULL。

 

示例:

DECLARE
--定義記錄
TYPE DeptRecord IS RECORD(
no    NUMBER(2),
name  VARCHAR2(14),
city  scott.dept.loc%TYPE
);
--定義游標
CURSOR  DeptCursor IS SELECT * FROM DEPT;
--定義嵌套表元素類型時使用%TYPE
TYPE DNameList IS TABLE OF dept.dname%TYPE;
--定義嵌套表元素類型時使用表的%ROWTYPE
TYPE DeptList1  IS TABLE OF DEPT%ROWTYPE;
--定義嵌套表元素類型時使用游標的%ROWTYPE
TYPE DeptList2  IS TABLE OF DeptCursor%ROWTYPE;
--定義嵌套表元素類型時使用記錄類型
TYPE DeptList3  IS TABLE OF DeptRecord ;
--在SQL語句中定義嵌套表類型
CREATE TYPE PhoneList IS TABLE OF VARCHAR2(10);

2、聲明嵌套表類型變量

示例:

DECLARE
TYPE DNameList IS TABLE OF dept.dname%TYPE;
nameList1 DNameList;
nameList2 nameList1%TYPE;   --使用%TYPE聲明嵌套表類型變量
--在存儲過程參數中定義嵌套表類型變量
CREATE OR REPLACE PROCEDURE proc_name(nameList  IN DNameList)

注意:不能將嵌套表類型和嵌套表類型變量同名,大小寫不同也不可,因PL/SQL不區分大小寫

3、初始化嵌套表類型變量

嵌套表必須先通過構造方法初始化(索引表不需要通過構造方法進行初始化),否則嵌套表變量為NULL,在初始化中元素個數沒有限制。

示例:

DECLARE
TYPE DNameList IS TABLE OF dept.dname%TYPE;
my DNameList ;
BEGIN
my:=DNameList('CORESUN','CORESUN','CORESUN');

注意:my變量在初始化時傳入了3個參數,那麼嵌套表長度就是3,以後使用時長度不夠,必須通過extend函數進行擴展長度。如果在構造方法中沒有傳入任何參數,則嵌套表長度為0。

也可以在聲明聲明嵌套表類型變量的同時進行初始化,如:

my DNameList:=DNameList('CORESUN','CORESUN','CORESUN');

如果定義元素類型時沒有指定NOT NULL,在構造方法中也可以傳入NULL,如:

my:=DNameList('CORESUN',NULL,'CORESUN');

4、引用嵌套表類型變量

通過嵌套表變量和圓括號裡的索引值來引用嵌套表中的元素,嵌套表的下標是從1開始編號,最大至231 ,下標可以是一個整數,也可以是整數表達式。

示例:

DECLARE
TYPE DNameList IS TABLE OF dept.dname%TYPE;
my DNameList ;
BEGIN
my:=DNameList(NULL,'CORESUN','CORESUN');
SELECT DNAME INTO my(2) FROM dept where deptno=20;
my(1):='CORESUN';
--my(4):='CORESUN';
DBMS_OUTPUT.PUT_LINE(my(1));
DBMS_OUTPUT.PUT_LINE(my(2));
END;

四、嵌套表應用示例

示例1:創建記錄類型的嵌套表

DECLARE
TYPE DeptRecord IS RECORD(
no    NUMBER(2),
name  VARCHAR2(14),
city  scott.dept.loc%TYPE
);
TYPE DeptRecordList IS TABLE OF DeptRecord;

示例2:嵌套表用在另一個表的內部

1、創建全局嵌套表類型

--當嵌套表作為表列的類型時,要先創建,這樣的嵌套表我們稱為全局嵌套表

CREATE OR REPLACE TYPE PHONE_TYPE IS TABLE OF VARCHAR2(20);
/
CREATE TABLE person
(
id NUMBER,
name VARCHAR2(10),
sal NUMBER(6,2),
phone PHONE_TYPE
) NESTED TABLE phone STORE AS PHONE_TABLE;

2、向person表插入數據:

INSERT INTO person VALUES(1,'SCOTT',800,PHONE_TYPE('13256789876','031198765432'));
INSERT INTO PERSON VALUES(20,'CORESUN',2000,PHONE_TYPE('13999999999','13098765345','01064890987'));

3、查詢嵌套表列的數據:

查詢全部的列信息

SELECT * FROM PERSON;

在isql*plus中結果如下:

通過嵌套表變量顯示信息

DECLARE
pTable PHONE_TYPE;
BEGIN
SELECT phone into pTable FROM person WHERE name='SCOTT';
FOR   i   IN 1..pTable.COUNT LOOP
DBMS_OUTPUT.PUT_LINE('號碼'||i||':'||pTable(i));
END LOOP;

結果如下:

號碼1:13256789876

號碼2:031198765432

4、更新嵌套表數據:

DECLARE
pTable PHONE_TYPE:=PHONE_TYPE('034223455432','13888888888');
BEGIN
UPDATE person SET phone=pTable WHERE name='SCOTT';
END;

四、可變數組(VARRAY數組)

VARRAY數組是一種集合數據類型,也可以作為表的列來使用,該集合的下標從1開始,並且元素個數是有限制的。語法如下:

DECLARE
TYPE MyArrayTypeName IS VARRAY(size) OF ELEMENT_TYPE [NOT NULL];
my MyArrayTypeName

其中MyArrayTypeName 是數組類型的名字,size表示數組最多存儲多少個元素,ELEMENT_TYPE是元素的類型,NOT NULL不允許使用NULL值,my是數組變量的名稱。

示例1:

DECLARE
TYPE MyVArrayType IS VARRAY(10) OF dept.dname%TYPE NOT NULL;

--構造方法中最多可以有10(size)個元素

--既是沒有定義NOT NULL,也不會自動為4-10元素賦NULL值

nameArray MyVArrayType:=MyVArrayType('1','2','3');
BEGIN
SELECT dname into nameArray(1) from dept where deptno=20;
SELECT dname into nameArray(2) from dept where deptno=30;
DBMS_OUTPUT.PUT_LINE(nameArray(1));
DBMS_OUTPUT.PUT_LINE(nameArray(2));
DBMS_OUTPUT.PUT_LINE(nameArray(3));
END;

結果如下: RESEARCH
SALES
3

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved