Oracle數據庫之PL/SQL程序基礎設計

1、PL/SQL塊結構php

前邊咱們已經介紹了PL/SQL塊的結構,再來回顧一下:css

DECLARE
/* * 聲明部分——定義常量、變量、複雜數據類型、遊標、用戶自定義異常 */ BEGIN /* * 執行部分——PL/SQL語句和SQL語句 */ EXCEPTION /* * 異常處理部分——處理運行異常 */ END; /*塊結束標記 */

要實現PL/SQL程序設計,先介紹以下的基本內容:sql

2、標識符數據庫

PL/SQL程序設計中的標識符定義與SQL的標識符定義的要求相同:express

  • 標識符名第一個字符必須爲字母
  • 標識符名不分大小寫
  • 標識符名不能超過30字符
  • 不能用‘-’(減號)
  • 不能是SQL保留字

注意: 通常不要把變量名聲明與表中字段名徹底同樣,若是這樣可能獲得不正確的結果。編程

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的變量做用範圍特色是:

  • 變量的做用範圍是在你所引用的程序單元(塊、子程序、包)內。即從聲明變量開始到該塊的結束。
  • 一個變量(標識)只能在你所引用的塊內是可見的。
  • 當一個變量超出了做用範圍,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特性的優勢在於:

  • 所引用的數據庫列的數據類型能夠沒必要知道。
  • 所引用的數據庫列的數據類型能夠實時改變,容易保持一致,也不用修改PL/SQL程序。

3. %ROWTYPE

%ROWTYPE操做符,返回一個記錄類型,其數據類型和數據庫表的數據結構相一致。

示例:

rec employee%ROWTYPE;

使用%ROWTYPE特性的優勢在於:

  • 所引用的數據庫中列的個數和數據類型能夠沒必要知道。
  • 所引用的數據庫中列的個數和數據類型能夠實時改變,容易保持一致,也不用修改PL/SQL程序。

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子句是應注意如下幾點限制:

  • 不能與DML語句和遠程對象一塊兒使用;
  • 不能檢索LONG類型信息;
  • 當經過視圖向基表中插入數據時,只能與單基表視圖一塊兒使用。

示例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);
相關文章
相關標籤/搜索