什麼是存儲過程
簡單的說,就是一組SQL語句集,功能強大,可以實現一些比較複雜的邏輯功能,類似於JAVA語言中的方法;
ps:存儲過程跟觸發器有點類似,都是一組SQL集,但是存儲過程是主動調用的,且功能比觸發器更加強大,觸發器是某件事觸發後自動調用;
存儲過程有哪些特性
有輸入輸出參數,可以聲明變量,有if/else, case,while等控制語句,通過編寫存儲過程,可以實現複雜的邏輯功能;
函數的普遍特性:模塊化,封裝,代碼複用;
速度快,只有首次執行需經過編譯和優化步驟,後續被調用可以直接執行,省去以上步驟;
創建一個存儲過程
create procedure user_porced ()
begin
select name from users;
end;
調用存儲過程
call porcedureName ();
傳參存儲過程
create PROCEDURE user_porcedPa(
in a int(10)
)
BEGIN
select * from users where age>a;
END;
call user_porcedPa(10);
–call方式調用存儲過程
call pro_process.p_time_test();
–創建並執行定時計劃
Declare
i Integer;
Begin
dbms_job.submit(i,'pro_process.p_time_test;',Sysdate,'sysdate+30/(24*60*60)');
end;
–創建調用帶參數的存儲過程的定時任務
declare
i integer;
begin
dbms_job.submit(i,'declare arg varchar2(128); begin my_demo.demo_loop(arg); end;',sysdate,'sysdate+30/(24*60*60)');
commit;
end;
–查看任務隊列情況(包括任務號碼)
select job as jobno,next_date,next_sec,failures,broken from user_jobs where what='pro_process.p_time_test;' ;
--broken:Y:沒啓動 N:啓動
–job如果由於某種原因未能成功執行,oracle將重試16次後,還未能成功執行,將被標記爲broken,重新啓動狀態爲broken的job
–通過任務號碼重啓定時任務
Declare
jobno Integer := 23;
Begin
dbms_job.run(jobno); -- 運行制定的執行計劃
end;
–停止執行定時任務
–方式一
Declare
jobno Integer := 23;
Begin
dbms_job.broken(jobno,True); -- 停止計劃,不再繼續執行
dbms_job.broken(jobno,True,Sysdate+(2/24/60)); -- 停止計劃,並在兩分鐘後繼續執行
end;
–方式二
begin
dbms_job.broken(23, true, sysdate);
commit;
end;
–修改執行計劃方式一
Declare
jobno Integer;
Begin
dbms_job.interval(jobno, 'sysdate+1/(24*60)'); -- 修改爲:每分鐘執行一次
end;
–修改執行計劃方式二
declare
jobno Integer;
begin
dbms_job.next_date(jobno, next_date); --指定任務號的時間
end
–刪除執行計劃
Declare
jobno Integer:=23;
Begin
dbms_job.remove(jobno);
commit;
end;
act_defid number;--活動定義Id
act_defname varchar2(128);--活動實例名稱
act_desc varchar2(512);--活動實例描述
act_type varchar2(64);--活動類型
act_currentstate number;--活動當前環節
act_state number;--活動當前狀態
act_nextdefid number;--下個活動定義Id
act_nextdefname varchar2(128);--下個活動定義名稱
act_nextstate number;--下個活動環節
act_grade number;--參與當前活動(環節)執行機構等級
act_gradetype number;--機構等級與機構的類型(0爲機構等級,1爲機構,2爲流程執行者)
act_lastgrade number;--當前環節執行機構上級機構等級(屬於等級的上級,如部門,營業廳,班組的上級就是網、省、市等)
act_role clob;--角色標識
act_rolename clob;--角色名稱
act_person clob;--參與人員
act_org clob;--組織機構
存儲過程優缺點
優點
1.在生產環境下,可以通過直接修改存儲過程的方式修改業務邏輯(或bug),而不用重啓服務器。但這一點便利被許多人濫用了。有人直接就在正式服務器上修改存儲過程,而沒有經過完整的測試,後果非常嚴重。
2.執行速度快。存儲過程經過編譯之後會比單獨一條一條執行要快。但這個效率真是沒太大影響。如果是要做大數據量的導入、同步,我們可以用其它手段。
3.減少網絡傳輸。存儲過程直接就在數據庫服務器上跑,所有的數據訪問都在服務器內部進行,不需要傳輸數據到其它終端。但我們的應付服務器通常與數據庫是在同一內網,大數據的訪問的瓶頸會是硬盤的速度,而不是網速。
4.能夠解決presentation與數據之間的差異,說得文藝青年點就是解決OO模型與二維數據持久化之間的阻抗。領域模型和數據模型的設計可能不是同一個人(一個是SA,另一個是DBA),兩者的分歧可能會很大——這不奇怪,一個是以OO的思想來設計,一個是結構化的數據來設計,大家互不妥協——你說爲了軟件的彈性必須這麼設計,他說爲了效率必須那樣設計,爲了抹平鴻溝,就用存儲過程來做數據存儲的邏輯映射(把屬性映射到字段)。好吧,臺下已經有同學在叨咕ORM了。
5.方便DBA優化。所有的SQL集中在一個地方,DBA會很高興。這一點算是ORM的軟肋。不過按照CQRS框架的思想,查詢是用存儲過程還是ORM,還真不是問題——DBA對數據庫的優化,ORM一樣會受益。況且放在ORM中還能用二級緩存,有些時候效率還會更高。
缺點
1.SQL本身是一種結構化查詢語言,加上了一些控制(賦值、循環和異常處理等),但不是OO的,本質上還是過程化的,面對複雜的業務邏輯,過程化的處理會很喫力。這一點算致命傷。
2.不便於調試。基本上沒有較好的調試器,很多時候是用print來調試,但用這種方法調試長達數百行的存儲過程簡直是噩夢。好吧,這一點不算啥,C#/java一樣能寫出噩夢般的代碼。
3.沒辦法應用緩存。雖然有全局臨時表之類的方法可以做緩存,但同樣加重了數據庫的負擔。如果緩存併發嚴重,經常要加鎖,那效率實在堪憂。
4.無法適應數據庫的切割(水平或垂直切割)。數據庫切割之後,存儲過程並不清楚數據存儲在哪個數據庫中。
5.精通SQL的新手越來越少——不要笑,這是真的,我面試過N多新人,都不知道如何創建全局臨時表、不知道having、不知道聚集索引和非聚集索引,更別提遊標和提交叉表查詢了。好吧,這個缺點算是湊數用的,作爲屌絲程序員,我們的口號是:沒有不會的,只有不用的。除了少數有語言潔癖的人,我相信精通SQL只是時間問題。