存儲過程是一組為了完成特定功能的sql語句集,存儲在資料庫中,經過一次編譯後再次調用不需要編譯。用戶通過指定存儲過程的名字來執行它。 基本語法: create or replace procedure procedure_01 is//一直糾結這裡是is還是as,查資料後發現:在存儲過程(proce ...
存儲過程是一組為了完成特定功能的sql語句集,存儲在資料庫中,經過一次編譯後再次調用不需要編譯。用戶通過指定存儲過程的名字來執行它。
基本語法:
create or replace procedure procedure_01
is//一直糾結這裡是is還是as,查資料後發現:在存儲過程(procedure)和函數(function)中沒有區別。在視圖(view)中只能用as不能用is,在游標(cursor)中只能用is,不能用as。
begin
//要執行的代碼行
commit;
end procedure_01;
調用存儲過程:
call procedure_01();//註意括弧不可省略。創建的時候不用加,調用的時候必需加上。
*前兩天公司給安排了一個任務,要求寫一個存儲過程,迴圈遍歷所有表,找出所有業務已經完成的記錄,即status='11'的記錄插入到歷史表中,並刪除原表中的記錄。
記錄下來,方便日後查詢。歷史表與原表的區別就是多了‘_H’。
create or replace procedure insertH
is
begin
insert into TW_ZNDW_TASK_MAIN_H select * from TW_ZNDW_TAKS_MAIN where status='11';
delete from TW_ZNDW_TAKS_MAIN T where status = '11' and EXISTS(select 1 from TW_ZNDW_TASK_MAIN_H H where T.id = H.id);
//exists是判斷後面的sql語句是否為真,若為真則整個sql句子成立,否則沒有任何記錄。這句話的意思就是在刪除原表記錄之前先判斷一下是否已經插入到了歷史表中
//有時候為了提高效率,只是測試下某個表中是否存在記錄,就用1來代替。
commit;
end insertH;
call insertH();
//上述代碼只是插入一張表的記錄。後面查了資料,學習了怎麼迴圈遍歷所有表,接下來分享完整代碼。
create or replace procedure insertHistory
is
tableName1 varchar2(100);
tableName2 varchar2(100);
sqlstr varchar2(500);
cursor tableNameAll is Select table_name FROM USER_TABLES where regexp_like(table_name,'^TW_ZNDW_TASK_[0-9]+$') or table_name = 'TW_ZNDW_TASK';
//游標cursor,這裡只能用is來賦值。USER_TABLES是系統表,使用USER_TABLES可查詢所有的table_name欄位。
begin
for tableName in tableNameAll loop
begin
tableName1 := tableName.table_name;//這裡賦值用:=冒號加等號的形式賦值,tableName是形參,用來獲取table_name賦值給tableName1;
tableName2 := tableName1+'_H';
sqlstr := 'insert into' || tableName2 || 'select * from' || tableName1 || 'where status='' 11'' ';//連接符號用||,也可以用+。
EXECUTE IMMEDIATE sqlstr; //表示立即執行該語句。
sqlstr := 'delete from' tableName1 || 'where status=''11'' and exists (select 1 from' || tableName2 || 't2 where t1.id = t2.id' )';
EXECUTE IMMEDIATE sqlstr;
commit;
end;
end loop;
end insertHistory;
調用:call insertHistory();
*另外一個任務,初始化部分數據。之所以把這個任務放在這裡,是因為這是優化之後的代碼,剛接手這個任務的時候我是一條一條記錄來插入刪除的,後來請教了組長才明白這麼回事,可以動態執行。感覺跟存儲過程有異曲同工之妙。
--刪除歷史數據
DELETE from TW_PROD_ELEC_RULE_CONFIG where RULE_TYPE='退服指標自動稽核演算法';
--插入移動數據
INSERT INTO TW_PROD_ELEC_RULE_CONFIG
select
rawtohex(sys_guid()), o.ORGCODE, o.ORGNAME, NULL, NULL, NULL, NULL, '剔除免責站址數據,剔除夜間免責,未購買發電服務站址停電保夠3小時的退服不納入統計,運營商申告工單', '剔除免責站址數據 ,剔除夜間免責 ,未購買發電服務站址停電保夠3小時的退服不納入統計 ,運營商申告工單', '2', 'sa', sysdate, NULL, NULL, NULL, NULL, NULL, NULL, '退服指標自動稽核演算法', '1001'
from BAF_ORG_ORGANIZATION o
where OBJECTTYPEID='3'
and (
o.ORGNAME like '%四川%'
or o.ORGNAME like '%河南%'
or o.ORGNAME like '%江蘇%'
);
INSERT INTO TW_PROD_ELEC_RULE_CONFIG
select
rawtohex(sys_guid())as id,P_ORGID,P_ORGNAME,C_ORGID,C_ORGNAME,A_ORGID,A_ORGNAME,RULE_INFO,RULE_INFO_TEXT,STATUS,CREATE_USER,CREATE_DATE,
UPDATE_DATE,UPDATE_USER,COL1,COL2,COL3,RULE_COL_CHECK,RULE_TYPE,'1002' RETIREMENT_SCOPE
from TW_PROD_ELEC_RULE_CONFIG where RULE_TYPE='退服指標自動稽核演算法'
UNION
select
rawtohex(sys_guid())as id,P_ORGID,P_ORGNAME,C_ORGID,C_ORGNAME,A_ORGID,A_ORGNAME,RULE_INFO,RULE_INFO_TEXT,STATUS,CREATE_USER,CREATE_DATE,
UPDATE_DATE,UPDATE_USER,COL1,COL2,COL3,RULE_COL_CHECK,RULE_TYPE,'1003' RETIREMENT_SCOPE
from TW_PROD_ELEC_RULE_CONFIG where RULE_TYPE='退服指標自動稽核演算法';
*補充:
//union 和 union all都要求兩個sql查詢列要相同;
//union:聯合查詢出並集(會去除重覆記錄);
//union all:聯合查詢出並集,包含重覆記錄;