1. 程式人生 > 實用技巧 >PL/SQL

PL/SQL

PL/SQL:是一種過程化的語言,它與C、 C++、Java等語言一樣專注於處理細節,可以用來實現比較複雜的業務邏輯。它允許SQL的資料操作語言(MDL)和查詢語句包含在塊結構和程式碼過程語言中,使用PL/SQL成為一個功能強大的事務處理語句。

PL/SQL的語法結構:
(1)定義部分:定義常量、變數、遊標、複雜資料型別
(2)執行部分:包括要執行的PL/SQL語句和SQL語句
(3)異常部分:用於處理執行部分可能出現的錯誤

declare(可選)
begin(必選)
exception(可選)
end結束標誌

示例1:只包含執行部分的PL/SQL塊(輸出語句“Hello Word”)

1
BEGIN 2 3 DBMS_OUTPUT.PUT_LINE('HELLO');--要執行的SQL語句和PL/SQL塊 4 5 END;

示例2:只包含定義和執行部分的PL/SQL塊

1 DECLARE
2 V_Name VARCHA(12);
3 BEGIN
4 SELECT STUNAME INTO V_Name FROM STUDENTINFO WHERE STUID = &ID;
5 DBMS_OUTPUT.PUT_LINE('管理:' || V_Name);
6 END;

示例3:包含異常處理部分的PL/SQL塊

 1 DECLARE
 2 
 3 V_Name VARCHAR(12
); 4 5 BEGIN 6 7 SELECT STUNAME INTO V_Name FROM SYUDENTINFO WHERE STUID = &ID; 8 9 DBMS_OUTPUT.PUT_LINE('管理:' || V_Name); 10 11 EXCEPTION 12 13 WHEN NO_DATA_FOUND THEN 14 15 DBMS_OUTPUT.PUT_LINE('請輸入正確的ID'); 16 17 END;

函式(FUNCTION)

基本語法如下:

 1 CREATE [OR REPLACE] FUNCTION 函式名 (引數名 引數型別)
2 3 RETURN 返回型別 4 5 IS 6 7 變數名 變數型別 8 9 BEGIN 10 11 函式處理區: 12 13 RETURN 返回的函式變數 14 15 [EXCEPTION WHEN OTHERS 16 17 THEN 18 19 異常處理邏輯;] 20 21 END;

示例1:

1 CREATE OR REPLACE FUNCTION STU (Name VARCHAR)
2 RETUEN NUMBER
3 IS
4 V_Name NUMBER;
5 BEGIN
6 SELECT SUM(STUID) INTO V_Name FROM STUDENTINFO;
7 RETURN V_Name;
8 END;

儲存過程(PROCEDURE)

基本語法如下:

 1 CREATE OR REPLACE PROCEDURE 儲存過程名
 2 (
引數名 IN 引數型別,
3 引數名 OUT 引數型別 4 ) 5 IS 6 變數名 變數型別; 7 BEGIN 8 儲存過程處理區: 9 EXCEPTION WHEN OTHERS 10 THEN 11 異常處理邏輯; 12 END 儲存過程名

例子:

 1 CREATE OR REPLACE PROCEDURE Update_Student
 2 (
 3 
 4  V_StuName VARCHAR2,
 5  V_Id VARCHAR2
 6 )
 7 IS
 8 BEGIN
 9 UPDATE STUDENTINFO SET STUNAME = V_StuName WHERE STUID = V_Id
10 END;
11 
12  
13 
14 使用儲存過程
15 EXEC Update_Student('1'.'08')

包(PACKAGE)
包的理解:
包:用於邏輯組合相關的過程和函式
包規範:定義公式用的常量,變數,過程,函式
包體:用於實現包規範中的過程和函式

包的結構:(用於函式和儲存過程的處理)如下

 1 CREATE OR REPLACE PACKAGE 包名
 2 FUNCTION 函式名(引數名 引數型別)
 3 RETURN 返回型別;
 4 IS
 5 變數名 變數型別
 6 BEGIN
 7 函式處理部分;
 8 RETURN 返回資料變數;
 9 EXCEPTION WHEN OTHERS
10 THEN
11 異常處理部分;
12 END;

觸發器(TRIGGER)
觸發器是指被隱藏執行的PL/SQL語句,語法結構如下:

CREATE [OR REPLACE] TRIGGER 觸發事件 觸發事件
ON 表名/檢視名
[FOR EACH ROW]  //加上FOR EACH ROW即為行級觸發器,不加時為語句級觸發器
BEGIN
處理語句
END;


CREATE [OR REPLACE] TRIGGER tigger name
{BEFORE|AFTER|INSERT OF}
{DELETE [OR INSERT] [OR UPDATE] [OF COLUMN,...N]}
ON
TABLE NAME | VIEW NAME
[FOR EACH ROW [WHEN(CONITION)]]
BEGIN
執行過程
  [EXCEPTION WHEN OTHERS
THEN
異常處理邏輯:]
END;

例子:

