存儲過程實例

 

  1. create or replace procedure GetRecords(name_out out varchar2,age_in in varchar2) as    
  2. begin    
  3.   select NAME into name_out from test where AGE = age_in;    
  4. end;    
  5.   
  6. create or replace procedure insertRecord(UserID in varchar2, UserName in varchar2,UserAge in varchar2) is   
  7. begin   
  8.   insert into test values (UserID, UserName, UserAge);   
  9. end;   

首先,在Oracle中創建了一個名爲TEST_SEQ的Sequence對象,SQL語句如下:

  1. create sequence TEST_SEQ    
  2. minvalue 100    
  3. maxvalue 999    
  4. start with 102    
  5. increment by 1    
  6. nocache;   

語法應該是比較易懂的,最小最大值分別用 minvalue,maxvalue表示,初始值是102(這個數字是動態變化的,我創建的時候設的是100,後因插入了2條數據後就自動增加了 2),increment當然就是步長了。在PL/SQL中可以用test_seq.nextval訪問下一個序列號,用 test_seq.currval訪問當前的序列號。

    定義完了Sequence,接下來就是創建一個存儲過程InsertRecordWithSequence:

--這次我修改了test表的定義,和前面的示例不同。其中,UserID是PK。

  1. create or replace procedure InsertRecordWithSequence(UserID   out number,UserName in varchar2,UserAge  in number)    
  2. is    
  3. begin insert into test(id, name, age) --插入一條記錄,PK值從Sequece獲取    
  4. values(test_seq.nextval, UserName, UserAge);    
  5. /*返回PK值。注意Dual表的用法*/    
  6. select test_seq.currval into UserID from dual;       
  7. end InsertRecordWithSequence;   

爲了讓存儲過程返回結果集,必須定義一個遊標變量作爲輸出參數。這和Sql Server中有着很大的不同!並且還要用到Oracle中“包”(Package)的概念,似乎有點繁瑣,但熟悉後也會覺得很方便。

關於“包”的概念,有很多內容可以參考,在此就不贅述了。首先,我創建了一個名爲TestPackage的包,包頭是這麼定義的:

  1. create or replace package TestPackage is    
  2.     type mycursor is ref cursor; -- 定義遊標變量    
  3.      procedure GetRecords(ret_cursor out mycursor); -- 定義過程,用遊標變量作爲返回參數    
  4. end TestPackage;      
  5. 包體是這麼定義的:    
  6. create or replace package body TestPackage is    
  7. /*過程體*/    
  8.           procedure GetRecords(ret_cursor out mycursor) as    
  9.           begin    
  10.               open ret_cursor for select * from test;    
  11.           end GetRecords;    
  12. end TestPackage;   

小結:

    包是Oracle特有的概念,Sql Server中找不到相匹配的東西。在我看來,包有點像VC++的類,包頭就是.h文件,包體就是.cpp文件。包頭只負責定義,包體則負責具體實現。如果包返回多個遊標,則DataReader會按照您向參數集合中添加它們的順序來訪問這些遊標,而不是按照它們在過程中出現的順序來訪問。可使用 DataReader的NextResult()方法前進到下一個遊標。

 

 

  1. create or replace package TestPackage is    
  2.      type mycursor is ref cursor;    
  3.      procedure UpdateRecords(id_in in number,newName in varchar2,newAge in number);    
  4.      procedure SelectRecords(ret_cursor out mycursor);    
  5.      procedure DeleteRecords(id_in in number);    
  6.      procedure InsertRecords(name_in in varchar2, age_in in number);    
  7. end TestPackage;   

包體如下:

  1. create or replace package body TestPackage is   
  2.     procedure UpdateRecords(id_in in number, newName in varchar2, newAge  in number) as   
  3.     begin   
  4.      update test set age = newAge, name = newName where id = id_in;   
  5.     end UpdateRecords;   
  6.   
  7.     procedure SelectRecords(ret_cursor out mycursor) as   
  8.     begin   
  9.        open ret_cursor for select * from test;   
  10.     end SelectRecords;   
  11.   
  12.     procedure DeleteRecords(id_in in number) as   
  13.     begin   
  14.        delete from test where id = id_in;   
  15.     end DeleteRecords;  
  16.  
  17.     procedure InsertRecords(name_in in varchar2, age_in in number) as   
  18.     begin   
  19.        insert into test values (test_seq.nextval, name_in, age_in);    
  20.     --test_seq是一個已建的Sequence對象,請參照前面的示例    
  21.     end InsertRecords;   
  22.     end TestPackage;   

TestPackage.SelectRecords

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

oracle 存儲過程的基本語法

1.基本結構

CREATE OR REPLACE PROCEDURE 存儲過程名字

(

    參數1 IN NUMBER,

    參數2 IN NUMBER

) IS

變量1 INTEGER :=0;

變量2 DATE;

BEGIN

END 存儲過程名字

2.SELECT INTO STATEMENT

  將select查詢的結果存入到變量中,可以同時將多個列存儲多個變量中,必須有一條

  記錄,否則拋出異常(如果沒有記錄拋出NO_DATA_FOUND)

  例子:

  BEGIN

  SELECT col1,col2 into 變量1,變量2 FROM typestruct where xxx;

  EXCEPTION

  WHEN NO_DATA_FOUND THEN

      xxxx;

  END;

  ...

