这段时间晚上有时候去打打球,回家看看电视剧,日子一天天过……。学了点ORACLE存储过程基础,作一下备注,以便日后需查阅。

创建无参存储过程

create procedure p_myPro1 is
begin
insert into dept(deptno,dname,loc) values(60,'ccx','');
end;

修改无参存储过程

create or replace procedure p_myPro1 is
begin
insert into dept(deptno,dname,loc) values(60,'ccx','');
end;

创建和修改有参存储过程

create or replace procedure p_myPro2(spName varchar2,newSal number) is
begin
update emp set sal=newSal where ename=spName;
end; call p_myPro2('SCOTT','');

创建和修改有参存储过程 带反回值

create or replace function f_myPro3(spName varchar2)
return number is
yearSal number(7,2);
begin
select sal*12 into yearSal from emp where ename=spName;
return yearSal;
end;

调用方法:select f_mypro3('SCOTT') from dual;

查看错误信息
 show error;

调用存储过程
调用存储过程的方式有两种,call,exec

exec是sqlplus的命令,只能在sqlplus中使用。和 set serveroutput on 一起用。call是sql命令,任何工具都可以使用。

例如:call p_myPro1()

Oracle输出语句过程

dbms_output是oracle所提供的包(类似java的开发包),该包包含一些过程,put_line就是dbms_output包的一个过程。

Oracle变量的使用例子 

declare
v_ename varchar2(5);
v_sal number(7,2);
begin
select ename,sal into v_ename,v_sal from emp where empno=7369;
dbms_output.put_line('姓名'||v_ename||' 工资'||v_sal);
end;

Oracle异常捕捉

declare
v_ename varchar2(5);
v_sal number(7,2);
begin
select ename,sal into v_ename,v_sal from emp where empno=1111;
dbms_output.put_line('姓名'||v_ename||' 工资'||v_sal); exception
when no_data_found then
dbms_output.put_line('SELECT INTO没有找到数据');
when not_logged_on then
dbms_output.put_line('没有连接到ORACLE'); end;

错误号

异常错误信息名称

说明

ORA-0001

Dup_val_on_index

违反了唯一性限制

ORA-0051

Timeout-on-resource

在等待资源时发生超时

ORA-0061

Transaction-backed-out

由于发生死锁事务被撤消

ORA-1001

Invalid-CURSOR

试图使用一个无效的游标

ORA-1012

Not-logged-on

没有连接到ORACLE

ORA-1017

Login-denied

无效的用户名/口令

ORA-1403

No_data_found

SELECT INTO没有找到数据

ORA-1422

Too_many_rows

SELECT INTO 返回多行

ORA-1476

Zero-divide

试图被零除

ORA-1722

Invalid-NUMBER

转换一个数字失败

ORA-6500

Storage-error

内存不够引发的内部错误

ORA-6501

Program-error

内部错误

ORA-6502

Value-error

转换或截断错误

ORA-6504

Rowtype-mismatch

宿主游标变量与 PL/SQL变量有不兼容行类型

ORA-6511

CURSOR-already-OPEN

试图打开一个已处于打开状态的游标

ORA-6530

Access-INTO-null

试图为null 对象的属性赋值

ORA-6531

Collection-is-null

试图将Exists 以外的集合( collection)方法应用于一个null pl/sql 表上或varray上

ORA-6532

Subscript-outside-limit

对嵌套或varray索引得引用超出声明范围以外

ORA-6533

Subscript-beyond-count

对嵌套或varray 索引得引用大于集合中元素的个数.

对这种异常情况的处理,只需在PL/SQL块的异常处理部分,直接引用相应的异常情况名,并对其完成相应的异常错误处理即可。

看存储过程示例:

这里通过IM_INSTOCK_D0.LOCNO%TYPE 取得表的类型

is下面的存储过程的变量,()里面是存储过程的参数

