Oracle存储过程实例
Jun 07, 2016 pm 03:44 PMcreateorreplaceprocedureGetRecords(name_outoutvarchar2,age_ininvarchar2)as begin selectNAMEintoname_outfromtestwhereAGE=age_in; end; createorreplaceprocedureinsertRecord(UserIDinvarchar2,UserNameinvarchar2,UserAgeinvarchar2)is begin insert
- create or replace procedure GetRecords(name_out out varchar2,age_in in varchar2) as
- begin
- select NAME into name_out from test where AGE = age_in;
- end;
- create or replace procedure insertRecord(UserID in varchar2, UserName in varchar2,UserAge in varchar2) is
- begin
- insert into test values (UserID, UserName, UserAge);
- end;
Java代码
- create sequence TEST_SEQ
- minvalue 100
- maxvalue 999
- start with 102
- increment by 1
- nocache;
语法应该是比较易懂的,最小最大值分别用minvalue,maxvalue表示,初始值是102(这个数字是动态变化的,我创建的时候设的是100,后因插入了2条数据后就自动增加了2),increment当然就是步长了。在PL/SQL中可以用test_seq.nextval访问下一个序列号,用test_seq.currval访问当前的序列号。
定义完了Sequence,接下来就是创建一个存储过程InsertRecordWithSequence:
--这次我修改了test表的定义,和前面的示例不同。其中,UserID是PK。
Java代码
- create or replace procedure InsertRecordWithSequence(UserID out number,UserName in varchar2,UserAge in number)
- is
- begin insert into test(id, name, age) --插入一条记录,PK值从Sequece获取
- values(test_seq.nextval, UserName, UserAge);
- /*返回PK值。注意Dual表的用法*/
- select test_seq.currval into UserID from dual;
- end InsertRecordWithSequence;
为了让存储过程返回结果集,必须定义一个游标变量作为输出参数。这和Sql Server中有着很大的不同!并且还要用到Oracle中“包”(Package)的概念,似乎有点繁琐,但熟悉后也会觉得很方便。
关于“包”的概念,有很多内容可以参考,在此就不赘述了。首先,我创建了一个名为TestPackage的包,包头是这么定义的:
Java代码
- create or replace package TestPackage is
- type mycursor is ref cursor; -- 定义游标变量
- procedure GetRecords(ret_cursor out mycursor); -- 定义过程,用游标变量作为返回参数
- end TestPackage;
- 包体是这么定义的:
- create or replace package body TestPackage is
- /*过程体*/
- procedure GetRecords(ret_cursor out mycursor) as
- begin
- open ret_cursor for select * from test;
- end GetRecords;
- end TestPackage;
小结:
包是Oracle特有的概念,Sql Server中找不到相匹配的东西。在我看来,包有点像VC++的类,包头就是.h文件,包体就是.cpp文件。包头只负责定义,包体则负责具体实现。如果包返回多个游标,则DataReader会按照您向参数集合中添加它们的顺序来访问这些游标,而不是按照它们在过程中出现的顺序来访问。可使用DataReader的NextResult()方法前进到下一个游标。
Java代码
- create or replace package TestPackage is
- type mycursor is ref cursor;
- procedure UpdateRecords(id_in in number,newName in varchar2,newAge in number);
- procedure SelectRecords(ret_cursor out mycursor);
- procedure DeleteRecords(id_in in number);
- procedure InsertRecords(name_in in varchar2, age_in in number);
- end TestPackage;
包体如下:
Java代码
- create or replace package body TestPackage is
- procedure UpdateRecords(id_in in number, newName in varchar2, newAge in number) as
- begin
- update test set age = newAge, name = newName where id = id_in;
- end UpdateRecords;
- procedure SelectRecords(ret_cursor out mycursor) as
- begin
- open ret_cursor for select * from test;
- end SelectRecords;
- procedure DeleteRecords(id_in in number) as
- begin
- delete from test where id = id_in;
- end DeleteRecords;
- procedure InsertRecords(name_in in varchar2, age_in in number) as
- begin
- insert into test values (test_seq.nextval, name_in, age_in);
- --test_seq是一个已建的Sequence对象,请参照前面的示例
- end InsertRecords;
- 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_DA
例子:
BEGIN
SELECT col1,col2 into 变量1,变量2 FROM typestruct where xxx;
EXCEPTION
WHEN NO_DA
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代码
- CREATE OR REPLACE PACKAGE PY_PCKG_REFUND2 AS
- ------------------------------------------------------------------------
- -- Oracle 包
- ---国航支付平台VISA退款
- -- 游标定义:
- --
- -- 存储过程定义:
- -- PY_WEBREFUND_VISA_PREPARE : VISA退款准备
- -- 最后修改人:dougq
- -- 最后修改日期:2007.4.17
- ------------------------------------------------------------------------
- PROCEDURE PY_WEBREFUND_VISA_PREPARE (
- in_serialNoStr IN VARCHAR2, --用"|"隔开的一组网上退款申请流水号
- in_session_operatorid IN VARCHAR2, --业务操作员
- out_return_co
de OUT VARCHAR2, --存储过程返回码 - out_visaInfoStr OUT VARCHAR2
- );
- END PY_PCKG_REFUND2;
- /
- CREATE OR REPLACE PACKAGE BODY PY_PCKG_REFUND2 AS
- PROCEDURE PY_WEBREFUND_VISA_PREPARE (
- in_serialNoStr IN VARCHAR2, --用"|"隔开的一组网上退款申请流水号
- in_session_operatorid IN VARCHAR2,--业务操作员
- out_return_co
de OUT VARCHAR2, --存储过程返回码 - out_visaInfoStr OUT VARCHAR2
- ) IS
- --变量声明
- v_serialno VARCHAR2(20);--网上退款申请流水号
- v_refserialno VARCHAR2(20);--支付交易流水号
- v_tobankOrderNo VARCHAR2(30);--上送银行的订单号
- v_orderDate VARCHAR2(8);--订单日期
- v_businessType VARCHAR2(10);--业务类型
- v_currType VARCHAR2(3);--订单类型(ET-电子机票)
- v_merno VARCHAR2(15);--商户号
- v_orderNo VARCHAR2(20);--商户订单号
- v_orderState VARCHAR2(2);
- v_refAmount NUMBER(15,2);--退款金额
- v_tranType VARCHAR(2);--交易类型
- v_bank VARCHAR2(10);--收单银行
- v_date VARCHAR2 (8);--交易日期
- v_time VARCHAR2 (6);--交易时间
- v_datetime VARCHAR2 (14);--获取的系统时间
- v_index_start NUMBER;
- v_index_end NUMBER;
- v_i NUMBER;
- BEGIN
- -- 初始化参数
- out_visaInfoStr := '';
- v_i := 1;
- v_index_start := 1;
- v_index_end := INSTR(in_serialNoStr,'|',1,1);
- v_refserialno := SUBSTR(in_serialNoStr, v_index_start, v_index_end-1);
- v_datetime := TO_CHAR (SYSDATE, 'yyyymmddhh24miss');
- v_date := SUBSTR (v_datetime, 1, 8);
- v_time := SUBSTR (v_datetime, 9, 14);
- --从退款请求表中查询定单信息(商户号、商户订单号、退款金额)
- WHILE v_index_end > 0 LOOP
- SELECT
- WEBR_MERNO,
- WEBR_ORDERNO,
- WEBR_AMOUNT,
- WEBR_SERIALNO,
- WEBR_REFUNDTYPE
- INTO
- v_merno,
- v_orderNo,
- v_refAmount,
- v_serialno,
- v_tranType
- FROM
- PY_WEB_REFUND
- WHERE
- WEBR_REFREQNO = v_refserialno;
- --将查询到的数据组成串
- out_visaInfoStr := out_visaInfoStr || v_merno || '~' || v_orderNo || '~' || v_refAmount + '|';
- --为下次循环做数据准备
- v_i := v_i + 1;
- v_index_start := v_index_end + 1;
- v_index_end := INSTR(in_serialNoStr,'|',1,v_i);
- IF v_index_end > 0 THEN
- v_refserialno := SUBSTR(in_serialNoStr, v_index_start, v_index_end - 1);
- END IF;
- --根据原支付流水号在流水表中查询该订单的信息,包括原上送银行或第三方的订单号:WTRN_TOBANKORDERNO
- SELECT
- WTRN_TOBANKORDERNO,
- WTRN_ORDERNO,
- WTRN_ORDERDATE,
- WTRN_BUSINESSTYPE,
- WTRN_ACCPBANK,
- WTRN_TRANCURRTYPE
- INTO
- v_tobankOrderNo,
- v_orderNo,
- v_orderDate,
- v_businessType,
- v_bank,
- v_currType
- FROM PY_WEBPAY_VIEW
- WHERE WTRN_SERIALNO = v_serialno;
- --记录流水表(退款)
- INSERT INTO PY_WEBPAY_TRAN(
- WTRN_SERIALNO,
- WTRN_TRANTYPE,
- WTRN_ORIGSERIALNO,
- WTRN_ORDERNO,
- WTRN_ORDERDATE,
- WTRN_BUSINESSTYPE,
- WTRN_TRANCURRTYPE,
- WTRN_TRANAMOUNT,
- WTRN_ACCPBANK,
- WTRN_TRANSTATE,
- WTRN_TRANTIME,
- WTRN_TRANDATE,
- WTRN_MERNO,
- WTRN_TOBANKORDERNO
- )VALUES(
- v_refserialno, --和申请表的流水号相同,作为参数传人
- v_tranType,
- v_serialno, --原交易流水号,查询退款申请表得到
- v_orderNo,
- v_orderDate,
- v_businessType,
- v_currType,
- v_refAmount,
- v_bank,
- '1',
- v_time,
- v_date,
- v_merno,
- v_tobankOrderNo --上送银行的订单号,查询流水表得到
- );
- --更新网上退款申请表
- UPDATE PY_WEB_REFUND
- SET
- WEBR_IFDISPOSED = '1',
- WEBR_DISPOSEDOPR = in_session_operatorid,
- WEBR_DISPOSEDDATE = v_datetime
- WHERE
- WEBR_REFREQNO = v_refserialno;
- --更新定单表
- IF v_tranType = '2' THEN
- v_orderState := '7';
- ELSE
- v_orderState := '10';
- END IF;
- UPDATE PY_ORDER
- SET
- ORD_ORDERSTATE = v_orderState
- WHERE
- ORD_ORDERNO = v_orderNo
- AND ORD_ORDERDATE = v_orderDate
- AND ORD_BUSINESSTYPE = v_businessType;
- END LOOP;
- -- 异常处理
- EXCEPTION
- WHEN OTHERS THEN
- ROLLBACK;
- out_return_co
de := '14001'; - RETURN;
- END;
- END PY_PCKG_REFUND2;
- /

Artikel Panas

Alat panas Tag

Artikel Panas

Tag artikel panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas

Berfungsi untuk mengira bilangan hari antara dua tarikh dalam oracle

Berapa lama log pangkalan data Oracle akan disimpan?

Urutan langkah permulaan pangkalan data oracle ialah

Berapa banyak memori yang diperlukan oleh oracle?

Bagaimana untuk melihat bilangan kemunculan watak tertentu dalam Oracle

Keperluan konfigurasi perkakasan pelayan pangkalan data Oracle

Bagaimana untuk menggantikan rentetan dalam oracle
