日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Oracle存储过程(转)

發(fā)布時(shí)間:2023/12/10 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Oracle存储过程(转) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

存儲(chǔ)過程

  1??CREATE?OR?REPLACE?PROCEDURE?存儲(chǔ)過程名

  2??IS

  3??BEGIN

  4??NULL;

  5??END;

?

行1:

  CREATE?OR?REPLACE?PROCEDURE?是一個(gè)SQL語句通知Oracle數(shù)據(jù)庫(kù)去創(chuàng)建一個(gè)叫做skeleton存儲(chǔ)過程,?如果存在就覆蓋它;

行2:

  IS關(guān)鍵詞表明后面將跟隨一個(gè)PL/SQL體。

行3:

  BEGIN關(guān)鍵詞表明PL/SQL體的開始。

行4:

  NULL?PL/SQL語句表明什么事都不做,這句不能刪去,因?yàn)镻L/SQL體中至少需要有一句;

行5:

  END關(guān)鍵詞表明PL/SQL體的結(jié)束

存儲(chǔ)過程創(chuàng)建語法:

?create?or?replace?procedure?存儲(chǔ)過程名(param1?in?type,param2?out?type)?

as?

變量1?類型(值范圍);?--vs_msg???VARCHAR2(4000);?

變量2?類型(值范圍);

Begin

Select?count(*)?into?變量1?from?表A?where列名=param1;

?

????If?(判斷條件)?then

???????Select?列名?into?變量2?from?表A?where列名=param1;

???????Dbms_output。Put_line(‘打印信息’);

????Elsif?(判斷條件)?then

???????Dbms_output。Put_line(‘打印信息’);

????Else

???????Raise?異常名(NO_DATA_FOUND);

????End?if;

Exception

????When?others?then

???????Rollback;

End;

?

?

?

注意事項(xiàng):

1,?存儲(chǔ)過程參數(shù)不帶取值范圍,in表示傳入,out表示輸出

類型可以使用任意Oracle中的合法類型。

2,??變量帶取值范圍,后面接分號(hào)

3,??在判斷語句前最好先用count(*)函數(shù)判斷是否存在該條操作記錄

4,??用select?。。。into。。。給變量賦值

5,??在代碼中拋異常用?raise+異常名

?

CREATE?OR?REPLACE?PROCEDURE存儲(chǔ)過程名
(

--定義參數(shù)
?is_ym??IN?CHAR(6)?,

the_count?OUT?NUMBER,
)?
AS?
--定義變量?
vs_msg???VARCHAR2(4000);???--錯(cuò)誤信息變量
vs_ym_beg??CHAR(6);??????--起始月份
vs_ym_end??CHAR(6);??????--終止月份
vs_ym_sn_beg?CHAR(6);?????--同期起始月份
vs_ym_sn_end?CHAR(6);?????--同期終止月份

--定義游標(biāo)(簡(jiǎn)單的說就是一個(gè)可以遍歷的結(jié)果集)?


CURSOR?cur_1?IS?
??SELECT?。。。?
??FROM?。。。?
????WHERE?。。。
???GROUP?BY?。。。;?

BEGIN?


--用輸入?yún)?shù)給變量賦初值,用到了Oralce的SUBSTR?TO_CHAR?ADD_MONTHS?

?

TO_DATE?等很常用的函數(shù)。?
vs_ym_beg?:=?SUBSTR(is_ym,1,6);?
vs_ym_end?:=?SUBSTR(is_ym,7,6);?
vs_ym_sn_beg?:=?TO_CHAR(ADD_MONTHS(TO_DATE(vs_ym_beg,'yyyymm'),?-12),'yyyymm');?
vs_ym_sn_end?:=?TO_CHAR(ADD_MONTHS(TO_DATE(vs_ym_end,'yyyymm'),?-12),'yyyymm');?


--先刪除表中特定條件的數(shù)據(jù)。?


DELETE?FROM?表名?WHERE?ym?=?is_ym;?


??--然后用內(nèi)置的DBMS_OUTPUT對(duì)象的put_line方法打印出影響的記錄行數(shù),其中用到一個(gè)系統(tǒng)變量SQL%rowcount?


DBMS_OUTPUT.put_line('del上月記錄='||SQL%rowcount||'條');?

INSERT?INTO表名(area_code,ym,CMCODE,rmb_amt,usd_amt)?
SELECT?area_code,is_ym,CMCODE,SUM(rmb_amt)/10000,SUM(usd_amt)/10000?
FROM?BGD_AREA_CM_M_BASE_T?
??WHERE?ym?>=?vs_ym_beg?
??AND?ym?<=?vs_ym_end?
GROUP?BY?area_code,CMCODE;?

DBMS_OUTPUT.put_line('ins當(dāng)月記錄='||SQL%rowcount||'條');?
--遍歷游標(biāo)處理后更新到表。遍歷游標(biāo)有幾種方法,用for語句是其中比較直觀的一種。

?
FOR?rec?IN?cur_1?LOOP?
??UPDATE?表名
??SET?rmb_amt_sn?=?rec.rmb_amt_sn,usd_amt_sn?=?rec.usd_amt_sn?
???WHERE?area_code?=?rec.area_code?
???AND?CMCODE?=?rec.CMCODE?
???AND?ym?=?is_ym;?
END?LOOP;?