3.IF 判斷

  IF V_TEST=1 THEN

    BEGIN

       do something

    END;

  END IF;

4.while 循環

  WHILE V_TEST=1 LOOP

  BEGIN

XXXX

  END;

  END LOOP;

5.變量賦值

  V_TEST := 123;

6.用for in 使用cursor

  ...

  IS

  CURSOR cur IS SELECT * FROM xxx;

  BEGIN

FOR cur_result in cur LOOP

  BEGIN

   V_SUM :=cur_result.列名1+cur_result.列名2

  END;

END LOOP;

  END;

7.帶參數的cursor

  CURSOR C_USER(C_ID NUMBER) IS SELECT NAME FROM USER WHERE TYPEID=C_ID;

  OPEN C_USER(變量值);

  LOOP

FETCH C_USER INTO V_NAME;

EXIT FETCH C_USER%NOTFOUND;

    do something

  END LOOP;

  CLOSE C_USER;

8.用pl/sql developer debug

  連接數據庫後建立一個Test WINDOW

  在窗口輸入調用SP的代碼,F9開始debug,CTRL+N單步調試

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

oracle存儲過程一例

By  凌雲志 發表於 2007-4-18 17:01:00  

最近換了一個項目組,暈,要寫oracle的存儲過程,幸虧寫過一些db2的存儲過程,尚且有些經驗,不過oralce的pl/sql不大一樣,花費了一下午的時間寫了一個出來,測試編譯通過了,是爲記,以備以後查閱。

  1. CREATE OR REPLACE PACKAGE PY_PCKG_REFUND2 AS   
  2. ------------------------------------------------------------------------   
  3. -- Oracle 包   
  4. ---國航支付平臺VISA退款   
  5. -- 遊標定義:   
  6. --   
  7. -- 存儲過程定義:   
  8. -- PY_WEBREFUND_VISA_PREPARE  : VISA退款準備   
  9. -- 最後修改人:dougq   
  10. -- 最後修改日期:2007.4.17  
  11. ------------------------------------------------------------------------   
  12.   
  13.  PROCEDURE PY_WEBREFUND_VISA_PREPARE (   
  14.   in_serialNoStr   IN  VARCHAR2, --用"|"隔開的一組網上退款申請流水號   
  15.   in_session_operatorid IN VARCHAR2, --業務操作員   
  16.   out_return_code     OUT VARCHAR2, --存儲過程返回碼   
  17.   out_visaInfoStr     OUT VARCHAR2   
  18.  );   
  19.     
  20. END PY_PCKG_REFUND2;   
  21. /   
  22.   
  23.   
  24. CREATE OR REPLACE PACKAGE BODY PY_PCKG_REFUND2 AS   
  25.     
  26.  PROCEDURE PY_WEBREFUND_VISA_PREPARE (   
  27.   in_serialNoStr      IN  VARCHAR2, --用"|"隔開的一組網上退款申請流水號   
  28.   in_session_operatorid IN VARCHAR2,--業務操作員   
  29.   out_return_code     OUT VARCHAR2, --存儲過程返回碼   
  30.   out_visaInfoStr     OUT VARCHAR2   
  31.  ) IS   
  32.   --變量聲明   
  33.   v_serialno  VARCHAR2(20);--網上退款申請流水號   
  34.   v_refserialno VARCHAR2(20);--支付交易流水號   
  35.   v_tobankOrderNo VARCHAR2(30);--上送銀行的訂單號   
  36.   v_orderDate  VARCHAR2(8);--訂單日期   
  37.   v_businessType VARCHAR2(10);--業務類型   
  38.   v_currType  VARCHAR2(3);--訂單類型(ET-電子機票)   
  39.   v_merno   VARCHAR2(15);--商戶號   
  40.   v_orderNo  VARCHAR2(20);--商戶訂單號   
  41.   v_orderState VARCHAR2(2);   
  42.   v_refAmount     NUMBER(15,2);--退款金額    
  43.   v_tranType  VARCHAR(2);--交易類型   
  44.   v_bank   VARCHAR2(10);--收單銀行   
  45.   v_date   VARCHAR2 (8);--交易日期   
  46.       v_time   VARCHAR2 (6);--交易時間   
  47.       v_datetime  VARCHAR2 (14);--獲取的系統時間   
  48.   v_index_start NUMBER;   
  49.   v_index_end  NUMBER;   
  50.   v_i    NUMBER;   
  51.  BEGIN   
  52.   -- 初始化參數   
  53.   out_visaInfoStr := '';   
  54.   v_i := 1;   
  55.   v_index_start := 1;   
  56.   v_index_end := INSTR(in_serialNoStr,'|',1,1);    
  57.   v_refserialno := SUBSTR(in_serialNoStr, v_index_start, v_index_end-1);   
  58.   v_datetime := TO_CHAR (SYSDATE, 'yyyymmddhh24miss');   
  59.   v_date := SUBSTR (v_datetime, 1, 8);   
  60.   v_time := SUBSTR (v_datetime, 9, 14);   
  61.   
  62.   --從退款請求表中查詢定單信息(商戶號、商戶訂單號、退款金額)   
  63.   WHILE v_index_end > 0 LOOP   
  64.    SELECT   
  65.     WEBR_MERNO,   
  66.     WEBR_ORDERNO,   
  67.     WEBR_AMOUNT,   
  68.     WEBR_SERIALNO,   
  69.     WEBR_REFUNDTYPE   
  70.    INTO   
  71.     v_merno,   
  72.     v_orderNo,   
  73.     v_refAmount,   
  74.     v_serialno,   
  75.     v_tranType   
  76.       FROM    
  77.     PY_WEB_REFUND   
  78.       WHERE    
  79.     WEBR_REFREQNO = v_refserialno;   
  80.       
  81.    --將查詢到的數據組成串   
  82.    out_visaInfoStr := out_visaInfoStr || v_merno || '~' || v_orderNo || '~' || v_refAmount + '|';   
  83.      
  84.    --爲下次循環做數據準備   
  85.       v_i := v_i + 1;   
  86.       v_index_start := v_index_end + 1;   
  87.       v_index_end := INSTR(in_serialNoStr,'|',1,v_i);   
  88.       IF v_index_end > 0 THEN   
  89.         v_refserialno := SUBSTR(in_serialNoStr, v_index_start, v_index_end - 1);         
  90.       END IF;   
  91.          
  92.    --根據原支付流水號在流水錶中查詢該訂單的信息,包括原上送銀行或第三方的訂單號:WTRN_TOBANKORDERNO   
  93.    SELECT   
  94.     WTRN_TOBANKORDERNO,   
  95.     WTRN_ORDERNO,   
  96.       WTRN_ORDERDATE,   
  97.       WTRN_BUSINESSTYPE,   
  98.     WTRN_A**BANK,   
  99.     WTRN_TRANCURRTYPE   
  100.    INTO   
  101.     v_tobankOrderNo,   
  102.     v_orderNo,   
  103.     v_orderDate,   
  104.     v_businessType,   
  105.     v_bank,   
  106.     v_currType   
  107.    FROM PY_WEBPAY_VIEW   
  108.     WHERE WTRN_SERIALNO = v_serialno;   
  109.        
  110.    --記錄流水錶(退款)   
  111.       INSERT INTO PY_WEBPAY_TRAN(   
  112.     WTRN_SERIALNO,   
  113.     WTRN_TRANTYPE,    
  114.     WTRN_ORIGSERIALNO,   
  115.     WTRN_ORDERNO,    
  116.     WTRN_ORDERDATE,    
  117.     WTRN_BUSINESSTYPE,   
  118.     WTRN_TRANCURRTYPE,   
  119.     WTRN_TRANAMOUNT,   
  120.     WTRN_A**BANK,    
  121.     WTRN_TRANSTATE,    
  122.     WTRN_TRANTIME,   
  123.     WTRN_TRANDATE,    
  124.     WTRN_MERNO,    
  125.     WTRN_TOBANKORDERNO   
  126.    )VALUES(   
  127.     v_refserialno, --和申請表的流水號相同,作爲參數傳人   
  128.     v_tranType,   
  129.     v_serialno, --原交易流水號,查詢退款申請表得到   
  130.     v_orderNo,   
  131.     v_orderDate,   
  132.     v_businessType,   
  133.     v_currType,   
  134.     v_refAmount,   
  135.     v_bank,   
  136.     '1',   
  137.     v_time,   
  138.     v_date,   
  139.     v_merno,   
  140.     v_tobankOrderNo --上送銀行的訂單號,查詢流水錶得到   
  141.    );   
  142.   
  143.    --更新網上退款申請表   
  144.    UPDATE PY_WEB_REFUND   
  145.    SET    
  146.     WEBR_IFDISPOSED = '1',   
  147.     WEBR_DISPOSEDOPR = in_session_operatorid,   
  148.     WEBR_DISPOSEDDATE = v_datetime   
  149.    WHERE    
  150.     WEBR_REFREQNO = v_refserialno;   
  151.       
  152.    --更新定單表   
  153.    IF v_tranType = '2' THEN   
  154.     v_orderState := '7';   
  155.    ELSE   
  156.     v_orderState := '10';   
  157.    END IF;   
  158.     
  159.    UPDATE PY_ORDER   
  160.    SET   
  161.     ORD_ORDERSTATE = v_orderState   
  162.    WHERE   
  163.      ORD_ORDERNO = v_orderNo   
  164.     AND ORD_ORDERDATE = v_orderDate   
  165.     AND ORD_BUSINESSTYPE = v_businessType;    
  166.   END LOOP;   
  167.     
  168.   -- 異常處理   
  169.   EXCEPTION   
  170.    WHEN OTHERS THEN   
  171.    ROLLBACK;   
  172.    out_return_code := '14001';   
  173.    RETURN;    
  174.  END;   
  175.   
  176. END PY_PCKG_REFUND2;   

發佈了51 篇原創文章 · 獲贊 0 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章