首頁 資料庫 mysql教程 Oracle存储过程实例

Oracle存储过程实例

Jun 07, 2016 pm 03:44 PM
oracle 儲存 實例 過程

createorreplaceprocedureGetRecords(name_outoutvarchar2,age_ininvarchar2)as begin selectNAMEintoname_outfromtestwhereAGE=age_in; end; createorreplaceprocedureinsertRecord(UserIDinvarchar2,UserNameinvarchar2,UserAgeinvarchar2)is begin insert

  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语句如下:

Java代码 Oracle存储过程实例

  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。

Java代码 Oracle存储过程实例

  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的包,包头是这么定义的:

Java代码 Oracle存储过程实例

  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()方法前进到下一个游标。

Java代码 Oracle存储过程实例

  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;   

包体如下:

Java代码 Oracle存储过程实例

  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不大一样,花费了一下午的时间写了一个出来,测试编译通过了,是为记,以备以后查阅。

Java代码 Oracle存储过程实例

  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_ACCPBANK,   
  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_ACCPBANK,    
  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;   
  177. /  
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

oracle打不開怎麼辦 oracle打不開怎麼辦 Apr 11, 2025 pm 10:06 PM

Oracle 打不開的解決辦法包括:1. 啟動數據庫服務;2. 啟動監聽器;3. 檢查端口衝突;4. 正確設置環境變量;5. 確保防火牆或防病毒軟件未阻止連接;6. 檢查服務器是否已關閉;7. 使用 RMAN 恢復損壞的文件;8. 檢查 TNS 服務名稱是否正確;9. 檢查網絡連接;10. 重新安裝 Oracle 軟件。

oracle游標關閉怎麼解決 oracle游標關閉怎麼解決 Apr 11, 2025 pm 10:18 PM

解決 Oracle 游標關閉問題的方法包括:使用 CLOSE 語句顯式關閉游標。在 FOR UPDATE 子句中聲明游標,使其在作用域結束後自動關閉。在 USING 子句中聲明游標,使其在關聯的 PL/SQL 變量關閉時自動關閉。使用異常處理確保在任何異常情況下關閉游標。使用連接池自動關閉游標。禁用自動提交,延遲游標關閉。

oracle怎麼循環創建游標 oracle怎麼循環創建游標 Apr 12, 2025 am 06:18 AM

Oracle 中,FOR LOOP 循環可動態創建游標, 步驟為:1. 定義游標類型;2. 創建循環;3. 動態創建游標;4. 執行游標;5. 關閉游標。示例:可循環創建游標,顯示前 10 名員工姓名和工資。

oracle數據庫怎麼停止 oracle數據庫怎麼停止 Apr 12, 2025 am 06:12 AM

要停止 Oracle 數據庫,請執行以下步驟:1. 連接到數據庫;2. 優雅關機數據庫(shutdown immediate);3. 完全關機數據庫(shutdown abort)。

HDFS配置CentOS需要哪些步驟 HDFS配置CentOS需要哪些步驟 Apr 14, 2025 pm 06:42 PM

在CentOS系統上搭建Hadoop分佈式文件系統(HDFS)需要多個步驟,本文提供一個簡要的配置指南。一、前期準備安裝JDK:在所有節點上安裝JavaDevelopmentKit(JDK),版本需與Hadoop兼容。可從Oracle官網下載安裝包。環境變量配置:編輯/etc/profile文件,設置Java和Hadoop的環境變量,使系統能夠找到JDK和Hadoop的安裝路徑。二、安全配置:SSH免密登錄生成SSH密鑰:在每個節點上使用ssh-keygen命令

oracle日誌寫滿怎麼辦 oracle日誌寫滿怎麼辦 Apr 12, 2025 am 06:09 AM

Oracle 日誌文件寫滿時,可採用以下解決方案:1)清理舊日誌文件;2)增加日誌文件大小;3)增加日誌文件組;4)設置自動日誌管理;5)重新初始化數據庫。在實施任何解決方案前,建議備份數據庫以防數據丟失。

甲骨文在商業世界中的作用 甲骨文在商業世界中的作用 Apr 23, 2025 am 12:01 AM

Oracle不僅是數據庫公司,還是雲計算和ERP系統的領導者。 1.Oracle提供從數據庫到雲服務和ERP系統的全面解決方案。 2.OracleCloud挑戰AWS和Azure,提供IaaS、PaaS和SaaS服務。 3.Oracle的ERP系統如E-BusinessSuite和FusionApplications幫助企業優化運營。

oracle動態sql怎麼創建 oracle動態sql怎麼創建 Apr 12, 2025 am 06:06 AM

可以通過使用 Oracle 的動態 SQL 來根據運行時輸入創建和執行 SQL 語句。步驟包括:準備一個空字符串變量來存儲動態生成的 SQL 語句。使用 EXECUTE IMMEDIATE 或 PREPARE 語句編譯和執行動態 SQL 語句。使用 bind 變量傳遞用戶輸入或其他動態值給動態 SQL。使用 EXECUTE IMMEDIATE 或 EXECUTE 執行動態 SQL 語句。

See all articles