1、PL/SQL塊結構php
前邊咱們已經介紹了PL/SQL塊的結構,再來回顧一下:css
DECLARE
/* * 聲明部分——定義常量、變量、複雜數據類型、遊標、用戶自定義異常 */ BEGIN /* * 執行部分——PL/SQL語句和SQL語句 */ EXCEPTION /* * 異常處理部分——處理運行異常 */ END; /*塊結束標記 */
要實現PL/SQL程序設計,先介紹以下的基本內容:sql
2、標識符數據庫
PL/SQL程序設計中的標識符定義與SQL的標識符定義的要求相同:express
注意: 通常不要把變量名聲明與表中字段名徹底同樣,若是這樣可能獲得不正確的結果。編程
3、變量數組
1. 變量定義ruby
聲明:網絡
variable_name Type;
示例:數據結構
my_var NUMBER(4);
賦值:
variable := expression ;
示例:
my_var := 32 * 8 + 79;
-- 聲明並賦值 cnt NUMBER(2) := 3;
2. 變量做用域
在PL/SQL編程中,若是在變量的定義上沒有作到統一的話,可能會隱藏一些危險的錯誤,這樣的緣由主要是變量的做用域所致。變量的做用域是指變量的有效做用範圍,與其它高級語言相似,PL/SQL的變量做用範圍特色是:
4、運算符
1. 關係運算符
運算符 | 說明 |
---|---|
= | 等於 |
<> , != , ~= , ^= | 不等於 |
< | 小於 |
> | 大於 |
<= | 小於等於 |
>= | 大於等於 |
2. 邏輯運算符
運算符 | 說明 |
---|---|
AND | 邏輯與 |
OR | 邏輯或 |
NOT | 邏輯非,取反 |
3. 算術運算符
運算符 | 說明 |
---|---|
+ | 加 |
- | 減 |
* | 乘 |
/ | 除 |
4. 其它運算符
運算符 | 說明 |
---|---|
IS NULL | 是空值 |
BETWEEN AND | 介於二者之間 |
IN | 在一列值中間 |
:= | 賦值運算符 |
=> | 關係號 |
.. | 範圍運算符 |
|| | 字符鏈接符 |
5、數據類型
前面已經介紹過Oracle中的基本數據類型,除了這些基本數據類型外,Oracle中還有其它的數據類型,咱們一一來分析。
1. BOOLEAN
該數據用於定義布爾變量,其變量的值爲TRUE、FALSE或NULL。注意此類型只能在PL/SQL中使用,表列是沒有此類型的。
2. %TYPE
一般用於指定表的某個列的數據類型,能夠理解爲「的類型」(小技巧:%讀「的」)。
示例:
emp_id employee.id%TYPE;
使用%TYPE特性的優勢在於:
3. %ROWTYPE
%ROWTYPE操做符,返回一個記錄類型,其數據類型和數據庫表的數據結構相一致。
示例:
rec employee%ROWTYPE;
使用%ROWTYPE特性的優勢在於:
4. 複合數據類型
4.1. 記錄(Record)
記錄類型相似於C語言中的結構數據類型,它把分離的、邏輯相關的、基本數據類型的變量組成一個總體存儲起來,它必須包括至少一個標量型或RECORD數據類型的成員,稱做PL/SQL RECORD的域(FIELD),其做用是存放互不相同但邏輯相關的信息。
語法:
TYPE record_name IS RECORD( varable1 data_type1 [NOT NULL] [:= default_value ], varable2 data_type2 [NOT NULL] [:= default_value ], ......, varablen data_typen [NOT NULL] [:= default_value ] );
在使用記錄數據類型變量時,須要先在聲明部分先定義記錄的組成、記錄的變量,而後在執行部分引用該記錄變量自己或其中的成員。
示例1:
DECLARE
-- 定義記錄類型
TYPE TEST_REC IS RECORD( rec_name VARCHAR2(30) NOT NULL := '匿名', info VARCHAR2(100) ); -- 聲明記錄變量 rec_emp TEST_REC; BEGIN rec_emp.rec_name :='劉強東'; rec_emp.info :='談京東的業務發展'; DBMS_OUTPUT.PUT_LINE(rec_emp.rec_name||' ' ||rec_emp.info); END;
說明:咱們可使用DBMS_OUTPUT.PUT_LINE(outdata)
或DBMS_OUTPUT.PUT(outdata)
將處理結果輸出到屏幕上。
運行結果:
劉強東 談京東的業務發展
示例2(示例中所用到的表及數據見文末):
DECLARE
--定義與employee表中的幾個列相同的記錄數據類型
TYPE RECORD_TYPE_EMPLOYEES IS RECORD( e_id employee.id%TYPE, e_name employee.name%TYPE, e_birth employee.birthday%TYPE, e_address employee.address%TYPE, e_did employee.did%TYPE ); --聲明一個該記錄數據類型的記錄變量 emp_record RECORD_TYPE_EMPLOYEES; BEGIN SELECT id, name, birthday, address, did INTO emp_record FROM employee WHERE id = &emp_id; DBMS_OUTPUT.PUT_LINE('僱員名稱:'||emp_record.e_name ||' 出生日期:'||emp_record.e_birth ||' 地址:'||emp_record.e_address); END;
說明:能夠用SELECT語句對記錄變量進行賦值,只要保證記錄字段與查詢結果列表中的字段相配便可。&emp_id
表示接收用戶的輸入。
緊跟着&符號後面的變量被稱爲替換變量。替換變量對數據庫引擎是「不可見的」。其實PL/SQL會用用戶輸入的文本內容來替換變量引用。
若是你想在代碼的不一樣地方引用相同的替換變量,那就須要在第一個替換變量前面放兩個&符號,這樣纔會爲你保留這個值以便後續使用。
輸入2,輸出結果:
僱員名稱:劉蘭 出生日期:03-9月 -85 地址:四川成都
4.2. 表(TABLE)
4.2.1. 索引表
索引表也稱爲PL/SQL表,它是Oracle早期版本用於處理PL/SQL數組的數據類型。索引表的元素個數沒有限制,而且下標能夠爲負值。
它與記錄類型類似,但它是對記錄類型的擴展。它能夠處理多行記錄,使得能夠在PL/SQL中模仿數據庫中的表。
注意,索引表只能做爲PL/SQL複合數據類型使用,而不能做爲表列的數據類型使用。
語法結構:
TYPE table_name IS TABLE OF element_type [NOT NULL] INDEX BY [BINARY_INTEGER | PLS_INTEGER | VARCHAR2];
關鍵字INDEX BY表示建立一個主鍵索引,以便引用記錄表變量中的特定行。
表是集合類型,集合類型經常使用方法有:
方法 | 說明 |
---|---|
EXISTS(n) | 若是集合的第n個成員存在,則返回true |
COUNT | 返回已經分配了存儲空間即賦值了的成員數量 |
FIRST | 返回成員的最低下標值 |
LAST | 返回成員的最高下標值 |
PRIOR(n) | 返回下標爲n的成員的前一個成員的下標。若是沒有則返回NULL |
NEXT(N) | 返回下標爲n的成員的後一個成員的下標。若是沒有則返回NULL |
TRIM | TRIM:刪除末尾一個成員。 TRIM(n) :刪除末尾n個成員 |
DELETE | DELETE:刪除全部成員。 DELETE(n) :刪除第n個成員。DELETE(m, n) :刪除從n到m的成員。 |
EXTEND | EXTEND:添加一個null成員。 EXTEND(n):添加n個null成員。 EXTEND(n,i):添加n個成員,其值與第i個成員相同。 |
LIMIT | 返回在varray類型變量中出現的最高下標值 |
集合方法調用語法爲:
collection_name.method_name[(parameters)]
示例1:
DECLARE
/* 定義索引表類型 */ TYPE name_index IS TABLE OF employee.name%type INDEX BY binary_integer; TYPE charindex is table of employee.name%type index by varchar2(10); /* 聲明變量 */ names name_index; names2 charindex; BEGIN names(1) := 'love'; names(2) := 'lily'; names2('girl') := 'Lucy'; names2('boy') := 'Tom'; dbms_output.put_line(names(1)); dbms_output.put_line(names(2)); dbms_output.put_line(names2('girl')); dbms_output.put_line(names2('boy')); END;
輸出結果:
love lily Lucy Tom
示例2:
DECLARE
/* 定義索引表類型 */ TYPE name_index IS TABLE OF employee.name%type INDEX BY binary_integer; TYPE charindex is table of employee.name%type index by varchar2(10); /* 聲明變量 */ names name_index; names2 charindex; BEGIN SELECT name INTO names(1) FROM employee WHERE id=3; SELECT empname INTO names2('name') FROM employee WHERE id=5; dbms_output.put_line(names(1)); dbms_output.put_line(names2('name')); END;
輸出結果:
張強 向小梅
示例3:
DECLARE
TYPE DEPT_TABLE_TYPE IS TABLE OF DEPT%ROWTYPE INDEX BY BINARY_INTEGER; dept_table DEPT_TABLE_TYPE; cnt number(2) :=4; BEGIN FOR i IN 1 .. cnt LOOP SELECT * INTO dept_table(i) FROM DEPT WHERE id=i; END LOOP; FOR i IN 1 .. cnt LOOP DBMS_OUTPUT.PUT_LINE('Department id: '||dept_table(i).id); DBMS_OUTPUT.PUT_LINE('Department name: '|| dept_table(i).name); END LOOP; END;
輸出結果:
Department id: 1 Department name: 財務部 Department id: 2 Department name: 市場部 Department id: 3 Department name: 綜合部 Department id: 4 Department name: 研發部
4.2.2 嵌套表
嵌套表的元素下標從1開始,而且元素個數沒有限制。嵌套表數組元素值能夠是稀疏的。
注意:索引表類型不能做爲表列的數據類型使用,但嵌套表類型能夠做爲表列的數據類型。
語法結構:
TYPE type_name IS TABLE OF element_type;
示例1:
DECLARE
TYPE EMP_TABLE_TYPE IS TABLE OF employee.name%TYPE; emp_table EMP_TABLE_TYPE; BEGIN emp_table := EMP_TABLE_TYPE(' ',' ',' ');--這裏必須使用構造方法初始化嵌套表變量。 SELECT name INTO emp_table(2) FROM employee WHERE id=&emp_id; DBMS_OUTPUT.PUT_LINE('姓名:'||emp_table(2)); END;
輸入2,輸出結果:
姓名:劉蘭
在表列中也可使用嵌套表。
在表列中使用嵌套表類型,必須首先使用CREATE TYPE命令創建嵌套表類型。另外注意,必需要爲嵌套表列指定專門的存儲表。
示例2:
CREATE TYPE phone_type IS TABLE OF varchar2(20); CREATE TABLE employee( id number(4), name varchar2(10), sal number(6,2), phone phone_type )nested table phone store as phone_table; -- 在嵌套表中插入數據 BEGIN INSERT INTO employee VALUES(1, 'TOM', 800, phone_type('028-90909800', '13913001300')); END; -- 在嵌套表中檢索數據 DECLARE phone_table phone_type; BEGIN SELECT phone INTO phone_table FROM employee WHERE id=1; FOR i IN 1..phone_table.COUNT LOOP dbms_output.put_line('電話號碼:'||phone_table(i)); END LOOP; END; -- 在嵌套表中更新數據 DECLARE phone_table phone_type:=phone_type('028-10001000', '139800900100'); BEGIN UPDATE employee SET phone=phone_table WHERE id=1; END;
4.3. 數組(VARRAY)
數組是具備相同數據類型的一組成員的集合。每一個成員都有一個惟一的下標,它取決於成員在數組中的位置。
語法結構:
TYPE varray_name IS VARRAY(size) OF element_type [NOT NULL];
示例:
DECLARE
--定義一個最多保存5個VARCHAR(25)數據類型成員的VARRAY數據類型 TYPE ARRAY_TYPE IS VARRAY(5) OF VARCHAR(25); --聲明一個該VARRAY數據類型的變量 my_array ARRAY_TYPE; BEGIN --用構造函數語法賦予初值 my_array := ARRAY_TYPE ('中國', '美國', '英國', '日本', NULL); DBMS_OUTPUT.PUT_LINE('地區名稱:'||my_array(1)||'、' ||my_array(2)||'、' ||my_array(3)||'、' ||my_array(4)); DBMS_OUTPUT.PUT_LINE('賦予初值NULL的第5個成員的值:'||my_array(5)); --也能夠這樣對成員賦值 my_array(5) := '法國'; DBMS_OUTPUT.PUT_LINE('第5個成員的值:'||my_array(5)); END;
輸出結果:
地區名稱:中國、美國、英國、日本
賦予初值NULL的第5個成員的值: 第5個成員的值:法國
5. 綁定變量
綁定變量是在主機環境中定義的變量。在PL/SQL 程序中可使用綁定變量做爲他們將要使用的其它變量。爲了在PL/SQL 環境中聲明綁定變量,使用命令VAR或VARIABLE。
當在SQL*Plus中與PL/SQL塊之間進行數據交互時,須要使用SQL*Plus綁定變量來完成。
當在PL/SQL中引用非PL/SQL變量時,必需要在非PL/SQL變量前加冒號(「:」)。
示例:
VARIABLE name varchar2(10);
/
BEGIN SELECT name INTO :name FROM employee WHERE id = 1; end; / print name;
輸出結果:
name --------- 李飛
6、經常使用類型轉換函數
CHAR 轉換爲 NUMBER:
使用 TO_NUMBER 函數來完成字符到數字的轉換,如:
v_total := TO_NUMBER('100.0') + 25.5;
NUMBER 轉換爲CHAR:
使用 TO_CHAR 函數能夠實現數字到字符的轉換,如:
v_comm := TO_CHAR('12.34') || '元' ;
字符轉換爲日期:
使用 TO_DATE 函數能夠實現 字符到日期的轉換,如:
v_date := TO_DATE('2015.06.11','yyyy.mm.dd');
日期轉換爲字符:
使用 TO_CHAR 函數能夠實現日期到字符的轉換,如:
v_to_day := TO_CHAR(SYSDATE, 'yyyy.mm.dd hh24:mi:ss') ;
7、RETURNNING的使用
示例1:
DECLARE
row_id ROWID;
info VARCHAR2(40);
BEGIN INSERT INTO dept VALUES (10, '外交部') RETURNING rowid, name||':'||to_char(id) INTO row_id, info; DBMS_OUTPUT.PUT_LINE('ROWID:'||row_id); DBMS_OUTPUT.PUT_LINE(info); END;
說明:
數據類型ROWID用於存放數據的行號。
RETURNING子句做用:用於檢索INSERT語句中所影響的數據行數,當INSERT語句使用VALUES子句插入數據時,RETURNING 字句還可將列表達式、ROWID和REF值返回到輸出變量中。使用RETURNING子句是應注意如下幾點限制:
示例2:
DECLARE
row_id ROWID;
info VARCHAR2(40);
BEGIN UPDATE dept SET id=20 WHERE name='外交部' RETURNING rowid, name||':'||to_char(id) INTO row_id, info; DBMS_OUTPUT.PUT_LINE('ROWID:'||row_id); DBMS_OUTPUT.PUT_LINE(info); END;
說明:
RETURNING子句用於檢索被修改行的信息。當UPDATE語句修改單行數據時,RETURNING子句能夠檢索被修改行的ROWID和REF值,以及行中被修改列的列表達式,並可將他們存儲到PL/SQL變量或複合變量中;當UPDATE語句修改多行數據時,RETURNING子句能夠將被修改行的ROWID和REF值,以及列表達式值返回到複合變量數組中。在UPDATE中使用RETURNING 子句的限制與INSERT語句中對RETURNING子句的限制相同。
示例3:
DECLARE
row_id ROWID;
info VARCHAR2(40);
BEGIN DELETE dept WHERE id=20 RETURNING rowid, name||':'||to_char(id) INTO row_id, info; DBMS_OUTPUT.PUT_LINE('ROWID:'||row_id); DBMS_OUTPUT.PUT_LINE(info); END;
說明:
RETURNING子句用於檢索被刪除行的信息:當DELETE語句刪除單行數據時,RETURNING子句能夠檢索被刪除行的ROWID和REF值,以及被刪除列的列表達式,並可將他們存儲到PL/SQL變量或複合變量中;當DELETE語句刪除多行數據時,RETURNING子句能夠將被刪除行的ROWID和REF值,以及列表達式值返回到複合變量數組中。在DELETE中使用RETURNING子句的限制與INSERT語句中對RETURNING子句的限制相同。
8、註釋
在PL/SQL裏,有兩種註釋:
示例:
DECLARE
--定義v_sal變量 v_sal NUMBER(6,2); BEGIN /* 給變量賦值, 而後打印此變量 */ v_sal := 1000; dbms_output.put_line(v_sal); END;
各示例中所涉及的表及測試數據
-- 建立表 create table DEPT -- 部門 ( id NUMBER(4) not null constraint PK_DEPT_ID primary key, name VARCHAR2(20) ); create table EMPLOYEE -- 員工 ( id NUMBER(4) not null constraint PK_EMP_ID primary key, name VARCHAR2(20) not null, birthday DATE, address VARCHAR2(100), did NUMBER(4), constraint FK_EMP_DEPT foreign key (DID) references DEPT (ID) ); -- 添加測試數據 INSERT INTO DEPT VALUES(1, '財務部'); INSERT INTO DEPT VALUES(2, '市場部'); INSERT INTO DEPT VALUES(3, '綜合部'); INSERT INTO DEPT VALUES(4, '研發部'); INSERT INTO DEPT VALUES(5, '網絡部'); INSERT INTO EMPLOYEE VALUES(1, '李飛', TO_DATE('1975.07.03','yyyy.mm.dd'), '四川成都', 1); INSERT INTO EMPLOYEE VALUES(2, '劉蘭', TO_DATE('1985.09.03','yyyy.mm.dd'), '四川成都', 1); INSERT INTO EMPLOYEE VALUES(3, '張強', TO_DATE('1987.11.22','yyyy.mm.dd'), '廣東廣州', 2); INSERT INTO EMPLOYEE VALUES(4, '劉武龍', TO_DATE('1979.07.18','yyyy.mm.dd'), '陝西西安', 2); INSERT INTO EMPLOYEE VALUES(5, '向小梅', TO_DATE('1982.03.03','yyyy.mm.dd'), '四川成都', 2); INSERT INTO EMPLOYEE VALUES(6, '周斌', TO_DATE('1985.11.08','yyyy.mm.dd'), '四川成都', 4); INSERT INTO EMPLOYEE VALUES(7, '王強', TO_DATE('1985.01.25','yyyy.mm.dd'), '四川成都', 4);