oracle存儲過程、聲明變量、for循環 html
一、建立存儲過程java
create or replace procedure test(var_name_1 in type,var_name_2 out type) asnode
--聲明變量(變量名 變量類型)數組
beginoracle
--存儲過程的執行體ide
end test;函數
打印出輸入的時間信息oop
E.g:post
create or replace procedure test(workDate in Date) is測試
begin
dbms_output.putline('The input date is:'||to_date(workDate,'yyyy-mm-dd'));
end test;
二、變量賦值
變量名 := 值;
E.g:
create or replace procedure test(workDate in Date) is
x number(4,2);
begin
x := 1;
end test;
三、判斷語句:
if 比較式 then begin end; end if;
E.g
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;
四、For 循環
For ... in ... LOOP
--執行語句
end LOOP;
(1)循環遍歷遊標
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)循環遍歷數組
create or replace procedure test(varArray in myPackage.TestArray) as
--(輸入參數varArray 是自定義的數組類型,定義方式見標題6)
i number;
begin
i := 1; --存儲過程數組是起始位置是從1開始的,與java、C、C++等語言不一樣。由於在Oracle中本是沒有數組的概念的,數組其實就是一張
--表(Table),每一個數組元素就是表中的一個記錄,因此遍歷數組時就至關於從表中的第一條記錄開始遍歷
for i in 1..varArray.count LOOP
dbms_output.putline('The No.'|| i || 'record in varArray is:'||varArray(i));
end LOOP;
end test;
五、While 循環
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;
六、數組
首先明確一個概念:Oracle中本是沒有數組的概念的,數組其實就是一張表(Table),每一個數組元素就是表中的一個記錄。
使用數組時,用戶可使用Oracle已經定義好的數組類型,或可根據本身的須要定義數組類型。
(1)使用Oracle自帶的數組類型
x array; --使用時須要須要進行初始化
e.g:
create or replace procedure test(y out array) is
x array;
begin
x := new array();
y := x;
end test;
(2)自定義的數組類型 (自定義數據類型時,建議經過建立Package的方式實現,以便於管理)
E.g (自定義使用參見標題4.2) 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; --此處聲明瞭一個TestArray的類型數據,其實其爲一張存儲Info數據類型的Table而已,及TestArray 就是一張表,有兩個字段,一個是
name,一個是y。須要注意的是此處使用了Index by binary_integer 編制該Table的索引項,也能夠不寫,直接寫成:type TestArray is
table of info,若是不寫的話使用數組時就須要進行初始化:varArray myPackage.TestArray; varArray := new myPackage.TestArray();
end TestArray;
7.遊標的使用
Oracle中Cursor是很是有用的,用於遍歷臨時表中的查詢結果。其相關方法和屬性也不少,現僅就經常使用的用法作一二介紹:
(1)Cursor型遊標(不能用於參數傳遞)
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; 來實現對Cursor的遍歷
end test;
(2)SYS_REFCURSOR型遊標,該遊標是Oracle以預先定義的遊標,可做出參數進行傳遞
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中可以使用三個狀態屬性: ---%NOTFOUND(未找到記錄信息) %FOUND(找到記錄信息) ---%ROWCOUNT(而後當前遊標所指向的行位置)
dbms_output.putline(name);
end LOOP;
rsCursor := cursor;
end test;
下面寫一個簡單的例子來對以上所說的存儲過程的用法作一個應用:
現假設存在兩張表,一張是學生成績表(studnet),字段爲:stdId,math,article,language,music,sport,total,average,step 一張是學生課外成績表(out_school),字段爲:stdId,parctice,comment
經過存儲過程自動計算出每位學生的總成績和平均成績,同時,若是學生在課外課程中得到的評價爲A,就在總成績上加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); --調用名爲get_comment()的存儲過程獲取學生課外評分信息
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循環
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;
--取得學生評論信息的存儲過程
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;
--定義數組類型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;
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/squirrelrao/archive/2008/07/11/2639571.aspx https://www.cnblogs.com/yw0219/p/5939558.html
應用:
oracle遊標,存儲過程,for循環,loop合一
create or replace procedure libsys.add_money(money out number) ascursor cur is
select amount from libsys.money_record;
begin
money:=0;
for amounts in cur
loop
money:=money+amounts;
end loop;
end add_money;
本身使用過的案列
declare --類型定義 cursor c_sursorA is select node_id,flow_id from itouch_workflow.FLOW_NODES where node_name='不予許可通知'; --定義一個遊標變量v_cinfo c_emp%ROWTYPE ,該類型爲遊標c_emp中的一行數據類型 c_row c_sursorA%rowtype; begin for c_row in c_sursorA loop INSERT into itouch_workflow.FLOW_NODE_RESULTS(node_id,result_item_id,result_item_alias,id) values(c_row.node_id,'3','不予許可',RAWTOHEX(sys_guid())); dbms_output.put_line(c_row.node_id); DBMS_OUTPUT.ENABLE(buffer_size => null) ; end loop; end;
2
DECLARE CURSOR c_job9 IS select DISTINCT(ent_code) from ( select distinct t.* from ent_license t inner join ent_license f on t.ent_code = f.ent_code where t.lic_code <> f.lic_code and t.ent_code is not null order by t.ent_code ) where ROWNUM<810; --定義一個遊標變量v_cinfo c_emp%ROWTYPE ,該類型爲遊標c_emp中的一行數據類型 c_row c_job9 % rowtype ; BEGIN FOR c_row IN c_job9 loop --dbms_output.put_line (c_row.ENT_CODE) ; declare i int ; j int :=1; typez nvarchar2(100); IDZ nvarchar2(100); typenum int :=1; typeentcode nvarchar2(50); begin dbms_output.put_line (c_row.ENT_CODE) ; typeentcode :=sys_guid(); SELECT count(*) into i FROM ITOUCH_FDA_ENT.ENT_TYPE_RELATION T WHERE T.ENT_CODE = c_row.ENT_CODE; SELECT count(*) into j FROM ITOUCH_FDA_ENT.ENT_LICENSE T WHERE T.ENT_CODE = c_row.ENT_CODE; if(j=2) then begin if(i=2) then begin dbms_output.put_line(i||'*****'||j); dbms_output.put_line (c_row.ENT_CODE) ; --處理代碼塊 SELECT SUBSTR (ENT_TYPE_ID,1,4) into typez FROM ITOUCH_FDA_ENT.ENT_LICENSE T WHERE T.ENT_CODE = c_row.ENT_CODE and ROWNUM<2; dbms_output.put_line(typez); --查詢count =1 才進行獲取ID再使用各表id進行修改ent_code --SELECT COUNT(*) into typenum FROM ITOUCH_FDA_ENT.ENT_TYPE_RELATION T WHERE T.ENT_CODE = c_row.ENT_CODE and -- ENT_TYPE_ID like ''''||typez||'%'''; --SUBSTR (acc_unit_name,1,"LENGTH" (acc_unit_name) - 1) -- '''%'||typez||'%'''; --根據各種型進行分離擴展表。 dbms_output.put_line(typez||'if(typenum=1)開始'); --if(typenum=1) --THEN BEGIN dbms_output.put_line(i||'*****'||j); dbms_output.put_line('jingrule開始'||typez); --找出不一樣類型企業 if (typez='1204') then BEGIN SELECT COUNT(*) into typenum FROM ITOUCH_FDA_ENT.ENT_TYPE_RELATION T WHERE T.ENT_CODE = c_row.ENT_CODE and ENT_TYPE_ID like '1204%'; if typenum=1 THEN BEGIN --食品經營分離操做 dbms_output.put_line('進入了1204'); dbms_output.put_line("RAWTOHEX"(sys_guid())); INSERT INTO ENT_BASIC (SELECT RAWTOHEX(sys_guid()),typeentcode, ENT_NAME,PARENT_ENT_CODE,ENT_DESC,ORG_CODE,BIZ_LIC_NO,TAX_REG_NO,ENT_PROPERTY_ID,ENT_PROPERTY_NAME,ACCOUNT_TYPE_ID, ACCOUNT_TYPE_NAME,REG_ADDR,REG_ADDR_POSTAL_CODE,ENT_LEGAL_REP_ID,ENT_LEGAL_REP,ENT_PRINCIPAL_ID,ENT_PRINCIPAL, ENT_LINKMAN_ID,ENT_LINKMAN,ENT_TEL,ENT_FAX,ENT_EMAIL,EST_DATE,REG_CAP,UNIT_ID,UNIT_NAME,AREA_CODE,AREA_NAME, AREA_TYPE_ID,AREA_TYPE_NAME,LONGITUDE,LATITUDE,CA_ID,CA_DN,ENT_STATE,ENT_PASSWORD,ATTACHMENT_CODE,IS_RISK, REMARK,PARENT_ENT_NAME,LEGAL_REP_REG_NO,UNITE_CREDIT_NO,CORP_REG_NO,ENT_TAG,AUTH_CODE_TYPE_ID,ENT_DC_TIMES FROM ENT_BASIC WHERE ENT_CODE =c_row.ENT_CODE ); --測試修改一條測試表數據 UPDATE ENT_TYPE_RELATION set ent_code =typeentcode where ent_code=c_row.ENT_CODE and ENT_TYPE_ID like '1204%'; UPDATE ENT_TYPE_RELATION set ent_code =typeentcode where ent_code=c_row.ENT_CODE and ENT_TYPE_ID like '1204%'; UPDATE ENT_LICENSE set ent_code =typeentcode where ent_code=c_row.ENT_CODE and ENT_TYPE_ID like '1204%'; UPDATE ENT_PERSON_JOB set ent_code =typeentcode where ent_code=c_row.ENT_CODE and ENT_TYPE_ID like '1204%'; UPDATE ENT_EQUIP set ent_code =typeentcode where ent_code=c_row.ENT_CODE and ENT_TYPE_ID like '1204%'; UPDATE ENT_FOOD_BIZ_EXT set ent_code =typeentcode where ent_code=c_row.ENT_CODE ; end; end if; end; elsif (typez='1102') then BEGIN SELECT COUNT(*) into typenum FROM ITOUCH_FDA_ENT.ENT_TYPE_RELATION T WHERE T.ENT_CODE = c_row.ENT_CODE and ENT_TYPE_ID like '1102%'; if typenum=1 THEN BEGIN --藥品零售分離操做 dbms_output.put_line('進入了1102'); INSERT INTO ENT_BASIC (SELECT RAWTOHEX(sys_guid()),typeentcode, ENT_NAME,PARENT_ENT_CODE,ENT_DESC,ORG_CODE,BIZ_LIC_NO,TAX_REG_NO,ENT_PROPERTY_ID,ENT_PROPERTY_NAME,ACCOUNT_TYPE_ID, ACCOUNT_TYPE_NAME,REG_ADDR,REG_ADDR_POSTAL_CODE,ENT_LEGAL_REP_ID,ENT_LEGAL_REP,ENT_PRINCIPAL_ID,ENT_PRINCIPAL, ENT_LINKMAN_ID,ENT_LINKMAN,ENT_TEL,ENT_FAX,ENT_EMAIL,EST_DATE,REG_CAP,UNIT_ID,UNIT_NAME,AREA_CODE,AREA_NAME, AREA_TYPE_ID,AREA_TYPE_NAME,LONGITUDE,LATITUDE,CA_ID,CA_DN,ENT_STATE,ENT_PASSWORD,ATTACHMENT_CODE,IS_RISK, REMARK,PARENT_ENT_NAME,LEGAL_REP_REG_NO,UNITE_CREDIT_NO,CORP_REG_NO,ENT_TAG,AUTH_CODE_TYPE_ID,ENT_DC_TIMES FROM ENT_BASIC WHERE ENT_CODE =c_row.ENT_CODE ); --測試修改一條測試表數據 UPDATE ENT_TYPE_RELATION set ent_code =typeentcode where ent_code=c_row.ENT_CODE and ENT_TYPE_ID like '1102%'; UPDATE ENT_TYPE_RELATION set ent_code =typeentcode where ent_code=c_row.ENT_CODE and ENT_TYPE_ID like '1102%'; UPDATE ENT_LICENSE set ent_code =typeentcode where ent_code=c_row.ENT_CODE and ENT_TYPE_ID like '1102%'; UPDATE ENT_PERSON_JOB set ent_code =typeentcode where ent_code=c_row.ENT_CODE and ENT_TYPE_ID like '1102%'; UPDATE ENT_EQUIP set ent_code =typeentcode where ent_code=c_row.ENT_CODE and ENT_TYPE_ID like '1102%'; UPDATE ent_drug_biz_ext set ent_code =typeentcode where ent_code=c_row.ENT_CODE ; end; end if; end; elsif (typez='1201') then BEGIN SELECT COUNT(*) into typenum FROM ITOUCH_FDA_ENT.ENT_TYPE_RELATION T WHERE T.ENT_CODE = c_row.ENT_CODE and ENT_TYPE_ID like '1201%'; if typenum=1 THEN BEGIN --食品生產分離操做 dbms_output.put_line('進入了1201'); dbms_output.put_line("RAWTOHEX"(sys_guid())); INSERT INTO ENT_BASIC (SELECT RAWTOHEX(sys_guid()),typeentcode, ENT_NAME,PARENT_ENT_CODE,ENT_DESC,ORG_CODE,BIZ_LIC_NO,TAX_REG_NO,ENT_PROPERTY_ID,ENT_PROPERTY_NAME,ACCOUNT_TYPE_ID, ACCOUNT_TYPE_NAME,REG_ADDR,REG_ADDR_POSTAL_CODE,ENT_LEGAL_REP_ID,ENT_LEGAL_REP,ENT_PRINCIPAL_ID,ENT_PRINCIPAL, ENT_LINKMAN_ID,ENT_LINKMAN,ENT_TEL,ENT_FAX,ENT_EMAIL,EST_DATE,REG_CAP,UNIT_ID,UNIT_NAME,AREA_CODE,AREA_NAME, AREA_TYPE_ID,AREA_TYPE_NAME,LONGITUDE,LATITUDE,CA_ID,CA_DN,ENT_STATE,ENT_PASSWORD,ATTACHMENT_CODE,IS_RISK, REMARK,PARENT_ENT_NAME,LEGAL_REP_REG_NO,UNITE_CREDIT_NO,CORP_REG_NO,ENT_TAG,AUTH_CODE_TYPE_ID,ENT_DC_TIMES FROM ENT_BASIC WHERE ENT_CODE =c_row.ENT_CODE ); --測試修改一條測試表數據 UPDATE ENT_TYPE_RELATION set ent_code =typeentcode where ent_code=c_row.ENT_CODE and ENT_TYPE_ID like '1201%'; UPDATE ENT_TYPE_RELATION set ent_code =typeentcode where ent_code=c_row.ENT_CODE and ENT_TYPE_ID like '1201%'; UPDATE ENT_LICENSE set ent_code =typeentcode where ent_code=c_row.ENT_CODE and ENT_TYPE_ID like '1201%'; UPDATE ENT_PERSON_JOB set ent_code =typeentcode where ent_code=c_row.ENT_CODE and ENT_TYPE_ID like '1201%'; UPDATE ENT_EQUIP set ent_code =typeentcode where ent_code=c_row.ENT_CODE and ENT_TYPE_ID like '1201%'; UPDATE ent_food_prod_ext set ent_code =typeentcode where ent_code=c_row.ENT_CODE ; --UPDATE temp_ent_code set nums=(SELECT max("TO_NUMBER"(nums))+1 from temp_ent_code); end; end if; DBMS_OUTPUT.ENABLE(buffer_size => null) ; end; --else i:=20; end if; DBMS_OUTPUT.ENABLE(buffer_size => null) ; END; --end if; --找不一樣企業if結束 end; end if; end; end if; end; END loop ; END ;
3遊標if
--select * from FLOW_NODES where FLOW_ID in (select FLOW_ID from FLOW_NAME where FLOW_STATE=0) and --(node_name ='不許予許可' or node_name='不予許可通知'); declare --類型定義 cursor c_sursorA is select * from FLOW_NODES where FLOW_ID in (select FLOW_ID from FLOW_NAME where FLOW_STATE=0) and (node_name ='不許予許可' or node_name='不予許可通知') ; --定義一個遊標變量v_cinfo c_emp%ROWTYPE ,該類型爲遊標c_emp中的一行數據類型 c_row c_sursorA%rowtype; begin for c_row in c_sursorA loop DECLARE i int ;j int ; BEGIN SELECT count(*) INTO i from FLOW_NODE_RESULTS where NODE_ID=c_row.node_id and RESULT_ITEM_ID='3'; if(i=0) then dbms_output.put_line('+999999999+'); --插入結果選項 INSERT into FLOW_NODE_RESULTS(node_id,result_item_id,result_item_alias,id) values(c_row.node_id,'3','不予許可',RAWTOHEX(sys_guid())); end if; SELECT count(*) INTO j from FLOW_NODE_ACTIONS where NODE_ID=c_row.node_id and ACTION_ID='402881f651480ea701514843e3200000'; if(j=0) then dbms_output.put_line('+888+'); --插入結論 INSERT into FLOW_NODE_ACTIONS(node_id,ACTION_ID,"ID") values(c_row.node_id,'402881f651480ea701514843e3200000',RAWTOHEX(sys_guid())); end if; dbms_output.put_line(c_row.node_id||'---結果'||i||'+節點動做結論+'||j); DBMS_OUTPUT.ENABLE(buffer_size => null) ; END; end loop; end;
4。3中if句
1、單個IF 1、if if a=... then ......... end if; 2、if else if a=... then ...... else .... end if; 3、多個IF if a=.. then ...... elsif a=.. then .... end if; 這裏中間是ELSIF 而不是ELSE IF 這裏須要特別注意
4.decode函數
DECODE的語法:
DECODE(value,if1,then1,if2,then2,if3,then3,...,else)
5.case when
case when a='1'then 'xxxx' when a='2' then 'ssss' else 'zzzzz' end as 注意 1、以CASE開頭,以END結尾 2、分支中WHEN 後跟條件,THEN爲顯示結果 3、ELSE 爲除此以外的默認狀況,相似於高級語言程序中switch case的default,能夠不加 4、END 後跟別名