隨筆-7  評論-24  文章-102  trackbacks-0


          一、游標(biāo)
          二、存儲過程
          三、函數(shù)
              過程與函數(shù)的異同
          四、程序包



          一、游標(biāo)
              游標(biāo)是一種 PL/SQL 控制結(jié)構(gòu),可以對SQL語句的處理進(jìn)行顯式控制,便于對表的數(shù)據(jù)逐條進(jìn)行處理。
          ps.當(dāng)表中數(shù)據(jù)量大的時候,不建議使用游標(biāo)(效率不高,耗費資源),但是它能逐條取數(shù)據(jù)方法靈活。
              游標(biāo)是記錄的指針,利用游標(biāo)對活動集的更新或刪除會反饋到表的記錄上。

          游標(biāo)屬性:%FOUND、%NOTFOUND、%ROWCOUNT、%ISOPEN


          1、顯式游標(biāo)
              顯式游標(biāo)是由用戶顯式聲明的游標(biāo)。根據(jù)在游標(biāo)中定義的查詢,查詢返回的行集可以包含零或多行,這些行稱為活動集。游標(biāo)將指向活動集中的當(dāng)前行。

          顯式游標(biāo)操縱過程:聲明、打開、從游標(biāo)中獲取記錄、關(guān)閉。
          SET SERVEROUTPUT ON;
          DECLARE
            CURSOR cur IS
              SELECT * FROM books;
            myrecord books%ROWTYPE;
          BEGIN
            OPEN cur;
            LOOP
              FETCH cur INTO books;
              EXIT WHEN cur%NOTFOUND;
              DBMS_OUTPUT.PUT_LINE(books.id || ' ' || books.name);
            END LOOP;
            CLOSE cur;
          END;

          1.1、帶參數(shù)的顯式游標(biāo):參數(shù)不需指定長度或者精度。
          1.2、FOR 循環(huán)游標(biāo):采用遍歷方式,自動打開、提取和關(guān)閉游標(biāo)。(能否利用 %ROWCOUNT 獲得游標(biāo)提取的行數(shù)?)
          DECLARE
            /* 定義帶參數(shù)游標(biāo) */
            CURSOR cur_para(id varchar2) IS
            SELECT books_name FROM books WHERE books_id = id;
          BGEIN
            /* 調(diào)用帶參數(shù)游標(biāo),并以 FOR 循環(huán)方式處理 */
            FOR cur IN cur_para('0001') LOOP
              DBMS_OUTPUT.PUT_LINE(cur.books_id || ' ' || cur.books_id);
            END LOOP;
          END;
          1.3、使用顯示游標(biāo)刪除或更新記錄
          定義時:需使用 SELECT ... FOR UPDATE 語句表示事物的鎖定;
          執(zhí)行時:需使用 WHERE CURRENT OF curXXX 子句指定游標(biāo)的當(dāng)前行。

            /* 定義部分 */
            CURSOR cur IS
            SELECT name FROM deptment FOR UPDATE;
          ....
            /* 執(zhí)行部分 */
            UPDATE deptment SET name=name || '_tt' WHERE CURRENT OF cur;


          2、隱式游標(biāo)
          不需聲明,打開和關(guān)閉的游標(biāo)。PL/SQL 為所有的 SQL 數(shù)據(jù)操縱語句隱式聲明游標(biāo),它是不能直接命名和控制。
          BEGIN
            FROM cur IN (SELECT name FROM deptment) LOOP
              DBMS_OUTPUT.PUT_LINE(cur.books_id || ' ' || cur.books_id);
            END LOOP;
          END;

          ps.
          匿名塊:每次執(zhí)行時都需要被編譯,并且無法存儲到數(shù)據(jù)庫中,別的 PL/SQL 塊也無法調(diào)用它。
          命名塊:存儲在數(shù)據(jù)庫中,屬于數(shù)據(jù)庫對象。

          排錯:SHOW ERRORS PROCEDURE/FUNCTION/PACKAGE obj_name;



          二、存儲過程
          CREATE OR REPLACE PROCEDURE test (value IN varchar2, value2 OUT NUMBER)
            /* 參數(shù),不需指定長度或精度 */
          IS
            /* 局部變量,省略 DECLARE 關(guān)鍵字,需有長度 */
            identity NUMBER;
          BEGIN
            SELECT ITEMRATE INTO identity
              FROM itemFile
              WHERE itemcode = value;
            IF identity < 200 THEN
              value2 := 200;
            ELSE
              value2 :=50;
            END IF;
          END;

          ● 匿名塊執(zhí)行過程
          DECLARE
            tvalue2 NUMBER;
          BEGIN
            test('i202', tvalue2);
            DBMS_OUTPUT.PUT_LINE('value2的值為:' || TO_CHAR(value2));
          END;
          ● 單獨執(zhí)行
              EXECUTE myproc('0001');



          三、函數(shù)
              函數(shù)的主要特性是它必須返回一個值。創(chuàng)建函數(shù)時通過 RETURN 子句指定函數(shù)返回值的數(shù)據(jù)類型。
          函數(shù)的一些限制:
            ● 函數(shù)只能帶有 IN 參數(shù),不能帶有 IN OUT 或 OUT 參數(shù)。
            ● 形式參數(shù)必須只使用數(shù)據(jù)庫類型,不能使用 PL/SQL 類型。
            ● 函數(shù)的返回類型必須是數(shù)據(jù)庫類型。
          CREATE OR REPLACE FUNCTION item_price_rage (price NUMBER)
             /* 參數(shù)、指定返回類型 */
            RETURN varchar2
          AS
             /* 定義局部變量 */
            min_price NUMBER;
            max_price NUMBER;
          BEGIN
            SELECT MAX(ITEMRATE), MIN(ITEMRATE) INTO max_price, min_price
              FROM itemfile;
            IF price >= min_price AND price <= max_price THEN
              RETURN '輸入的單價介于最低價與最高價之間';
            ELSE
              RETURN '超出范圍';
            END IF;
          END;

          ● 匿名塊執(zhí)行函數(shù)
          DECLARE
            p NUMBER := 300;
            MSG varchar2(200);
          BEGIN
            MSG := item_price_range(p);
            DBMS_OUTPUT.PUT_LINE(MSG);
          END;
          ● SELECT查詢調(diào)用(因為函數(shù)必須有返回值)
              SELECT myfunction FROM dual;



              過程與函數(shù)的異同
          過程:
              作為 PL/SQL 語句執(zhí)行;
              在規(guī)范中不包含 RETURN 子句;
              不返回任何值(只有輸入/輸出參數(shù),結(jié)果集);
              可以包含 RETURN 語句,但是與函數(shù)不同,它不能用于返回值。
          函數(shù):
              作為表達(dá)式的一部分調(diào)用;
              必須在規(guī)范中包含 RETURN 子句;
              必須返回單個值;
              必須包含至少一條 RETURN 語句。



          四、程序包
              程序包是一種數(shù)據(jù)庫對象,它是對相關(guān) PL/SQL 類型、子程序、游標(biāo)、異常、變量和常量的封裝。
          程序包規(guī)范:聲明類型、變量、常量、異常、游標(biāo)和子程序。
          程序包主體:用于實現(xiàn)在程序包規(guī)范中定義的游標(biāo)、子程序。


          4.1、程序包規(guī)范
          包含應(yīng)用程序所需的程序包資源,是與應(yīng)用程序的接口。
          CREATE OR REPLACE PACKAGE pack_me
          IS
            PROCEDURE order_proc (orno varchar2);
            FUNCTION order_fun (ornos varchar2) RETURN varchar2;
          END pack_me;
          *創(chuàng)建 pack_me 包,并聲明了子程序 order_proc 和 order_fun,并交由程序包主體實現(xiàn)。


          4.2、程序包主體
          當(dāng)程序包規(guī)范中指定了子程序和游標(biāo)時,必須有程序包主體。
          CREATE OR REPLACE PACKAGE BODY pack_me
          AS
            /* 實現(xiàn)定義的存儲過程 */
            PROCEDURE order_proc (orno varchar2)
            IS
              stst CHAR(1);
            BEGIN
              SELECT ostatus INTO stat FROM order_master
                WHERE orderno = orno;
              IF stat = 'p' THEN
                DBMS_OUTPUT.PUT_LINE('暫掛的訂單');
              ELSE
                DBMS_OUTPUT.PUT_LINE('已完成的訂單');
              END IF;
            END order_proc;
            /* 實現(xiàn)定義的函數(shù) */
            FUNCTION order_fun(ornos varchar2) RETURN varchar2
            IS
              icode varchar2(5);
              ocode varchar2(5);
              qtyord NUMBER;
              qtydeld NUMBER;
            BEGIN
              SELECT qty_ord, qty_deld, itemcode, ordernc INTO qtyord, qtydeld, icode, ocode
                FROM order_detail
                WHERE orderno = ornos;
              IF qtyord < qtydeld THEN
                RETURN ocode;
              ELSE
                RETURN icode;
              END IF;
            END order_fun;
          END pack_me;

          ● 要執(zhí)行 pack_me包中的 order_proc過程,輸入
              EXECUTE pack_me.order_proc('o002');

          ● 要執(zhí)行包中預(yù)定義的函數(shù)
          DECLARE
            msg varchar2(10);
          BEGIN
            msg := pack_me.order_fun('o002');
            DBMS_OUTPUT.PUT_LINE('值是 ' || msg);
          END;
           
          4.3、程序包的優(yōu)點
              程序包將相關(guān)的功能在邏輯上組織在一起,模塊化,信息隱藏和更好的性能。
          ps.數(shù)據(jù)字典視圖 USER_SOURCE 包含存儲過程的代碼文本。


          4.4、內(nèi)置程序包
          STANDARD 和 DBMS_STANDARD:定義和擴展 PL/SQL 語言環(huán)境
          DBMS_LOB:提供對 Oracle LOB 數(shù)據(jù)類型進(jìn)行操作的功能
          DBMS_LOCK:用戶定義的鎖
          DBMS_OUTPUT:處理 PL/SQL 塊和子程序輸出調(diào)試信息
          DBMS_SESSION:提供 ALTER SESSION 命令的 PL/SQL 等效功能
          DBMS_ROWID:獲得 ROWID 的詳細(xì)信息
          DBMS_RANDOM:提供隨機數(shù)生成器
          DBMS_SQL:允許用戶使用動態(tài) SQL,構(gòu)造和執(zhí)行任意 DML 或 DDL 語句
          DBMS_JOB:提交和管理在數(shù)據(jù)庫中執(zhí)行的定時任務(wù)
          DBMS_XMLDOM:用 DOM 模型讀寫 XML 類型的數(shù)據(jù)
          DBMS_XMLPARSER:XML 解析,處理 XML 文檔內(nèi)容和結(jié)構(gòu)
          DBMS_XMLGEN:將 SQL 查詢結(jié)果轉(zhuǎn)換為規(guī)范的 XML 格式
          DBMS_XMLQUERY:提供將數(shù)據(jù)轉(zhuǎn)換為 XML 類型的功能
          DBMS_XSLPROCESSOR:提供 XSLT 功能,轉(zhuǎn)換 XML 文檔
          UTL_FILE:用 PL/SQL 程序來讀寫操作系統(tǒng)文本文件



          posted on 2008-10-25 21:08 黃小二 閱讀(16016) 評論(4)  編輯  收藏 所屬分類: [DB].Oracle

          評論:
          # re: Oracle 筆記(八)、PL/SQL 高級應(yīng)用(游標(biāo)、存儲過程、函數(shù)、程序包)[未登錄] 2008-12-02 16:24 | Jiang
          黃先生,您好!您寫的學(xué)習(xí)筆記《Oracle 筆記(八)、PL/SQL 高級應(yīng)用(游標(biāo)、存儲過程、函數(shù)、程序包)》,不知您學(xué)習(xí)的是否是這個課程《Oracle 10G 數(shù)據(jù)庫系統(tǒng)教程 中科院培訓(xùn)老師講授》中的052視頻?如果是,能否請您給052視頻,放上電驢(http://www.verycd.com/topics/93739/comments/#comment3176735),共享您的資料,讓大家來學(xué)習(xí)?本人也非常想找到這個052的完整版學(xué)習(xí),找了很久,找了很多修復(fù)AVI軟件都不行,用軟件轉(zhuǎn)換也不行,真的非常非常感謝您!  回復(fù)  更多評論
            
          # re: Oracle 筆記(八)、PL/SQL 高級應(yīng)用(游標(biāo)、存儲過程、函數(shù)、程序包)[未登錄] 2008-12-02 16:27 | Jiang
          黃先生,如果您看到上面的信息,還請您能考慮,非常非常感謝您!  回復(fù)  更多評論
            
          # re: Oracle 筆記(八)、PL/SQL 高級應(yīng)用(游標(biāo)、存儲過程、函數(shù)、程序包) 2009-01-12 15:17 | 黃小二
          我下的視頻 052集也是不完全的版本, 幫不上忙,真的很抱歉

          ps.現(xiàn)在才回復(fù)你, 抱歉
            回復(fù)  更多評論
            
          # re: Oracle 筆記(八)、PL/SQL 高級應(yīng)用(游標(biāo)、存儲過程、函數(shù)、程序包)[未登錄] 2009-10-18 14:14 | sam
          顯示游標(biāo):
          SET SERVEROUTPUT ON;
          DECLARE
          CURSOR cur IS
          SELECT * FROM books;
          myrecord books%ROWTYPE;
          BEGIN
          OPEN cur;
          LOOP
          FETCH cur INTO myrecord;
          EXIT WHEN cur%NOTFOUND;
          DBMS_OUTPUT.PUT_LINE(myrecord.id || ' ' || myrecord.name);
          END LOOP;
          CLOSE cur;
          END;
          -------------------------------
          DECLARE
          /* 定義帶參數(shù)游標(biāo) */
          CURSOR cur_para(id varchar2) IS
          SELECT books_name FROM books WHERE books_id = id;
          BGEIN
          /* 調(diào)用帶參數(shù)游標(biāo),并以 FOR 循環(huán)方式處理 */
          FOR cur IN cur_para('0001') LOOP
          DBMS_OUTPUT.PUT_LINE(cur.books_name);
          END LOOP;
          END;

          -------------------------------

          隱式游標(biāo):

          BEGIN
          FROM cur IN (SELECT name FROM deptment) LOOP
          DBMS_OUTPUT.PUT_LINE(cur.name);
          END LOOP;
          END;


            回復(fù)  更多評論
            
          主站蜘蛛池模板: 贺兰县| 徐水县| 山东| 呼伦贝尔市| 灵台县| 游戏| 耒阳市| 宁津县| 当阳市| 云林县| 来安县| 镇坪县| 许昌县| 涞水县| 东至县| 汝城县| 陇南市| 建宁县| 滁州市| 九龙坡区| 富民县| 祥云县| 清河县| 邮箱| 江孜县| 洪江市| 顺昌县| 城步| 册亨县| 越西县| 思茅市| 金昌市| 柳州市| 扎兰屯市| 韩城市| 宁阳县| 汾阳市| 漳浦县| 涟水县| 神农架林区| 南和县|