關於Oracle存儲過程相關講解

一:前言

目前由於mysql的開源,與幾年前的如ioe的一股浪潮,以及oracle的可拓展瓶頸問題,導致大的公司基本放棄使用oracle。取而代之的是一些基於mysql而改良後的雲數據庫環境,例如阿里雲的drds產品。但是對於業務量不是與日激增的服務,還是完全在使用oracle數據庫,畢竟單機oracle服務性能還是沒得說,已經它特有的一些統計函數等。今天主要講解下關於oracle的PL/SQL即Procedural Language/SQL 語言。

二:關於PL/SQL這一過程化編程語言主要分爲如下幾類便準編程結構:

  • 塊結構
  • 變量和類型
  • 條件邏輯
  • 循環
  • 遊標,保證查詢返回的結果
  • 過程
  • 函數
  • 包,可以用來將過程與函數組合到一個單元裏面

三:語法結構

1.基本結構示例

DECLARE --聲明部分
聲明語句
BEGIN --執行部分
執行語句
EXCEPTION --異常處理部分
執行語句
END;

2.變量聲明

1.定義普通變量
變量名 類型 [:= 初始值]
Eg: test_v number := 0;
2.引用數據庫表中某一個字段類型
變量名 數據庫表名.字段名 %type [:= 初始值]
eg: realName pl_user.real_name%type; --表示realName的類型和pl_user.real_name的類型相同
3.引用數據庫表中所有字段類型及字段名
變量名 數據庫表名 %rowtype;
Eg: testRow pl_user%rowtype; --表示 testRow包含了pl_user表中所有字段的名及類型,可以理解爲數組

3.常量聲明

變量名 CONSTANT 類型:=初始值;
示例: pi constant number(5,3):=3.14;

4.全局變量聲明

VARIABLE 變量名 類型;
示例: VARIABLE num number;

5.變量賦值

:= 賦給的值

6.使用全局變量

:<變量名>
示例:
:num:=100;
i=:num;

7.條件控制語句

IF <條件1> THEN
語句
[ELSIF <條件2> THEN
語句
ELSIF <條件n> THEN
語句]
[ELSE
語句]
END IF;

8.循環控制語句

1、 loop方式循環:
LOOP
語句;
EXIT WHEN <條件>
END LOOP;
2、 WHILE LOOP方式循環:
WHILE <條件>
LOOP
語句;
END LOOP;
3、 for循環方式:
FOR <循環變量> IN 下限…上限
LOOP
語句;
END LOOP;

9.NULL語句

null;
表示沒有操作;

10.註釋語法

單行註釋: –
多行註釋:/* …
…*/

11.異常處理

EXCEPTION
WHEN <異常類型> THEN
語句;
WHEN OTHERS THEN
語句;
END;

四:遊標

定義:

CURSOR <遊標名> IS <SELECT 語句> [FOR UPDATE | FOR UPDATE OF 字段];
[FOR UPDATE | FOR UPDATE OF 字段] --給遊標加鎖,既是在程序中有"UPDATE",“INSERT”,“DELETE"語句對數據庫操作時。
遊標自動給指定的表或者字段加鎖,防止同時有別的程序對指定的表或字段進行"UPDATE”,“INSERT”,“DELETE"操作.
在使用"DELETE”,“UPDATE"後還可以在程序中使用CURRENT OF <遊標名> 子句引用當前行
操作:OPEN <遊標名> --打開遊標
FETCH <遊標名> INTO 變量1,變量2,變量3,…變量n,;
或者
FETCH <遊標名> INTO 行對象; --取出遊標當前位置的值
CLOSE <遊標名> --關閉遊標
屬性: %NOTFOUND --如果FETCH語句失敗,則該屬性爲"TRUE”,否則爲"FALSE";
%FOUND --如果FETCH語句成果,則該屬性爲"TRUE",否則爲"FALSE";
%ROWCOUNT --返回遊標當前行的行數;
%ISOPEN --如果遊標是開的則返回"TRUE",否則爲"FALSE";
例子:

1:loop循環示例
declare
       cursor c_1 is select * from pl_user;     --定義遊標
       r c_1%rowtype;       --定義一個行對象,用於獲得遊標的值
begin
       if c_1%isopen then
          CLOSE c_1;
       end if;      --判斷遊標是否打開.如果開了將其關閉,然後在打開     
       open c_1;
       dbms_output.put_line('行號 字段一 字段二 字段三');
       loop
       fetch c_1 into r;--取值
       exit when c_1%notfound; --如果遊標沒有取到值,退出循環.
       dbms_output.put_line(c_1%rowcount ||' '|| r.id ||' '|| r.login_name ||' '|| r.real_name ||' '|| r.email);--輸出結果
       end loop;
end;
2:FOR循環示例
DECLARE 
     cursor c_1 is select id,real_name from pl_user;     --定義遊標     
BEGIN
     dbms_output.put_line('行號 id 真實姓名');
     FOR r IN c_1         --for循環中的循環變量i爲c_1%rowtype類型;
     LOOP
     dbms_output.put_line(c_1%rowcount ||' '|| r.id ||' '|| r.real_name);
     END LOOP;
END;

注:for循環使用遊標是在循環開始前自動打開遊標,並且自動取值到循環結束後,自動關閉遊標.

3:遊標加鎖示例:
DECLARE 
     cursor c_1 is select id,real_name from pl_user for update of real_name;     --定義遊標對pl_user表的real_name字段加鎖.     
BEGIN
     dbms_output.put_line('行號 id 真實姓名');
     FOR i IN c_1         --for循環中的循環變量i爲c_1%rowtype類型;
     LOOP
     UPDATE pl_user set real_name=concat(real_name,100) WHERE CURRENT OF c_1; --表示對當前行的real_name進行跟新.
     END LOOP;
     FOR i IN c_1        
     LOOP
     dbms_output.put_line(c_1%rowcount||' '||i.id||' '||i.real_name);    --輸出結果
     END LOOP;
END;
4:代參數的遊標示例
DECLARE 
     cursor c_1(name pl_user.real_name%type) is select id,real_name from pl_user where rownum <5 and real_name=name;     --定義遊標     
BEGIN
     dbms_output.put_line('行號 id 真實姓名');
     FOR i IN c_1('&name')         --for循環中的循環變量i爲c_1%rowtype類型;
     LOOP
     dbms_output.put_line(c_1%rowcount||' '||i.id||' '||i.real_name);    --輸出結果,需要 set serverout on 才能顯示.
     END LOOP;
END; 

注:需要傳入name變量的值供遊標的執行

5:隱式遊標示例

隱式遊標遊標是系統自動生成的。每執行一個DML語句就會產生一個隱試遊標,起名字爲SQL;

隱式遊標不能進行"OPEN" ,“CLOSE”,"FETCH"這些操作;

屬性:
%NOTFOUND --如果DML語句沒有影響到任何一行時,則該屬性爲"TRUE",否則爲"FALSE";
%FOUND --如果DML語句影響到一行或一行以上時,則該屬性爲"TRUE",否則爲"FALSE";
%ROWCOUNT --返回遊標當最後一行的行數;

BEGIN
    DELETE FROM pl_user WHERE real_name='&a';
    IF SQL%NOTFOUND THEN
        dbms_output.put_line('real_name不存在');
    END IF;
   IF SQL%ROWCOUNT>0 THEN
        dbms_output.put_line('刪除成功');
    END IF;
END;

注:調用時需要給a傳參纔可,如果參數爲number類型的話 則遊標創建語句後半部分需要改爲real_name=&a;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章