create or replace procedure P_IM_INSTOCK_M_AUDIT_LINE
(
as_LOCNO IM_INSTOCK_D0.LOCNO%TYPE, --仓别
as_OWNER_NO IM_INSTOCK_D0.OWNER_NO%TYPE, --委托业主
as_SHEET_ID IM_INSTOCK_D0.SHEET_ID%TYPE, --上架单号
as_SEQ_ID IM_INSTOCK_D0.SEQ_ID%TYPE, --上架单内序号
as_INSTOCK_WORKER IM_INSTOCK_D0.UPDT_NAME%TYPE, --上架人员
as_TerminalFlag container_content_move.terminal_flag%type, --作业设备
as_strMsg out varchar2 --错误信息返回
)
is ls_IMPORT_NO IM_INSTOCK_D0.IMPORT_NO%TYPE;
ls_CONTAINER_NO IM_INSTOCK_D0.CONTAINER_NO%TYPE;
ls_CELL_NO IM_INSTOCK_D0.DEST_CELL_NO%type; --源架储位
ls_CELL_ID IM_INSTOCK_D0.DEST_CELL_ID%type; --源架储位ID
ls_DEST_CELL_NO IM_INSTOCK_D0.DEST_CELL_NO%type; --预上架储位
ls_DEST_CELL_ID IM_INSTOCK_D0.DEST_CELL_ID%type; --预上架储位ID
ls_DEST_QTY IM_INSTOCK_D0.DEST_QTY%type; --预上架数量
ls_REAL_CELL_NO IM_INSTOCK_D0.REAL_CELL_NO%type; --实际上架储位
ls_REAL_CELL_ID IM_INSTOCK_D0.REAL_CELL_ID%type; --实际上架储位ID
ls_REAL_QTY IM_INSTOCK_D0.REAL_QTY%type; --实际上架数量
ls_Article_NO IM_INSTOCK_D0.ARTICLE_NO%TYPE;
li_Article_ID IM_INSTOCK_D0.ARTICLE_ID%TYPE;
ls_DepID IM_INSTOCK_M0.dept_id%type;
ls_Lot_No IM_INSTOCK_D0.Lot_No%type;
ls_errMsg varchar2(200); --错误信息
li_RowCount int;
li_MixFlag cm_defcell.mix_flag%TYPE;
li_MixBatch cm_defcell.mix_batch%TYPE;
ls_CellStatus cm_defcell.cell_status%TYPE;
ls_CellCheckStatus cm_defcell.check_status%TYPE;
ld_ProduceDate CONTAINER_ARTICLE_INFO.PRODUCE_DATE%TYPE;
ls_o_type cm_defarea.o_type%type; ls_AREA_HABITUDE CM_DEFAREA.AREA_HABITUDE%type;
ls_BUFFER_FLAG CM_DEFAREA.BUFFER_FLAG%type; ls_ERROR exception; --异常 begin --锁定当前表的行
update im_instock_d0 set status=status
where LOCNO=as_LOCNO and OWNER_NO=as_OWNER_NO and SHEET_ID=as_SHEET_ID and SEQ_ID=as_SEQ_ID and status in ('',''); IF SQL%ROWCOUNT=0 THEN
ls_errMsg:='更新此单失败';
raise ls_ERROR;
END IF; select IMD.CELL_NO,IMD.CELL_ID,DEST_CELL_NO,DEST_CELL_ID,DEST_QTY,REAL_CELL_NO,REAL_CELL_ID,REAL_QTY,IMD.CONTAINER_NO,
IMD.ARTICLE_NO,IMD.ARTICLE_ID,IMD.DEPT_ID,IMD.LOT_NO,IMD.IMPORT_NO
into ls_CELL_NO,ls_CELL_ID, ls_DEST_CELL_NO,ls_DEST_CELL_ID,ls_DEST_QTY,ls_REAL_CELL_NO,ls_REAL_CELL_ID,ls_REAL_QTY,
ls_CONTAINER_NO,ls_Article_NO,li_Article_ID,ls_DepID,ls_Lot_No,ls_IMPORT_NO
from IM_INSTOCK_D0 IMD,IM_INSTOCK_M0 IMM
where IMD.LOCNO=IMM.LOCNO AND IMD.OWNER_NO=IMM.OWNER_NO AND
IMD.SHEET_ID=IMM.SHEET_ID AND IMD.LOCNO=as_LOCNO and IMD.OWNER_NO=as_OWNER_NO
and IMD.SHEET_ID=as_SHEET_ID and IMD.SEQ_ID=as_SEQ_ID; IF ls_DEST_CELL_NO <> ls_REAL_CELL_NO THEN
BEGIN
select MIX_FLAG,MIX_BATCH,CELL_STATUS,CHECK_STATUS
into li_MixFlag,li_MixBatch,ls_CellStatus,ls_CellCheckStatus
from cm_defcell
where cell_no=ls_REAL_CELL_NO;
EXCEPTION WHEN NO_DATA_FOUND THEN
ls_errMsg :=ls_REAL_CELL_NO||'储位不存在';
raise ls_ERROR;
END;
if ls_CellStatus <> '' then
ls_errMsg :=ls_REAL_CELL_NO||'储位不可用吗,无法上架';
raise ls_ERROR;
end if;
if ls_CellCheckStatus <> '' then
ls_errMsg :=ls_REAL_CELL_NO||'在盘点中,无法上架';
raise ls_ERROR;
end if; IF li_MixFlag = '' THEN
select count(1) into li_RowCount
from container_content t1
where t1.locno=as_LOCNO and t1.cell_no = ls_REAL_CELL_NO
and ARTICLE_NO <> ls_Article_NO;
IF li_RowCount > 0 THEN
ls_errMsg :=ls_REAL_CELL_NO||'储位为不可混载储位,请重新指定储位上架';
raise ls_ERROR;
END IF;
END IF; IF li_MixBatch = '' THEN
select produce_date into ld_ProduceDate
from container_article_info
where article_id = li_Article_ID; select count(1) into li_RowCount
from container_content t1
where t1.locno=as_LOCNO and t1.cell_no = ls_REAL_CELL_NO
and ARTICLE_NO = ls_Article_NO
and not exists(select 1 from container_article_info t2
where t1.article_id=t2.article_id and t2.produce_date = ld_ProduceDate);
IF li_RowCount > 0 THEN
ls_errMsg :=ls_REAL_CELL_NO||'储位为不可混批储位,请重新指定储位上架';
raise ls_ERROR;
END IF;
END IF; END IF; update cm_defcell set cell_status=cell_status where cell_no=ls_REAL_CELL_NO and cell_status=0
and check_status=0; if SQL%ROWCOUNT=0 then
ls_errMsg:=ls_REAL_CELL_NO||'储位不存在或不可用';
raise ls_ERROR;
end if; begin
select t1.AREA_HABITUDE,t1.BUFFER_FLAG,t1.o_type into ls_AREA_HABITUDE,ls_BUFFER_FLAG,ls_o_type
from CM_DEFAREA t1,CM_DEFCELL t2
where t1.locno=t2.locno and t1.ware_no=t2.ware_no and t1.area_no=t2.area_no
and t2.locno=as_locno and t2.cell_no=ls_REAL_CELL_NO; IF ls_AREA_HABITUDE ='' THEN
ls_errMsg:=ls_REAL_CELL_NO||'所在储区为异常区,请核实';
raise ls_ERROR;
END IF; if ls_BUFFER_FLAG<>'' then
ls_errMsg:=ls_REAL_CELL_NO||'不是作业区';
raise ls_ERROR;
end if; if (ls_AREA_HABITUDE<>'' and ls_AREA_HABITUDE<>'' and ls_AREA_HABITUDE<>'') then
ls_errMsg:=ls_REAL_CELL_NO||'不是良品区或限制出货区';
raise ls_ERROR;
end if; end; P_BS_StockChangeLog(as_LOCNO,as_OWNER_NO,as_SHEET_ID,'',ls_CELL_NO,ls_CELL_ID,ls_REAL_CELL_NO,ls_REAL_CELL_ID,
ls_DepID,ls_Lot_No,ls_Article_NO,li_Article_ID,ls_REAL_QTY,as_INSTOCK_WORKER,as_TerminalFlag); if ls_DEST_CELL_NO<>ls_REAL_CELL_NO then P_BS_StockBackRevServ(as_LOCNO,as_OWNER_NO,ls_CELL_NO,ls_CELL_ID,ls_DEST_CELL_NO,ls_DEST_CELL_ID,ls_DEST_QTY,0,ls_DepID,as_INSTOCK_WORKER,as_strMsg);
if substr(as_strMsg,1,1)='N' then
ls_errMsg:='修改库存失败'|| SUBSTR(as_strMsg,3);
raise ls_ERROR;
end if; P_BS_StockChangePal(as_LOCNO,as_OWNER_NO,ls_CELL_NO,ls_CELL_ID, ls_REAL_CELL_NO,-1,ls_CONTAINER_NO,ls_DepID, ls_REAL_QTY,as_INSTOCK_WORKER,0,ls_REAL_CELL_ID,as_strMsg ); if substr(as_strMsg,1,1)='N' then
ls_errMsg:='转移库存失败'|| SUBSTR(as_strMsg,3);
raise ls_ERROR;
end if; update im_instock_d0 d set d.status='',d.real_cell_id=ls_REAL_CELL_ID,d.Updt_Name=as_INSTOCK_WORKER,
d.Updt_Date=sysdate where LOCNO=as_LOCNO and OWNER_NO=as_OWNER_NO
and SHEET_ID=as_SHEET_ID and SEQ_ID=as_SEQ_ID; else P_BS_StockBackRevServ(as_LOCNO,as_OWNER_NO,ls_CELL_NO,ls_CELL_ID,ls_DEST_CELL_NO,ls_DEST_CELL_ID,ls_DEST_QTY,ls_REAL_QTY,ls_DepID,as_INSTOCK_WORKER,as_strMsg); if substr(as_strMsg,1,1)='N' then
ls_errMsg:='修改库存失败' || SUBSTR(as_strMsg,3);
raise ls_ERROR;
end if; IF as_TerminalFlag=1 THEN ---表单
update im_instock_d0 d set d.status='',d.real_cell_id=d.dest_cell_id
where LOCNO=as_LOCNO and OWNER_NO=as_OWNER_NO
and SHEET_ID=as_SHEET_ID and SEQ_ID=as_SEQ_ID;
ELSE
update im_instock_d0 d set d.status='',d.real_cell_id=d.dest_cell_id,
d.Updt_Name=as_INSTOCK_WORKER, d.Updt_Date=sysdate
where LOCNO=as_LOCNO and OWNER_NO=as_OWNER_NO
and SHEET_ID=as_SHEET_ID and SEQ_ID=as_SEQ_ID;
END IF;
end if; P_BS_StockChangeListLog(as_LocNo,as_OWNER_NO,ls_DepID,ls_Article_NO,li_Article_ID,ls_Lot_No,ls_REAL_QTY,'','N');
/* P_CONTENTER_LOTNO(as_LOCNO,as_OWNER_NO,'100',ls_IMPORT_NO,ls_Article_NO,li_Article_ID,'N',0,ls_Lot_No,ls_REAL_QTY,0,as_INSTOCK_WORKER,as_strMsg);
if substr(as_strMsg,1,1)='N' then
raise ls_ERROR;
end if;
*/
update bm_article_pcs bm set bm.recent_cell=ls_REAL_CELL_NO,bm.recent_pickcell=
case when ls_o_type='P' then bm.recent_pickcell else ls_REAL_CELL_NO end where bm.OWNER_NO=as_OWNER_NO and bm.article_no=ls_Article_NO; ----更新标签表的状态
UPDATE CONTAINER_LABEL_M0 SET STATUS='' WHERE CONTAINER_NO=ls_CONTAINER_NO AND NOT EXISTS
(SELECT 1 FROM im_instock_d0 WHERE CONTAINER_NO=ls_CONTAINER_NO AND STATUS<''); IF SQL%ROWCOUNT<>0 THEN P_TRANS_CONTAINER_LABEL(as_locno,as_owner_no,ls_CONTAINER_NO,ls_errMsg); if substr(ls_errMsg,1,1)<>'Y' then
ls_errMsg:=SUBSTR(ls_errMsg,3);
raise ls_ERROR;
end if; END IF; --导入头档
insert into IM_INSTOCK_M(LOCNO, OWNER_NO, SHEET_ID, SHEET_TYPE,SHEET_DATE,DEPT_ID, AUTO_LOCATE_FLAG, ASSIGN_WORKER, ASSIGN_DATE,
REAL_WORKER, OPERATE_TYPE, STATUS, PRINT_TIMES, PRT_MEMO, BILL_MEMO,
AC_NO, RGST_NAME, RGST_DATE, UPDT_NAME, UPDT_DATE)
select LOCNO, OWNER_NO, SHEET_ID, SHEET_TYPE, SHEET_DATE, DEPT_ID, AUTO_LOCATE_FLAG, ASSIGN_WORKER, ASSIGN_DATE,
REAL_WORKER, OPERATE_TYPE,'' as STATUS, PRINT_TIMES, PRT_MEMO, BILL_MEMO,
SEQ_EOSBILL.NEXTVAL,RGST_NAME, RGST_DATE, UPDT_NAME, UPDT_DATE
from IM_INSTOCK_M0
where LOCNO=as_LOCNO and OWNER_NO=as_OWNER_NO and SHEET_ID=as_SHEET_ID
and not exists(select 'X' from IM_INSTOCK_d0
where LOCNO=as_LOCNO and OWNER_NO=as_OWNER_NO and SHEET_ID=as_SHEET_ID
and status<>'');
if SQL%ROWCOUNT<>0 then delete from IM_INSTOCK_M0 where LOCNO=as_LOCNO and OWNER_NO=as_OWNER_NO and SHEET_ID=as_SHEET_ID; --导入明细表
insert into IM_INSTOCK_D(LOCNO, OWNER_NO, SHEET_ID, SEQ_ID, CELL_NO, CELL_ID, CONTAINER_NO,
ARTICLE_NO, ARTICLE_ID, LOT_NO, SUPPLIER_NO,DEST_CELL_NO,DEST_CELL_ID, DEST_CONTAINER_NO,DEST_QTY,
REAL_CELL_NO, REAL_CELL_ID, REAL_CONTAINER_NO, REAL_QTY, IMPORT_NO, IMPORTSUM_NO, CHECK_NO,
WORKLOAD_P, WORKLOAD_C, WORKLOAD_B, STATUS,ROW_FLAG,LABEL_NO,DEPT_ID,UPDT_NAME,UPDT_DATE)
select LOCNO, OWNER_NO, SHEET_ID, SEQ_ID, CELL_NO, CELL_ID, CONTAINER_NO, ARTICLE_NO,
ARTICLE_ID, LOT_NO,SUPPLIER_NO, DEST_CELL_NO,DEST_CELL_ID, DEST_CONTAINER_NO,DEST_QTY, REAL_CELL_NO, REAL_CELL_ID,
REAL_CONTAINER_NO, REAL_QTY, IMPORT_NO, IMPORTSUM_NO, CHECK_NO, WORKLOAD_P, WORKLOAD_C, WORKLOAD_B,
'' as STATUS,ROW_FLAG,LABEL_NO,DEPT_ID,UPDT_NAME,UPDT_DATE
from IM_INSTOCK_D0
where LOCNO=as_LOCNO and OWNER_NO=as_OWNER_NO and SHEET_ID=as_SHEET_ID ;
if SQL%ROWCOUNT<>0 then
delete from IM_INSTOCK_D0 where LOCNO=as_LOCNO and OWNER_NO=as_OWNER_NO and SHEET_ID=as_SHEET_ID;
end if;
end if; as_strMsg:='Y|成功';
--异常处理
exception
WHEN ls_ERROR THEN
as_strMsg:='N|'||ls_errMsg;
when others then
as_strMsg:='N|' || to_char(SQLCODE) || ' ' || SUBSTR(SQLERRM, 1, 100);
end P_IM_INSTOCK_M_AUDIT_LINE;