CREATE OR REPLACE TRIGGER TR_Ttu
BEFORE INSERT OR UPDATE
  ON STUDENTINFO
  FOR EACH ROW
  BEGIN
  IF UPDATEING THEN
  :NEW.BIRTHDAY := SYSDATE;
  ELSE IF INSERTING THEN
  :NEW.BIRTHDAY := SYSDATE;
  :NEW.BIRTHDAY := SYSDATE;
  END IF;
  END;

遊標

遊標是用來處理資料庫中檢索的多行記錄(使用SELECT語句)。利用遊標,程式可以逐個的處理和遍歷一次檢索返回的整個記錄集。
遊標分類:
靜態遊標:在編譯時就知道其SELECT語句的遊標。靜態遊標又可以分為兩種型別:隱式遊標和顯示遊標。
動態遊標:使用者為遊標使用的查詢知道進行的時候才能確定,可以使用REF遊標和遊標變數滿足這個要求。為了使用申明遊標變數,必須申明遊標變數
REF有兩種型別:強制型REF遊標和弱型別REF遊標

顯示遊標:
顯示遊標被用於處理返回多行資料的SELECT語句,遊標名通過CURSOR...IS語句顯示地賦值給SELECT語句
使用步驟:
1,宣告遊標:CURSOR cursor name IS select statement
2,為查詢開啟遊標:OPEN cursor name
3,獲取結果放入PL/SQL變數中:
FETCH cursor name INTO list of variable;
FETCH cursor name INTO PL/SQL record;
4,關閉遊標:COLSE cursor name

例子:

 1 DECLARE
 2     V_Name STUDENTINFO.STUNAME%TYPE;
 3     V_SCORE STUDENTINFO.STUSCORE%TYPE;
 4 CURSOR cus_Student
 5 IS
 6 SELECT STUNAME, STUSCORE FROM STUDENTINFO;
 7 BEGIN
 8 OPEN cus_Student;
 9 LOOP
10 FETCH cus_Student INTO V_Name, V_SCORE;
11 EXIT WHEN cus_Student%NOTFOUND;
12 DBMS_OUTPUT.PUT_LINE(''|| cus_Student%ROWCOUNT || '個使用者 姓名:'|| V_Name || '分數:'|| V_SCORE);
13 END LOOP;
14 CLOSE cus_Student;
15 END;

顯示遊標屬性:
%FOUND:只有在DML語句影響一行或者多行,則返回TRUE
%NOTFOUND:沒有影響任何行,則返回TRUE
%ROWCOUNT:返回DML語句影響的行數,沒有則返回0
%ISOPEN:返回遊標是否開啟,在執行SQL之後,Oracle自定關閉SQL遊標

例子:

1 DECLARE
2 CURSOR cus_Student --宣告遊標
3 IS
4 SELECT STUNAME, STUSCORE FROM STUDENTINFO;
5 BEGIN
6 FOR record_Student IN cus_Student
7 LOOP
8 DBMS_OUTPUT.PUT_LINE(''|| cus_Student%ROWCOUNT || '個使用者 姓名:'|| V_Name || '分數:'|| V_SCORE);
9 END;

隱式遊標

 1 DECLARE
 2     row_Student STUDENTINFO%ROWTYPE;
 3 BEGIN
 4     SELECT STUNAME,STUSCORE INTO row_Student. STUNAME, row_Student. STUSCORE FROM STUDENTINFO WHERE STUDENTINFO.STUID = '1';
 5     IF(SQL%ROWCOUNT = 1) THEN
 6     DBMS_OUTPUT.PUT_LINE('找到了');
 7     END IF;
 8     IF(SQL%FOUND) THEN
 9     DBMS_OUTPUT.PUT_LINE('找到了');
10     END IF;
11 DBMS_OUTPUT.PUT_LINE(' STUNAME '|| row_Student. STUNAME || ' STUSCORE '|| row_Student. STUSCORE);
12 END;

動態遊標使用步驟:
1,宣告動態遊標型別
2,開啟遊標,指定遊標查詢
3,提取遊標
4,關閉遊標
強型別遊標,使用return宣告的遊標為強型別遊標。在對遊標進行繫結查詢只能繫結遊標返回的型別ROWTYPE

 1 --強型別的動態遊標,查詢表中的數
 2 DECLARE
 3     TYPE ref_Cur IS REF CURSOR  --宣告遊標型別
 4     RETUEN STUDENTINFO%ROWTYPE;  --帶返回值的為強型別動態遊標
 5     refCur_Stu ref_Cur;  --遊標型別物件
 6     v_Stu STUDENTINFO%ROWTYPE;
 7 BEGIN
 8     OPEN refCur_Stu FOR  --將遊標繫結到一個查詢語句,因為宣告的是強型別,所以只能繫結STUDENTINFO
 9     SELECT * FROM STUDENTINFO;
10     LOOP
11     FETCH refCur_Stu INTO V_Stu;  --提取遊標內容
12     EXIT WHEN refCur_Stu%NOTFOUND;
13     DBMS_OUTPUT.PUT_LINE(refCur_Stu%ROWCOUNT|| ' STUNAME:' || V_Stu. STUNAME || '  STUSCORE :' V_Stu. STUSCORE);
14     END LOOP;
15     CLOSE refCur_Stu;