db2存儲過程


一. 使用存儲過程的好處

  1. 減少客戶機與服務器之間的網絡使用率,以及數據庫鎖定保持的時間

      應用程序通常在執行每個SQL語句都要跨網絡兩次,存儲過程可以將SQL語句集中在一起,

    從而使得對於每一組SQL語句只需要跨網絡兩次。存儲過程中集中在一起的SQL語句越多,

    網絡的使用率和數據庫鎖定保持的時間就越低。通過減少網絡使用率和數據庫鎖定的時間長短,

    就可以提高網絡的總體性能並減少鎖定爭用問題。

 

二. 用於存儲過程的語言

  在DB2的"開發中心",可以用Java或SQL來創建存儲過程。

 

三. SQL存儲過程

  1. 使用SQL過程語言來編寫存儲過程具有下列優點:

    a. 可以通過在"開發中心"中使用集成調試器來調試SQL存儲過程

    b. 借助SQL存儲過程,可以調用其它SQL過程,最多可以嵌套16層調用

    c. SQL存儲過程運行速度快,因為它是作為已編譯的例程來運行的

  2. SQL存儲過程具有大小和參數限制,這取決於正在運行的DB2版本:

    a. 對於DB2 Windows版和UNIX版,在版本7和版本8中,SQL存儲過程的最大大小是64KB

 

四. Java存儲過程

   1. 使用Java語言來編寫存儲過程具有下列優點:

    a. 在Java的安全性限制之內,可以使用Java存儲過程進行文件的輸入/輸出。SQL存儲過程不支持

      文件的輸入/輸出。

 

五. 存儲過程的基本語法 

create procedure db2Inst.proce1(
    in "inParam" integer,
    out "outParam" varchar(10)
)
specific "proce1"
language sql
dynamic result sets 1
not deterministic
external action
modifies sql data
old savepoint level

begin
    L1: begin
        /*變量定義*/
        declare inum integer default 0;

        /*變量賦值*/
        set inum = 20;

        /*分支語句*/
        if 條件1 then
            ...
        elseif 條件2 then
            ...
        else 
            ...
        end if;

        /*多分支語句case*/
        case 變量名
            when 變量值1 then 
                ...
            when 變量值2 then 
                ...
            else 
                ...
        end case;

        /*for循環*/
        for 變量名 as 游標名或select 表達式
        do
            ...
        end for;

        /*while循環*/
        while 條件表達式 do
            ...
        end while;

        /*loop語句*/
        insLoop:
        loop
            ...
            leave insLoop;/*中斷循環*/
            iterate insLoop;/*下一個循環*/
        end loop;

        /*游標的使用方式一*/
        /*定義游標*/
        declare 游標名 cursor for select 語句;
        /*打開游標*/
        open 游標名;
        /*取值*/
        fetch 游標名 into 變量列表;
        /*關閉游標*/
        close 游標名;

        /*goto語句*/
        goto fail;
            ...
        success: return 0
        fail: return -200
        
    end L1;

    /*游標的使用方式二*/
    /*游標的定義如果放在中間段,要用"begin...end;"段分割標志分割開*/
    L2: begin
        declare v_notfound integer default 0;
        declare stmt statement;/*聲明放游標的值 */        
        declare cur cursor with return for stmt;/*聲明動態游標存儲變量*/
        declare continue handler for not found set v_notfound = 1;

        prepare stmt from qrySql;
        open cur;
        fetch cur into 變量列表;
        close cur;
    end L2;
    
    /*臨時表*/
    L3: begin
        /*定義臨時表*/
        declare global temporary table session.tableName(
                columnName integer
        )
        not logged with replace;/*不記錄日志,沒有則替換*/
        /*操作臨時表*/
        insert into session.tableName values(columnValue);
    end L3;

    /*取得行號*/
    select rownumber() over() as rownum from tableName;

    /*解決like后跟一個字段*/
    select * from table1 a
    left join table2 b on locate(a.columnName,b.columnName)>0;

end
View Code


六. 存儲過程屬性說明

procedureName:存儲過程的名字,在同一個數據庫的同一模式下,不能存在
    存儲過程名相同,參數數目相同的存儲過程,即使參數的類型不同也不行
    
(in|out|inout paramName dataType, ...):傳入參數
    in:輸入參數,out:輸出參數,inout:作為輸入輸出參數
    dataType:參數類型,可以接收SQL類型和創建的表,不支持long varchar,
        long vargraphic,datalink,reference和用戶自定義類型。

