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”)
1BEGIN 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;