COMMIT;?


--錯(cuò)誤處理部分。OTHERS表示除了聲明外的任意錯(cuò)誤。SQLERRM是系統(tǒng)內(nèi)置變量保存了當(dāng)前錯(cuò)誤的詳細(xì)信息。?


EXCEPTION?


???WHEN?OTHERS?THEN?
??????vs_msg?:=?'ERROR?IN?xxxxxxxxxxx_p('||is_ym||'):'||SUBSTR(SQLERRM,1,500);

?
???ROLLBACK;?


???--把當(dāng)前錯(cuò)誤記錄進(jìn)日志表。?


???INSERT?INTO?LOG_INFO(proc_name,error_info,op_date)?
???VALUES('xxxxxxxxxxx_p',vs_msg,SYSDATE);?
???COMMIT;?
???RETURN;?


END;

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

oracle存儲(chǔ)過程語法

1?、判斷語句:?

if?比較式?then?begin?end;?end?if;?

create?or?replace?procedure?test(x?in?number)?is?

begin?

????????if?x?>0?then?

?????????begin?

????????x?:=?0?-?x;?

????????end;?

????end?if;?

????if?x?=?0?then?

???????begin?

????????x:?=?1;?

????end;?

????end?if;?

end?test;?

2?、For?循環(huán)?

For?...?in?...?LOOP?

--?執(zhí)行語句?

end?LOOP;?

(1)?循環(huán)遍歷游標(biāo)?

create?or?replace?procedure?test()?as?

Cursor?cursor?is?select?name?from?student;?name?varchar(20);?

begin?

for?name?in?cursor?LOOP?

begin?

?dbms_output.putline(name);??

end;?

end?LOOP;?

end?test;?

(2)?循環(huán)遍歷數(shù)組?

?create?or?replace?procedure?test(varArray?in?myPackage.TestArray)?as?

--(?輸入?yún)?shù)varArray?是自定義的數(shù)組類型,定義方式見標(biāo)題6)?

i?number;?

begin?

i?:=?1;??--?存儲(chǔ)過程數(shù)組是起始位置是從1?開始的,與java?、C?、C++?等語言不同。因?yàn)樵贠racle?中本是沒有數(shù)組的概念的,數(shù)組其實(shí)就是一張?

--?表(Table),?每個(gè)數(shù)組元素就是表中的一個(gè)記錄,所以遍歷數(shù)組時(shí)就相當(dāng)于從表中的第一條記錄開始遍歷?

for?i?in?1..varArray.count?LOOP??????

dbms_output.putline('The?No.'||?i?||?'record?in?varArray?is:'||varArray(i));????

?end?LOOP;?

end?test;?

3?、While?循環(huán)?

while?條件語句?LOOP?

begin?

end;?

end?LOOP;?

E.g?

create?or?replace?procedure?test(i?in?number)?as?

begin?

while?i?<?10?LOOP?

begin?????

?i:=?i?+?1;?

end;?

end?LOOP;?

?end?test;?

4?、數(shù)組?

首先明確一個(gè)概念:Oracle?中本是沒有數(shù)組的概念的,數(shù)組其實(shí)就是一張表(Table),?每個(gè)數(shù)組元素就是表中的一個(gè)記錄。?

使用數(shù)組時(shí),用戶可以使用Oracle?已經(jīng)定義好的數(shù)組類型,或可根據(jù)自己的需要定義數(shù)組類型。?

(1)?使用Oracle?自帶的數(shù)組類型?

x?array;?--?使用時(shí)需要需要進(jìn)行初始化?

e.g:?

create?or?replace?procedure?test(y?out?array)?is?

?x?array;???

?begin?

x?:=?new?array();?

y?:=?x;?

end?test;?

(2)?自定義的數(shù)組類型?(?自定義數(shù)據(jù)類型時(shí),建議通過創(chuàng)建Package?的方式實(shí)現(xiàn),以便于管理)?

create?or?replace?package?myPackage?is?

???Public?type?declarations???type?info?is?record(?????name?varchar(20),?????y?number);?

??type?TestArray?is?table?of?info?index?by?binary_integer;???

--?此處聲明了一個(gè)TestArray?的類型數(shù)據(jù),其實(shí)其為一張存儲(chǔ)Info?數(shù)據(jù)類型的Table?而已,及TestArray?就是一張表,有兩個(gè)字段,一個(gè)是name?,一個(gè)是y?。需要注意的是此處使用了Index?by?binary_integer?編制該Table?的索引項(xiàng),也可以不寫,直接寫成:type?TestArray?is?

table?of?info?,如果不寫的話使用數(shù)組時(shí)就需要進(jìn)行初始化:varArray?myPackage.TestArray;?varArray?:=?new?myPackage.TestArray();?

end?TestArray;?

5.?游標(biāo)的使用?Oracle?中Cursor?是非常有用的,用于遍歷臨時(shí)表中的查詢結(jié)果。其相關(guān)方法和屬性也很多,現(xiàn)僅就常用的用法做一二介紹:?