specific specificName:唯一的特定名稱(別名),可以用存儲過程名代替。
    用於給存儲過程添加注釋用,但不能調用存儲過程。如果不指定,則數據庫
    會自動生成一個yymmddhhmmsshhn時間戳的名字。

language sql:指定過程的主體用的是SQL語言

dynamic result sets integer:指定存儲過程返回結果的最大數量,若小於實際返回數量,則db2返回警告

deterministic or not deterministic:表示存儲過程是動態或者非動態的。
    動態的返回的值是不確定的,非動態每次返回值都是相同的

external action or no external action:表示存儲過程是否執行改變數據庫狀態的活動,
    而不通過數據庫管理器。默認是external action。如果指定為no external action,
    則數據庫會確定最佳優化方案。

contains sql, reads sql data, modifies sql data:指定存儲過程中的SQL訪問級別
    contains sql:表示存儲過程可以執行中,既不可讀取SQL數據,也不可修改SQL數據。
    reads sql data:表示存儲過程可以執行中,可讀取SQL,但不可修改SQL數據。
    modifies sql data:表示存儲過程可以執行任何SQL語句。可以對數據庫中的數據進行
        增加、刪除和修改。
    
old savepoint level or new savepoint level:建立存儲點(存儲某個時候的數據),
    old savepoint level是默認的存儲點

called on null input:表示可以調用存儲過程而不管任何的輸入參數是否為NULL,並且,
    任何的out或者inout參數可以返回一個NULL或者非空值。檢驗參數是否為NULL是在過程中進行的。

inherit special registers:表示繼承專用寄存器

parameter ccsid:指定所有輸出字符串數據的編碼,默認為unicode編碼數據庫為:parameter ccsid unicode,
    其他的數據庫默認為:parameter ccsid 3 ascii
View Code

 

七. 存儲過程調用另一存儲過程,返回結果集

  1. 存儲過程1:返回2個結果集

create procedure db2Inst.proc1()
language sql
result sets 2

P1:begin
    declare c1 cursor with return to caller for select語句;
    declare c2 cursor with return to caller for select語句;

    open c1;
    open c2;

    ...
end P1
View Code

  2. 存儲過程2:調用存儲過程1,取得2個結果集

create procedure db2Inst.proc2()
language sql

P1:begin
    /*建立一個結果集數組*/
    declare loc1,loc2 result_set_locator varying;
    /*調用存儲過程1,返回結果集*/
    call proc1;
    /*將返回結果集和結果集數組關聯*/
    associate result set locator(loc1,loc2) with procedure proc1;
    /*將結果集數組進行分配*/
    allocate cursor1 cursor for result set loc1;
    allocate cursor2 cursor for result set loc2;

    /*直接從結果集中取值*/
    fetch cursor1 into 變量列表;
    close cursor1;
    
    ...
end P1
View Code

 

八. 結果集的返回類型  

create procedure db2Inst.proc3()
language sql
dynamic result sets 2
reads sql data

begin
    declare rs1 cursor with return to client for select語句;
    declare rs2 cursor with return to caller for select語句;
    open rs1;
    open rs2;
end
View Code

  1. with return to client:表示由發出最初call語句的客戶應用接收結果集,即使結果集由嵌套層次中的

    15層深的嵌套存儲過程發出也是如此。

  2. with return to caller:表示由存儲過程的調用者接收結果集,而不考慮調用者是否是另一個存儲過程,

    還是客戶應用。

 

九. 異常處理

  1. 聲明異常處理器的語法如下,它會位於變量聲明和游標聲明之后:

    declare handlerType handler for condition

  2. handlerType異常處理器類型有以下幾種:

    a. continue:在處理器操作完成之后,會繼續執行產生這個異常語句之后的下一條語句

    b. exit:在處理器操作完成之后,存儲過程會終止,並將控制返回給調用者

    c. undo:在處理器操作執行之前,DB2會回滾存儲過程中執行的SQL操作。在處理器操作

      完成之后,存儲過程會終止,並將控制返回給調用者。

  3. 異常的種類(condition)

    異常處理器可以處理基於特定SQLSTATE值的定制異常,或者處理預定義異常的類。

    預定義的3種異常:

      a. not found:標識導致SQLCODE值為+100或者SQLSTATE值為0200的異常。

        這個異常通常在select沒有返回行的時候出現。

      b. sqlexception:標識導致SQLCODE值為負的異常

      c. sqlwarning:標識導致警告異常或者導致+100以外的SQLCODE正值的異常

  4. 異常處理器示例

    declare exit handler for sqlexception, sqlwarning set stmt = "aborted";

    declare undo handler for not found;


免責聲明!

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



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