<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 297,  comments - 1618,  trackbacks - 0

    1、簡介
            存儲過程(Stored Procedure)是一組為了完成特定功能的SQL語句集,經編譯后存儲在數據庫中。用戶通過指定存儲過程的名字并給出參數(如果該存儲過程帶有參數)來執行它。存儲過程是數據庫中的一個重要對象,任何一個設計良好的數據庫應用程序都應該用到存儲過程。
            存儲過程是由流控制和SQL語句書寫的過程,這個過程經編譯和優化后存儲在數據庫服務器中,應用程序使用時只要調用即可。
    2、重要概念和疑問解答
            1)何謂informix中的SPL?
            SPL(Stored Procedure Language)是informix中提供的一種提供流程控制(分支和循環)的SQL。它包括SPL過程(沒有返回值)和SPL函數(有返回值)。SPL將在創建的時候被解析和優化,它以可執行的方式保存在system catalog表中。
            2)使用SPL為什么會改善性能?
            i)因為它運行在informix引擎中,所以減少了I/O;
            ii)降低了應用的復雜性;
            iii)對頻率較高的重復操作使用更好。
            3)SPL的靈活性表現在哪些部分?
            i)它可在其它SQL語法中被調用;
            ii)它也可以在觸發器中使用;
            iii)可在SQL中添加流程控制;
            iv)很容易維護。
           4)SPL的參數
           i)可以傳遞很多個參數;
           ii)SPL的參數的最大限制是32K;
           iii)除了如下兩種外可以是任何一種SQL數據類型:
                 Serial/Serial8
                 Text/Byte (能夠使用REFERENCES關鍵字傳遞)。
           iv)能夠使用很復雜或者用戶自定義的數據類型;
           v)可以通過default為參數指定默認值。
           5)SPL函數的返回值
           i)可以使用RETURNING或RETURNS關鍵字定義返回值的返回類型;
           ii)除了如下兩種數據類型外可以為任何數據類型:
                Serial/Serial8
                Text/Byte (可以使用REFERENCES關鍵字傳遞)。
           iii)在過程體內必須至少有一個return語句;
           iv)可以為返回值取一個名稱。例如:

    CREATE FUNCTION val_comp (val1 INTEGER, val2 INTEGER)
    RETURNING 
    INTEGER AS comp_res;

          6)SPL的重載
          可定義多個具有相同名字的SPL函數;例如如下SPL函數雖然名稱相同,但是參數類型或各不相同:

    CREATE FUNCTION val_comp (val1 INTEGER, val2 INTEGER)
    CREATE FUNCTION val_comp (val1 CHAR(25), val2 CHAR(25))
    CREATE FUNCTION val_comp (val1 DECIMAL, val2 DECIMAL)

         可使用SPECIFIC關鍵字指定SPL函數的簡短的、獨一無二的被重載的SPL的函數的名稱。這個名字在數據庫中是唯一的。例如:

    CREATE FUNCTION val_comp (val1 INTEGER, val2 INTEGER) SPECIFIC int_comp
    CREATE FUNCTION val_comp (val1 CHAR(25), val2 CHAR(25)) SPECIFIC string_comp
    CREATE FUNCTION val_comp (val1 DECIMAL, val2 DECIMAL) SPECIFIC dec_comp

         7)何謂語句塊?
         i)語句塊是一組SPL或SQL語句;
         ii)隱式的語句塊包含在CREATE PROCEDURE/FUNCTION和END PROCEDURE/FUNCITON之間;
         iii)可使用BEGIN和END來顯式的知名內嵌在另一個語句塊中的語句塊,例如:

    CREATE PROCEDURE myproc1() -- 隱式的語句塊的開始
    DEFINE x INT;
    LET x 
    = 15;
    INSERT INTO table1 VALUES (x, 'amigo');
    BEGIN -- 顯式的語句塊的開始
    DEFINE y INT;
    LET y 
    = 16;
    INSERT INTO table1 VALUES ( y, 'xingxing');
    END -- 顯式的語句塊的結束
    END PROCEDURE-- 隱式的語句塊的結束

          8)如何定義變量?
          i)是語句塊中使用DEFINE定義變量;
          ii)變量在內存中,而不是在數據庫中保存;
          iii)有本地變量和全局變量兩種;
          iv)變量可以是除了如下兩種類型之外的任何一種SQL數據類型和擴展類型:
                 Serial/Serial8
                 Text/Byte (可以使用REFERENCES關鍵字來聲明)。
          定義變量舉例如下:

    DEFINE x, y INT-- 內建的數據類型
    DEFINE p person_type; -- 用戶自定義的數據類型person_type
    DEFINE mymusic REFERENCES BYTE; -- 使用REFERENCES關鍵字定義BYTE類型

          9)本地變量和全局變量比較
          本地變量:
          i)本地變量值在SPL中有效;
          ii)在SPL函數或過程結束后就被復位;
          iii)它不能有默認值;
          iv)它的作用域是在它定義的語句塊中,或者任何內嵌語句塊中;
          v)本地變量能夠被重新定義在另一個語句塊中。
         下面來看一個本地變量的實例:

    CREATE PROCEDURE local_scope()
    DEFINE x,y,z 
    INT;
    LET x 
    = 5;
    LET y 
    = 10;
    LET z 
    = x + y; -- z等于15
    BEGIN
      DEFINE x, q 
    INT-- x被重新定義
      DEFINE z CHAR(5); -- z被重新定義
      LET x = 100;
      LET q 
    = x + y; -- q=110
      LET z = 'amigo'-- 給z設置了一個新的值
    END
    LET y 
    = x; -- y等于5
    LET x = z; -- z的值是15,而不是amigo
       END PROCEDURE;

         全局變量:
         i)在相同數據庫中使用相同的用戶會話的地方都能得到全局變量的值;
         ii)必須有一個默認值;
         iii)必須在每一個要使用它的SPL函數或過程中定義;
         iv)不能是一個集合變量。
         例如如下定義了兩個SPL函數,名稱分別為func1和func2,func1參考語句如下:

    CREATE FUNCTION func1() RETURNING INT;
    DEFINE GLOBAL gvar 
    INT DEFAULT 2;
    LET gvar 
    = gvar + 1;
    RETURN gvar;
    END FUNCTION;

         func2參考語句如下:

    CREATE FUNCTION func2()RETURNING INT;
    DEFINE GLOBAL gvar 
    INT DEFAULT 5;
    LET gvar 
    = gvar + 1;
    RETURN gvar;
    END FUNCTION;

         如果執行兩者的順序如下:

    EXECUTE FUNCTION func1();
    EXECUTE FUNCTION func2();

         則執行完第一句后,gvar被設置了默認值2,且執行了加1的操作,所以第一句執行完畢后gvar的值為3.
         接著執行第二句,第這次不在設置gvar的默認值,因此在3的基礎上再執行了加1操作,執行完畢后gvar的值為4.
         若執行兩者的順序如下:

    EXECUTE FUNCTION func2();
    EXECUTE FUNCTION func1();

         則執行完第一句后,gvar被設置了默認值5,且執行了加1的操作,所以第一句執行完畢后gvar的值為6.
         接著執行第二句,第這次不在設置gvar的默認值,因此在6的基礎上再執行了加1操作,執行完畢后gvar的值為7.
         10)給變量賦值
         i)使用一個未定義的變量將會報錯;
         ii)給已定義的變量賦值的方法:
               * 使用LET語句直接給變量賦初值,參考語句如下:

          LET <變量> = <有效的表達式或函數名>;

              *使用SELET INTO語句將查詢到的結果給變量賦值,參考語句如下:

          SELECT … INTO <變量> FROM …;

              *使用CALL...RETURNING語句將返回結果賦給變量,參考語句如下:

           CALL … RETURNING <變量>;

              *使用EXECUTE FUNCTION INTO語句,將返回結果賦給變量,參考語句如下:

           EXECUTE FUNCTION … INTO <變量>;

    3、語法
     
          1)創建SPL過程

    CREATE PROCEDURE name (parameter list) SPECIFIC specific_name
    … {語句塊}
    END PROCEDURE;

          例如,在下面的實例中創建了一個名為set_status的存儲過程,可傳入myid和mystatus兩個參數,在這個存儲過程中,對item_inventory表進行update操作,id字段滿足myid的記錄將status字段更新為mystatus。參考語句如下:

    CREATE PROCEDURE set_status (myid INTEGER DEFAULT 0, mystatus CHAR(25))
    UPDATE item_inventory SET status = mystatus WHERE id = myid;
    END PROCEDURE;

           2)創建SPL函數

    CREATE FUNCTION name (parameter list)
    RETURNING list SPECIFIC specific_name
    … {語句塊}
    END FUNCTION;

          例如,創建一個名為val_comp的SPL函數,可傳入val1和val2兩個參數,在該函數中,比較這兩個變量,如果兩者相等,返回0,否則返回1。參考語句如下:

    CREATE FUNCTION val_comp (val1 INTEGER, val2 INTEGER)
    RETURNING 
    INTEGER;
    DEFINE res 
    INTEGER;
    IF (val1 = val2) THEN
    LET res 
    = 0;
    ELSE
    LET res 
    = 1;
    END IF;
    RETURN res;
    END FUNCTION;

     4、SPL中的流程控制
         1)分支語句if...then...else...end if
         參考實例:

    IF ( condition ) THEN
       statements
    ELIF ( condition ) 
    THEN
       statements
       …
    ELSE
       statements
    END IF;
         2)分支語句case
         參考實例:
    CASE ( condition )
       
    WHEN <value1> THEN
          statements
       
    WHEN <value2> THEN
          statements
          …
        
    ELSE
          statements
    END CASE;
         3)循環語句for
         參考語法如下:
    FOR 變量 IN ( 范圍或值 )
         或者使用如下語法:
    FOR 變量=范圍
         舉例如下:
    FOR count = 2 TO 30
    FOR count = 2 TO 30 STEP 2
    FOR count IN ( 2579)
    FOR count IN ( 2 to 8 STEP 212 to 1922)
    FOR name IN ("AMY", "MAX",
    (
    SELECT name FROM customer WHERE customer_num = 100) )
         4)循環語句while
         參考語法如下所示:
    WHILE (條件表達式)
       執行的語句
    END WHILE;
          while中的條件表達式的舉例如下:
    WHILE (count < 20)
    WHILE (status matches "A*")
    WHILE (EXISTS (SELECT name FROM customer WHERE cus_num=100))
    WHILE (status IN ("A", "I", "D"))
          5)循環語句foreach
          i)被用來取多行數據;
          ii)它打開了一個游標;
          iii)游標用來取得當前的行,以便進行行的更新或刪除操作。
          參考實例如下:
    FOREACH SELECT salary INTO ind_sal
    FROM customer
    WHERE location = “UK"
    sum_sal 
    += ind_sal;
    END FOREACH;
    RETRUN sum_sal;
           6)continue或exit語句
           都可以被使用在for、foreach和while循環語句中。
           參考實例如下:
    FOR i = 1 TO 5
       LET j 
    = i;
       
    WHILE (j > 0)
          LET id 
    = foo(j);
          
    IF (id = 5THEN
             LET j 
    = j – 1;
             
    CONTINUE WHILE-- 不執行后續的操作,繼續回到while循環接著執行
          END IF;
          LET 
    sum = sum + 5;
          LET j 
    = j – 1;
          
    IF (sum > 500THEN
             
    EXIT FOR-- 退出for循環
          END IF;
       
    END WHILE;
    END FOR;
    RETURN sum;
    5、異常處理
          1)ON EXCEPTION語句
          ON EXCEPTION語句語句提供了異常的捕獲和處理機制。在IN中指定要捕獲的錯誤,并指定當異常發生時需要執行的動作。在一個語句塊中允許有多個ON EXCEPTION語句。
          ON EXCEPTION語句必須在DEFINE語句之后,并在在任何可執行的語句塊之前。并且它在內嵌的語句塊中也是有效的。它使用SET語句來接收SQL、ISAM錯誤碼和錯誤信息。
          參考實例如下所示:
    CREATE PROCEDURE ex_test()
       DEFINE sql_err 
    INTEGER;
       DEFINE isam_err 
    INTEGER;
       DEFINE err_txt 
    CHAR(200);
       
    ON EXCEPTION IN (-206SET sql_err, isam_err, err_txt
          
    CREATE TABLE tab1 ( col1 INT, col2 INT);
          
    INSERT INTO tab1 VALUES (12);
          
    INSERT INTO tab1 VALUES (23);
       
    END EXCEPTION
       
    INSERT INTO tab1 VALUES (12); --如果tab1不存在時,跳到異常處理
       INSERT INTO tab1 VALUES (23);
    END PROCEDURE;
           2)WITH RESUME語句
           該語句在存儲過程發生錯誤時恢復語句。
           如下實例展示了WITH RESUME的使用,當異常處理完畢后,繼續后續的語句處理。參考語句如下:
    CREATE PROCEDURE ex_test()
    ON EXCEPTION IN (-206)
         
    CREATE TABLE tab1 (col1 INT, col2 INT);
         
    INSERT INTO tab1 VALUES (12);
    END EXCEPTION WITH RESUME;
    INSERT INTO tab1 VALUES (12); -- 如果tab1不存在,跳到異常處理
    INSERT INTO tab1 VALUES (23); -- 異常處理完成后,繼續該句進行處理
    INSERT INTO tab1 VALUES (34);
    END PROCEDURE;
           3)RAISE EXCEPTION語句
           i) 該語句用來創建錯誤;
           ii)它能夠用來指定SQL錯誤、ISAM錯誤和錯誤信息;
           iii)用該語句創建的錯誤,能夠被ON EXCEPTION捕獲;
           iv)可以使用指定的錯誤碼-746來表示自定義的錯誤消息。
           如下實例使用ON EXCEPTION語句指明了當發生錯誤時將錯誤碼、錯誤信息插入到自定義的錯誤表my_error_table,當傳入的參數小于1時,拋出自定義的-746異常,其余情況成功將數據插入到tab1表中,參考語句如下:
    CREATE PROCEDURE ex_test5 (a INT)
       DEFINE sql_err 
    INTEGER;
       DEFINE isam_err 
    INTEGER;
       DEFINE err_txt 
    CHAR(200);
       
    ON EXCEPTION IN (-746SET sql_err, isam_err, err_txt
          
    INSERT INTO my_error_table values (sql_err, isam_err, err_txt);
       
    END EXCEPTION;
       
    IF (a < 1THEN
          RAISE EXCEPTION 
    -7460, "插入值必須大于0";
       
    END IF;
       
    INSERT INTO tab1 VALUES (1, a);
    END PROCEDURE;
    6、執行SPL函數或存儲過程
            可使用EXECUTE PROCEDURE語句來執行SPL存儲過程,使用EXECUTE FUNCTION來執行SPL函數;
            參考實例1:
    EXECUTE PROCEDURE foo();
            參考實例2:
    CREATE FUNCTION func1() RETURNING INT
        DEFINE myvalue 
    INT;
        CALL foo() RETURNING myvalue;
        
    INSERT INTO table1 VALUES (myvalue);
        
    RETURN myvalue;
    END FUNCTION;
            參考實例3:
    SELECT * FROM table2 WHERE id = get_id("amigo");
            參考實例4:
    UPDATE table2 SET col2=foo() WHERE id=1;
    7、刪除SPL函數或存儲過程
            1)使用DROP PROCEDURE來刪除SPL存儲過程;
            2)使用DROP FUNCTION來刪除SPL函數;
            3)使用DROP ROUTINE來刪除SPL存儲過程或SPL函數。
            幾個參考實例如下:
    DROP PROCEDURE foo;
    DROP PROCEDURE foo (INTEGER);
    DROP SPECIFIC PROCEDURE foo_int;
    DROP FUNCTION foo_ret;
    DROP FUNCTION foo_ret (INTEGER);
    DROP SPECIFIC FUNCTION foo_ret_int;
    DROP ROUTINE foo;
    DROP ROUTINE foo_ret;
    posted on 2010-11-05 16:44 阿蜜果 閱讀(11205) 評論(3)  編輯  收藏 所屬分類: database


    FeedBack:
    # re: informix的存儲過程[未登錄]
    2010-12-31 20:37 | dd
    ding  回復  更多評論
      
    # re: informix的存儲過程
    2011-11-23 15:20 | jsp
    ok ,study thanks  回復  更多評論
      
    # re: informix的存儲過程
    2015-04-17 15:46 | sarahs
    study...  回復  更多評論
      
    <2010年11月>
    31123456
    78910111213
    14151617181920
    21222324252627
    2829301234
    567891011

          生活將我們磨圓,是為了讓我們滾得更遠——“圓”來如此。
          我的作品:
          玩轉Axure RP  (2015年12月出版)
          

          Power Designer系統分析與建模實戰  (2015年7月出版)
          
         Struts2+Hibernate3+Spring2   (2010年5月出版)
         

    留言簿(263)

    隨筆分類

    隨筆檔案

    文章分類

    相冊

    關注blog

    積分與排名

    • 積分 - 2294296
    • 排名 - 3

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲国产精品线观看不卡| 蜜芽亚洲av无码一区二区三区 | 亚洲综合欧美色五月俺也去| 免费观看大片毛片| 一区二区免费电影| 亚洲区视频在线观看| 免费a级毛片网站| 精品无码人妻一区二区免费蜜桃| 亚洲日韩一中文字暮| 亚洲夜夜欢A∨一区二区三区| 亚洲第一网站免费视频| 污污视频网站免费观看| 亚洲伦理一区二区| www.亚洲色图.com| 久草视频免费在线| 国产福利免费视频| 亚洲最大的成人网站| 亚洲av永久无码精品漫画 | 日韩电影免费观看| 亚洲sm另类一区二区三区| 无码久久精品国产亚洲Av影片| 破了亲妺妺的处免费视频国产| 成全视频免费观看在线看| 亚洲国产欧洲综合997久久| 久久亚洲国产精品五月天| 免费国产精品视频| 99久久这里只精品国产免费| a在线观看免费网址大全| 另类小说亚洲色图| 亚洲中文字幕一二三四区| 久久久久久久久亚洲| 国产精品亚洲高清一区二区| 成年女人免费视频播放体验区| 无码一区二区三区免费| 国产va免费观看| 在线观看免费亚洲| 亚洲一本之道高清乱码| 久久狠狠高潮亚洲精品| 亚洲精品乱码久久久久久| 亚洲日韩在线观看免费视频| 狠狠久久永久免费观看|