(1)Cursor?型游標(biāo)(?不能用于參數(shù)傳遞)?

create?or?replace?procedure?test()?is???

cusor_1?Cursor?is?select?std_name?from?student?where??...;??--Cursor?的使用方式1???cursor_2?Cursor;?

begin?

select?class_name?into?cursor_2?from?class?where?...;??--Cursor?的使用方式2?

可使用For?x?in?cursor?LOOP?....?end?LOOP;?來實(shí)現(xiàn)對(duì)Cursor?的遍歷?

end?test;?

(2)SYS_REFCURSOR?型游標(biāo),該游標(biāo)是Oracle?以預(yù)先定義的游標(biāo),可作出參數(shù)進(jìn)行傳遞?

create?or?replace?procedure?test(rsCursor?out?SYS_REFCURSOR)?is?

cursor?SYS_REFCURSOR;?

name?varhcar(20);?

begin?

OPEN?cursor?FOR?select?name?from?student?where?...?--SYS_REFCURSOR?只能通過OPEN?方法來打開和賦值?

LOOP?

?fetch?cursor?into?name???--SYS_REFCURSOR?只能通過fetch?into?來打開和遍歷?exit?when?cursor%NOTFOUND;??????????????--SYS_REFCURSOR?中可使用三個(gè)狀態(tài)屬性:?????????????????????????????????????????---%NOTFOUND(?未找到記錄信息)?%FOUND(?找到記錄信息)?????????????????????????????????????????---%ROWCOUNT(?然后當(dāng)前游標(biāo)所指向的行位置)?

?dbms_output.putline(name);?

end?LOOP;?

rsCursor?:=?cursor;?

end?test;?

?

?

?

實(shí)例

下面寫一個(gè)簡(jiǎn)單的例子來對(duì)以上所說的存儲(chǔ)過程的用法做一個(gè)應(yīng)用:?

現(xiàn)假設(shè)存在兩張表,一張是學(xué)生成績(jī)表(studnet)?,字段為:stdId,math,article,language,music,sport,total,average,step???????????????

一張是學(xué)生課外成績(jī)表(out_school),?字段為:stdId,parctice,comment?

通過存儲(chǔ)過程自動(dòng)計(jì)算出每位學(xué)生的總成績(jī)和平均成績(jī),同時(shí),如果學(xué)生在課外課程中獲得的評(píng)價(jià)為A?,就在總成績(jī)上加20?分。?

create?or?replace?procedure?autocomputer(step?in?number)?is?

rsCursor?SYS_REFCURSOR;?

commentArray?myPackage.myArray;?

math?number;?

article?number;?

language?number;?

music?number;?

sport?number;?

total?number;?

average?number;?

stdId?varchar(30);?

record?myPackage.stdInfo;?

i?number;?

begin?

i?:=?1;?

get_comment(commentArray);?--?調(diào)用名為get_comment()?的存儲(chǔ)過程獲取學(xué)生課外評(píng)分信息?

OPEN?rsCursor?for?select?stdId,math,article,language,music,sport?from?student?t?where?t.step?=?step;?

LOOP?

fetch?rsCursor?into?stdId,math,article,language,music,sport;?exit?when?rsCursor%NOTFOUND;?

total?:=?math?+?article?+?language?+?music?+?sport;?

for?i?in?1..commentArray.count?LOOP??

?record?:=?commentArray(i);?????

if?stdId?=?record.stdId?then???

?begin??????

?if?record.comment?=?'A'?then??????

??begin??????????

?total?:=?total?+?20;????

???go?to?next;?--?使用go?to?跳出for?循環(huán)????????

??end;?????

end?if;???

end;???

end?if;?

end?LOOP;?

<<continue>>??average?:=?total?/?5;?

?update?student?t?set?t.total=total?and?t.average?=?average?where?t.stdId?=?stdId;?

end?LOOP;?

end;?

end?autocomputer;?

--?取得學(xué)生評(píng)論信息的存儲(chǔ)過程?

create?or?replace?procedure?get_comment(commentArray?out?myPackage.myArray)?is?

rs?SYS_REFCURSOR?;?

record?myPackage.stdInfo;?

stdId?varchar(30);?

comment?varchar(1);?

i?number;?

begin?

open?rs?for?select?stdId,comment?from?out_school?

i?:=?1;?

LOOP?

?fetch?rs?into?stdId,comment;?exit?when?rs%NOTFOUND;?

record.stdId?:=?stdId;?

?record.comment?:=?comment;?

recommentArray(i)?:=?record;?

i:=i?+?1;?

end?LOOP;?

end?get_comment;?

--?定義數(shù)組類型myArray?

create?or?replace?package?myPackage?is?begin?

type?stdInfo?is?record(stdId?varchar(30),comment?varchar(1));?

type?myArray?is?table?of?stdInfo?index?by?binary_integer;?

end?myPackage;

轉(zhuǎn)載于:https://www.cnblogs.com/sotall/p/4366066.html

總結(jié)

以上是生活随笔為你收集整理的Oracle存储过程(转)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。