自己在學習Oracle是做的筆記及實驗代碼記錄,內容挺全的,也挺詳細,發篇博文分享給需要的朋友,共有1w多字的學習筆記吧。是以前做的,一直在壓箱底,今天拿出來整理了一下,給大家分享,有不足之處還望大家批評指正。
PL/SQL定義:PL/SQL是由Oracle開發,專門用於Oracle的程序設計語言。 PL---Procedural Language. SQL—Structure QueryLanguage。PL/SQL包括過程化語句和SQL語句
PL/SQL的單位:塊。 一個塊中可以嵌套子塊。
塊的三個組成部分:
一:定義部分(declare)
PL/SQL中使用的變量,常量,游標和異常的名字都必須先定義后使用。並且定義在以declare關鍵字開頭的定義部分
二:可執行部分:(begin)
是PL/SQL的主題,包含該塊的可執行語句,該部分定義了塊的功能,是必須的部分。由關鍵字begin開始,end結束
三:異常處理部分:(exception)
該部分以exception開始,以end結束
Demo: DECLARE –可選 變量,常量,游標,用戶自定義的特殊類型 BEGIN –必須 --SQL語句 --PL/SQL語句 EXCEPTION –可選 --異常處理部分 END; --必須 即由聲明,執行,異常組成
DEMO: DECLARE V_value1 VARCHAE2(5); BEGIN SELECT cn_name INTO v_value1 FROM table_name; EXCEPTION WHEN exception_name THEN --處理程序…… END;
PL/SQL的優點:
1、 改善了性能:PL/SQL把整個語句塊發送給服務器,這個過程在單次調用中完成,降低了網絡擁擠
2、 可重用性:只要有Oracle的地方都能運行
3、 模塊化:程序中的每一塊都實現一個邏輯操作,有效的進行了分割。
PL/SQL塊的類:
1、 匿名塊:只能存儲一次,不能存儲在數據庫中
2、 過程,函數和包(procedure,function,package):是命了名的PL/SQL塊,被存儲在數據庫中,可以被多次使用,可以用外部程序顯示執行。
3、 觸發器:是命名的PL/SQL塊,被存儲在數據庫中,當觸發某事件時自動執行。
PL/SQL中變量的命名規范:
1、 至多有30個字符
2、 不能是保留字
3、 必須以字母開頭
4、 不允許和數據庫中表的列名相同
5、 不可包括$,_和數字以外的字符
PL/SQL中的變量
1、 PL/SQL變量
a) 標量型:只能存放單一值
b) 復合型
c) 引用型
d) LOBx型:存放大數據
2、 定義變量語法
a) 變量名 變量類型 := 變量值
b) V_number NUMBER(2) NOT NULL :=20;
c) 常量的定義
i. V_number CONSTANT
NUMBER(2,3) :=20.098;
1 DEMO:查詢員工號為7369的員工,把其job存入v_job中並輸出 2 DECLARE 3 --定義存儲job的變量v_job為引用變量與--emp.job的類型相同,用%TYPE實現 4 v_job emp.job%TYPE; 5 --定義員工號變量並賦初值(:=) 6 n_empno emp.empno%TYPE:=7369; 7 BEGIN 8 --查詢語句 9 SELECT emp.job 10 --把查出來的結果賦給v_job 11 INTO v_job 12 FROM emp 13 WHERE emp.empno = n_empno; 14 --打印輸出結果 15 Dbms_Output.put_line(v_job); 16 END;
%TYPE屬性:
通過%TYPE聲明一個變量,實際上就是參照變量或表中的字段的類型作為變量的類型,並且保持同步。
變量將遵循下面的類型聲明:
1. 已聲明過的變量類型
2. 數據庫中表字段的類型
demo1:
創建一個匿名塊,輸出hello world
1 --創建一個匿名塊,輸出hello world 2 DECLARE 3 v_hello varchar2(20) :='Hello World'; 4 BEGIN 5 Dbms_Output.put_line(v_hello); 6 END; 7 8 --創建一個匿名塊,查詢emp表,顯示雇員名是’SCOTT‘的薪水,通過DBMS_OUTPUT包來顯示。 9 DECLARE 10 v_sal emp.sal%TYPE; 11 v_name emp.ename%TYPE := 'SCOTT'; 12 BEGIN 13 SELECT emp.sal 14 INTO v_sal 15 FROM emp 16 WHERE emp.ename = v_name; 17 dbms_output.put_line(v_sal); 18 END;
demo2:
-從部門表中找到最大的部門號,將其輸出到屏幕
1 --從部門表中找到最大的部門號,將其輸出到屏幕 2 DECLARE 3 v_deptno dept.deptno%TYPE; 4 BEGIN 5 SELECT MAX(dept.deptno) 6 INTO v_deptno 7 FROM dept; 8 dbms_output.put_line(v_deptno); 9 END;
demo3:
--PL/SQL嵌套和變量的作用域
--PL/SQL嵌套和變量的作用域 DECLARE v_parent NUMBER :=10; BEGIN DECLARE v_child NUMBER :=20; BEGIN dbms_output.put_line('chile='||v_child); dbms_output.put_line('parent='||v_parent); END; --dbms_output.put_line('chile='||v_child); --注意變量的作用域 dbms_output.put_line('chile='||v_parent); END; 結果: chile=20 parent=10 chile=10
demo4:
--選擇並打印emp表中薪水總和
1 --選擇並打印emp表中薪水總和 2 DECLARE 3 v_sal emp.sal%TYPE; 4 BEGIN 5 SELECT sum(emp.sal) 6 INTO v_sal 7 FROM emp; 8 dbms_output.put_line(v_sal); 9 END
demo5:事務的操作
1 DECLARE 2 v_sal emp.sal%TYPE :=800; 3 BEGIN 4 UPDATE emp 5 SET emp.sal = emp.sal+ v_sal 6 WHERE emp.job='ANALYST'; 7 SAVEPOINT a; 8 UPDATE emp 9 SET emp.sal = emp.sal+ v_sal 10 WHERE emp.job='ANALYST'; 11 SAVEPOINT b; 12 ROLLBACK TO SAVEPOINT a; 13 COMMIT; 14 END;
編寫控制結構
1、 條件分支語句
a) IF語句:
-
- i. – IF – THEN – END IF
- ii. – IF – THEN – ELSE – END IF
- iii. – IF – THEN – ELSEIF – END IF
2、 條件語句語法
a) IF condition THEN
i. Statement;
b) [ELSIF condition THEN
i. Statement;]
c) [ELSE
i. Statement;]
d) ENDIF;
3、 DEMO:
a) IF v_name = ‘SCOTT’ AND SAL >= 3000 THEN
i. v_dept :=20;
b) END IF;
1 DEMO: 2 --null的處理 3 DECLARE 4 v_x NUMBER :=NULL; 5 v_y NUMBER := NULL; 6 BEGIN 7 IF v_x = v_y THEN 8 dbms_output.put_line('NULL等於NULL'); 9 ELSE 10 dbms_output.put_line('NULL不等於NULL'); 11 END IF; 12 END; 13 結果:NULL不等於NULL 空是未知的東西
4.Case語句:語法(有返回值的)
1 CASE demo: 2 DECLARE 3 v_sal emp.sal%TYPE; 4 v_dept emp.deptno%TYPE; 5 v_result VARCHAR(20); 6 BEGIN 7 SELECT emp.deptno 8 INTO v_dept 9 FROM emp 10 WHERE emp.sal = 11 ( 12 SELECT MAX(emp.sal) 13 FROM emp 14 ); 15 dbms_output.put_line(v_dept); 16 v_result := 17 CASE v_dept 18 WHEN 10 THEN '部門一' 19 WHEN 20 THEN '部門二' 20 ELSE '部門三' 21 END; 22 dbms_output.put_line(v_result); 23 END; 24 輸出結果: 25 10 26 部門一
5、 循環語句LOOP :
DEMO:循環插入11條數據
1 DECLARE 2 v_count NUMBER := 0; 3 BEGIN 4 LOOP 5 --插入數據 6 INSERT INTO 7 test(name,id,password) 8 VALUES ('TEST'||v_count,v_count,'admin'); 9 --變量加一 10 v_count := v_count+1; 11 --判斷退出條件 12 EXIT WHEN v_count > 10; 13 END LOOP; 14 END;
b) FOR LOOP循環
1 DEMO: 2 DECLARE 3 v_counter NUMBER :=0; 4 BEGIN 5 --v_counter是自增的 6 FOR v_counter IN 0 .. 10 LOOP 7 DELETE FROM test 8 WHERE test.id = v_counter; 9 END LOOP; 10 END;
b) WHILE LOOP
1 DECLARE 2 v_count NUMBER := 0; 3 BEGIN 4 WHILE v_count<10 LOOP 5 --插入數據 6 INSERT INTO 7 test(name,id,password) 8 VALUES ('TEST'||v_count,v_count,'admin'); 9 --變量加一 10 v_count := v_count+1; 11 END LOOP; 12 END;
三:復合類型
1、 復合數據類型
a) 一個復合變量可以存放多個值
b) 復合變量創建后可以多次使用
c) 如同枚舉類型和數組
2、 PL/SQL記錄
a) 每個記錄內都有很多的不同類型的字段
b) 無初始值的字段為NULL
c) Record 類型聲明用戶自定義的類型
3、 定義一個記錄
a) 語法:
1 i. TYPE type_name IS RECORD( 2 ii. 字段名1 字段類型1, 3 iii. 字段名2 字段類型2 4 iv. );
b) DEMO
i. TYPE emp_record_name IS RECORD( ii. V_name varchar(20), iii. V_password varchar(10) iv. ); v. Emp_record emp_record_name;
--記錄的定義與使用 DECLARE TYPE test_record_name IS RECORD( v_name test.name%TYPE, v_id test.id%TYPE, v_password test.password%TYPE ); test_record test_record_name; BEGIN SELECT test.name,test.id,test.password INTO test_record FROM test WHERE test.name='TEST0'; dbms_output.put_line(test_record.v_name||test_record.v_id||test_record.v_password); END;
5 記錄的另一種定義:表名%ROWTYPE
a) Exp_row table_name%ROWTYPE
DEMO:
1 --記錄的定義與使用 2 DECLARE 3 emp_record emp%ROWTYPE; 4 5 BEGIN 6 SELECT * 7 INTO emp_record 8 FROM emp 9 WHERE emp.empno='7788'; 10 dbms_output.put_line(emp_record.empno||' '||emp_record.sal); 11 END;
編寫游標
1、 游標的定義:游標是Oracle在數據庫中開辟的一個工作區,用來存放SELECT語句查詢的結果。
2、 游標的分類
a) 隱式游標:PL/SQL隱式建立並管理這一游標。
b) 顯示游標:由程序員定義並控制,從數據庫中讀出多行數據,並從多行數據中一行一行的處理。
3、 游標的聲明:
a) 語法:CURSOR cursor_name IS select_statement;
b) 在游標聲明中SELECT語句不能使用INTO語句,可以在字句子中使用ORDER字句。
c) Demo:
1 CURSOR emp_cursor IS 2 SELECT * 3 FROM emp;
4、 打開游標
a) 語法:OPEN cursor_name;
b) 使用游標之前應打開游標
c) 打開游標實際上是執行定義游標時的SELECT語句,將查詢結果檢索到工作區中。
d) 如果沒有要返回的行沒有異常
5、 從游標中提取數值
a) 語法
i. FETCH cursor_name INTO [v1,v2……]|record_name]
b) 在使用FETCH時先把游標打開,不然沒法使用。
c) 對游標第一次使用FETCH時,游標指向的是第一條記錄,使用后游標指向下一條記錄。
d) 游標只能向下移動不能回退,如果想回退到上一條記錄,只有把游標關閉后在打開。
e) INTO字句中的變量個數、順序、數據類型必須和工作區中的保持一致;
6、 關閉游標
a) 語法:CLOSE cursor_name
b) 處理完數據后必須關閉游標,如果需要可以再次打開游標,游標一旦關閉不可再從游標中提取數據,當關閉游標后所有和游標相關的資源都會被關閉。
7.游標的使用Demo
1 --游標的使用 2 DECLARE 3 --定義臨時變量來存放游標中的內容 4 emp_empno emp.empno%TYPE; 5 emp_ename emp.ename%TYPE; 6 --定義名為emp_cursor的游標 7 CURSOR emp_cursor IS 8 SELECT emp.empno,emp.ename 9 FROM emp; 10 BEGIN 11 --打開游標 12 OPEN emp_cursor; 13 --循環輸出游標 14 FOR i IN 1..5 LOOP 15 --提取游標中的內容 16 FETCH emp_cursor 17 INTO emp_empno,emp_ename; 18 dbms_output.put_line(emp_empno||' '||emp_ename); 19 END LOOP; 20 --關閉游標 21 CLOSE emp_cursor; 22 END;