這段時間晚上有時候去打打球,回家看看電視劇,日子一每天過……。學了點ORACLE存儲過程基礎,做一下備註,以便往後需查閱。java
建立無參存儲過程sql
create procedure p_myPro1 is begin insert into dept(deptno,dname,loc) values(60,'ccx','321321'); end;
修改無參存儲過程oracle
create or replace procedure p_myPro1 is begin insert into dept(deptno,dname,loc) values(60,'ccx','321321'); end;
建立和修改有參存儲過程ide
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','1111');
建立和修改有參存儲過程 帶反回值工具
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;spa
查看錯誤信息
show error;code
調用存儲過程
調用存儲過程的方式有兩種,call,execserver
exec是sqlplus的命令,只能在sqlplus中使用。和 set serveroutput on 一塊兒用。call是sql命令,任何工具均可以使用。對象
例如:call p_myPro1() blog
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 ('10','11'); 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 <> '0' then ls_errMsg :=ls_REAL_CELL_NO||'儲位不可用嗎,沒法上架'; raise ls_ERROR; end if; if ls_CellCheckStatus <> '0' then ls_errMsg :=ls_REAL_CELL_NO||'在盤點中,沒法上架'; raise ls_ERROR; end if; IF li_MixFlag = '0' 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 = '0' 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 ='7' THEN ls_errMsg:=ls_REAL_CELL_NO||'所在儲區爲異常區,請覈實'; raise ls_ERROR; END IF; if ls_BUFFER_FLAG<>'0' then ls_errMsg:=ls_REAL_CELL_NO||'不是做業區'; raise ls_ERROR; end if; if (ls_AREA_HABITUDE<>'1' and ls_AREA_HABITUDE<>'20' and ls_AREA_HABITUDE<>'6') then ls_errMsg:=ls_REAL_CELL_NO||'不是良品區或限制出貨區'; raise ls_ERROR; end if; end; P_BS_StockChangeLog(as_LOCNO,as_OWNER_NO,as_SHEET_ID,'100',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='13',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='13',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='13',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,'100','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='13' WHERE CONTAINER_NO=ls_CONTAINER_NO AND NOT EXISTS (SELECT 1 FROM im_instock_d0 WHERE CONTAINER_NO=ls_CONTAINER_NO AND STATUS<'13'); 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,'13' 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<>'13'); 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, '13' 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;