Oracle之PL/SQL學習筆記


  自己在學習Oracle是做的筆記及實驗代碼記錄,內容挺全的,也挺詳細,發篇博文分享給需要的朋友,共有1w多字的學習筆記吧。是以前做的,一直在壓箱底,今天拿出來整理了一下,給大家分享,有不足之處還望大家批評指正。

 

  PL/SQL定義:PL/SQL是由Oracle開發,專門用於Oracle的程序設計語言。 PL---Procedural Language. SQLStructure 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語句:  

    1.  i.      IF THEN END IF
    2.  ii.      IF THEN ELSE END IF
    3.  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;

 

 

記錄的另一種定義:表名%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;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM