• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

Oracle存储过程实例

mysql 搞代码 4年前 (2022-01-09) 128次浏览 已收录 0个评论

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. create or replace procedure insertRecord(UserID in varchar2, UserName in varchar2,UserAge in varchar2) is
  6. begin
  7. insert into test values (UserID, UserName, UserAge);
  8. end;

首先,在Oracle中创建了一个名为TEST_SEQ的Sequence对象,SQL语句如下:

Java代码

  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代码

  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代码

  1. create or replace package TestPackage is
  2. type mycursor is ref cursor; — 定义游标变量
  3. procedure GetRecords(ret_cursor out mycursor); — 定义过程,用游标变量作为返回参数
  4. end TestPackage; 本文来源gao@dai!ma.com搞$代^码!网7
  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代码

  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代码

  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. procedure SelectRecords(ret_cursor out mycursor) as
  7. begin
  8. open ret_cursor for select * from test;
  9. end SelectRecords;
  10. procedure DeleteRecords(id_in in number) as
  11. begin
  12. delete from test where id = id_in;
  13. end DeleteRecords;
  14. procedure InsertRecords(name_in in varchar2, age_in in number) as
  15. begin
  16. insert into test values (test_seq.nextval, name_in, age_in);
  17. –test_seq是一个已建的Sequence对象,请参照前面的示例
  18. end InsertRecords;
  19. 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代码

  1. CREATE OR REPLACE PACKAGE PY_PCKG_REFUND2 AS
  2. ————————————————————————
  3. — Oracle 包
  4. —国航支付平台VISA退款
  5. — 游标定义:
  6. — 存储过程定义:
  7. — PY_WEBREFUND_VISA_PREPARE : VISA退款准备
  8. — 最后修改人:dougq
  9. — 最后修改日期:2007.4.17
  10. ————————————————————————
  11. PROCEDURE PY_WEBREFUND_VISA_PREPARE (
  12. in_serialNoStr IN VARCHAR2, –用”|”隔开的一组网上退款申请流水号
  13. in_session_operatorid IN VARCHAR2, –业务操作员
  14. out_return_code OUT VARCHAR2, –存储过程返回码
  15. out_visaInfoStr OUT VARCHAR2
  16. );
  17. END PY_PCKG_REFUND2;
  18. /
  19. CREATE OR REPLACE PACKAGE BODY PY_PCKG_REFUND2 AS
  20. PROCEDURE PY_WEBREFUND_VISA_PREPARE (
  21. in_serialNoStr IN VARCHAR2, –用”|”隔开的一组网上退款申请流水号
  22. in_session_operatorid IN VARCHAR2,–业务操作员
  23. out_return_code OUT VARCHAR2, –存储过程返回码
  24. out_visaInfoStr OUT VARCHAR2
  25. ) IS
  26. –变量声明
  27. v_serialno VARCHAR2(20);–网上退款申请流水号
  28. v_refserialno VARCHAR2(20);–支付交易流水号
  29. v_tobankOrderNo VARCHAR2(30);–上送银行的订单号
  30. v_orderDate VARCHAR2(8);–订单日期
  31. v_businessType VARCHAR2(10);–业务类型
  32. v_currType VARCHAR2(3);–订单类型(ET-电子机票)
  33. v_merno VARCHAR2(15);–商户号
  34. v_orderNo VARCHAR2(20);–商户订单号
  35. v_orderState VARCHAR2(2);
  36. v_refAmount NUMBER(15,2);–退款金额
  37. v_tranType VARCHAR(2);–交易类型
  38. v_bank VARCHAR2(10);–收单银行
  39. v_date VARCHAR2 (8);–交易日期
  40. v_time VARCHAR2 (6);–交易时间
  41. v_datetime VARCHAR2 (14);–获取的系统时间
  42. v_index_start NUMBER;
  43. v_index_end NUMBER;
  44. v_i NUMBER;
  45. BEGIN
  46. — 初始化参数
  47. out_visaInfoStr := ”;
  48. v_i := 1;
  49. v_index_start := 1;
  50. v_index_end := INSTR(in_serialNoStr,’|’,1,1);
  51. v_refserialno := SUBSTR(in_serialNoStr, v_index_start, v_index_end-1);
  52. v_datetime := TO_CHAR (SYSDATE, ‘yyyymmddhh24miss’);
  53. v_date := SUBSTR (v_datetime, 1, 8);
  54. v_time := SUBSTR (v_datetime, 9, 14);
  55. –从退款请求表中查询定单信息(商户号、商户订单号、退款金额)
  56. WHILE v_index_end > 0 LOOP
  57. SELECT
  58. WEBR_MERNO,
  59. WEBR_ORDERNO,
  60. WEBR_AMOUNT,
  61. WEBR_SERIALNO,
  62. WEBR_REFUNDTYPE
  63. INTO
  64. v_merno,
  65. v_orderNo,
  66. v_refAmount,
  67. v_serialno,
  68. v_tranType
  69. FROM
  70. PY_WEB_REFUND
  71. WHERE
  72. WEBR_REFREQNO = v_refserialno;
  73. –将查询到的数据组成串
  74. out_visaInfoStr := out_visaInfoStr || v_merno || ‘~’ || v_orderNo || ‘~’ || v_refAmount + ‘|’;
  75. –为下次循环做数据准备
  76. v_i := v_i + 1;
  77. v_index_start := v_index_end + 1;
  78. v_index_end := INSTR(in_serialNoStr,’|’,1,v_i);
  79. IF v_index_end > 0 THEN
  80. v_refserialno := SUBSTR(in_serialNoStr, v_index_start, v_index_end – 1);
  81. END IF;
  82. –根据原支付流水号在流水表中查询该订单的信息,包括原上送银行或第三方的订单号:WTRN_TOBANKORDERNO
  83. SELECT
  84. WTRN_TOBANKORDERNO,
  85. WTRN_ORDERNO,
  86. WTRN_ORDERDATE,
  87. WTRN_BUSINESSTYPE,
  88. WTRN_ACCPBANK,
  89. WTRN_TRANCURRTYPE
  90. INTO
  91. v_tobankOrderNo,
  92. v_orderNo,
  93. v_orderDate,
  94. v_businessType,
  95. v_bank,
  96. v_currType
  97. FROM PY_WEBPAY_VIEW
  98. WHERE WTRN_SERIALNO = v_serialno;
  99. –记录流水表(退款)
  100. INSERT INTO PY_WEBPAY_TRAN(
  101. WTRN_SERIALNO,
  102. WTRN_TRANTYPE,
  103. WTRN_ORIGSERIALNO,
  104. WTRN_ORDERNO,
  105. WTRN_ORDERDATE,
  106. WTRN_BUSINESSTYPE,
  107. WTRN_TRANCURRTYPE,
  108. WTRN_TRANAMOUNT,
  109. WTRN_ACCPBANK,
  110. WTRN_TRANSTATE,
  111. WTRN_TRANTIME,
  112. WTRN_TRANDATE,
  113. WTRN_MERNO,
  114. WTRN_TOBANKORDERNO
  115. )VALUES(
  116. v_refserialno, –和申请表的流水号相同,作为参数传人
  117. v_tranType,
  118. v_serialno, –原交易流水号,查询退款申请表得到
  119. v_orderNo,
  120. v_orderDate,
  121. v_businessType,
  122. v_currType,
  123. v_refAmount,
  124. v_bank,
  125. ‘1’,
  126. v_time,
  127. v_date,
  128. v_merno,
  129. v_tobankOrderNo –上送银行的订单号,查询流水表得到
  130. );
  131. –更新网上退款申请表
  132. UPDATE PY_WEB_REFUND
  133. SET
  134. WEBR_IFDISPOSED = ‘1’,
  135. WEBR_DISPOSEDOPR = in_session_operatorid,
  136. WEBR_DISPOSEDDATE = v_datetime
  137. WHERE
  138. WEBR_REFREQNO = v_refserialno;
  139. –更新定单表
  140. IF v_tranType = ‘2’ THEN
  141. v_orderState := ‘7’;
  142. ELSE
  143. v_orderState := ’10’;
  144. END IF;
  145. UPDATE PY_ORDER
  146. SET
  147. ORD_ORDERSTATE = v_orderState
  148. WHERE
  149. ORD_ORDERNO = v_orderNo
  150. AND ORD_ORDERDATE = v_orderDate
  151. AND ORD_BUSINESSTYPE = v_businessType;
  152. END LOOP;
  153. — 异常处理
  154. EXCEPTION
  155. WHEN OTHERS THEN
  156. ROLLBACK;
  157. out_return_code := ‘14001’;
  158. RETURN;
  159. END;
  160. END PY_PCKG_REFUND2;
  161. /

搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Oracle存储过程实例

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址