Oracle- 存储过程和异常捕捉的更多相关文章

  1. Oracle存储过程中异常Exception的捕捉和处理

    Oracle存储过程中异常的捕捉和处理 CREATE OR REPLACE Procedure Proc_error_process ( v_IN in Varchar2, v_OUT Out Var ...

  2. oracle存储过程获取异常信息码和异常信息

    oracle存储过程,可以通过sqlcode 获取异常编码.通过sqlerrm获取异常信息. 例子: create or replace procedure write2blob(p_id in nu ...

  3. Oracle存储过程记录异常

    --建立错误日志表 create table PUB_PROC_ERR_LOG ( LOG_ID NUMBER, MODULE_NAME ), PROC_NAME ), ERR_TIME DATE, ...

  4. Oracle存储过程记录异常日志

    一般我们会将一些涉及到数据库的定时任务直接用存储过程搞定,省去了后端代码的开发.部署,简单.快速,但这种方式存在一个弊端——当存储过程执行出错了,我们无法感知.解决办法也简单,学代码那样去捕获异常.打 ...

  5. Oracle 存储过程学习

    转自:http://blog.chinaunix.net/uid-20495387-id-174394.html http://www.cnblogs.com/rootq/articles/11000 ...

  6. Oracle 存储过程异常处理

    Oracle 存储过程异常处理 1.异常的优点    如果没有异常,在程序中,应当检查每个命令的成功还是失败,如  BEGIN  SELECT ...  -- check for ’no data f ...

  7. Oracle 存储过程使用总结

    参考 https://blog.csdn.net/weixin_41968788/article/details/83659164/ 创建 注意:一定不要漏掉了语句末尾的分号 DBMS_OUTPUT. ...

  8. oracle 存储过程

    来自:http://www.jb51.net/article/31805.htm Oracle存储过程基本语法 存储过程 1 CREATE OR REPLACE PROCEDURE 存储过程名 2 I ...

  9. Oracle存储过程语法

    原文链接:http://www.jb51.net/article/31805.htm Oracle存储过程基本语法 存储过程  1 CREATE OR REPLACE PROCEDURE 存储过程名  ...

随机推荐

  1. Silverlight之Styles和Behaviors

    本文简介 1.定义简单的Style 2.应用Style到元素 3.动态加载Style资源文件 4.Style的继承 5.组织内编写Style(在元素内) 6.自动应用Style到指定类型元素 7.St ...

  2. 区分jquery中的offset和position

    一次又一次地碰到需要获取元素位置的问题, 然后一次又一次地查offset和position的区别. 忍不了了, 这次一定得想办法记下来. position是元素相对于父元素的位置. 这个好记, par ...

  3. 【算法】 输入n 输出一个n*n的zigzag矩阵 利用c++实现

    int main() { int N; cin>>N; int **a = new int *[N]; ) ;//如果没有申请到空间 ;i<N;i++) { a[i]= new in ...

  4. Android开发之自定义组合控件

    自定义组合控件的步骤1.自定义一个View,继承ViewGroup,比如RelativeLayout2.编写组合控件的布局文件,在自定义的view中加载(使用View.inflate())3.自定义属 ...

  5. 设计模式 - interpreter

    interpreter模式在GOF中的定义是:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子. 定义看起来是非常晦涩.简单来讲,解释器模式通常用于处理特 ...

  6. bzoj1857

    三分的入门题,如果从AB上一点走到D是一个单峰函数从AB开始向CD传送带走的那个点也是一个单峰函数显然三分套三分 const eps=1e-5; var ax,ay,bx,by,cx,cy,dx,dy ...

  7. UVa 201 Squares

    题意: 给出这样一个图,求一共有多少个大小不同或位置不同的正方形. 分析: 这种题一看就有思路,最开始的想法就是枚举正方形的位置,需要二重循环,枚举边长一重循环,判断是否为正方形又需要一重循环,复杂度 ...

  8. [swustoj 1021] Submissions of online judge

    Submissions of online judge(1021) 问题描述 An online judge is a system to test programs in programming c ...

  9. (九)学习CSS之margin属性

    参考: 所有浏览器都支持 margin 属性. 注释:任何的版本的 Internet Explorer (包括 IE8)都不支持属性值 "inherit". 定义和用法 margi ...

  10. 我的Modbus Slave/Client开发历程(Rtu/AscII/Tcp)

    我的Modbus Slave/Client开发历程(Rtu/AscII/Tcp) 分类: [自动化]2007-07-19 10:04 34038人阅读 评论(38) 收藏 举报 vb嵌入式dostcp ...