ORACLE高級部分內容
1.pl/sql基本語句
DECLARE
BEGIN
END;
/
循環語句
DECLARE
I NUMBER(2):=1;
BEGIN
WHILE I<100
LOOP
I:=I+1;
END LOOP;
END;
/
DECLARE
I NUMBER(2):=1;
BEGIN
LOOP
EXIT WHEN I<100;
I:=I+1;
END LOOP;
END;
/
判斷語句
DECLARE
I NUMBER(2):=1;
BEGIN
IF I>2 THEN
....
ELSIF I>1 THEN
....
ELSE
....
END IF;
END;
/
2.遊標(cursor)(可帶參也可不帶參,參考scott表)
DECLARE
CURSOR [遊標名] IS SELECT ENAME FROM EMP;
PNAME EMP.ENAME%TYPE;
BEGIN
OPEN [遊標名]
LOOP
FETCH [] INTO PNAME ;
EXIT WHEN [遊標名]%NOTFOUND;
END LOOP;
END;
/
3.存儲過程(procedure)
CREATE OR REPLACE PROCEDURE PP_PRO
AS
PNAME VARCHAR2(10);
BEGIN
SELECT ENAME INTO PP_PRO;
END;
4.存儲函數
CREATE OR REPLACE FUNCTION PP_FUN RETURN VARCHAR2
AS
FNAME VARCHR2:=‘HELLO‘;
BEGIN
RETURN FNAME;
END;
5.觸發器(trigger)
CREATE OR REPLACE TRIGGER OOP_TRI
BEFORE/AFTER
INSERT/DELETE/UPDATE ON EMP
DECLARE
BEGIN
END;
歸納總結:
PLSQL
是專用於Oracle服務器,在SQL基礎之上,添加了一些過程化控制語句,叫PLSQL過程化包括有:類型定義,判斷,循環,遊標,異常或例外處理。。。
PLSQL強調過程
因為SQL是第四代命令式語言,無法顯示處理過程化的業務,所以得用一個過程化程序設計語言來彌補SQL的不足之處,
SQL和PLSQL不是替代關系,是彌補關系
CURSOR
類似於JDBC中的ResultSet對象的功能,從上向下依次獲取每一記錄的內容
PROCEDURE(存儲過程):事先運用oracle語法,寫好的一段具有業務功能的程序片段,長期保存在oracle服務器中,供客戶端和程序語言遠程訪問
(1)PLSQL每次執行都要整體運行一遍,才有結果
(2)PLSQL不能將其封裝起來,長期保存在oracle服務器中
(3)PLSQL不能被其它應用程序調用,例如:AVA程序調用:preparedStatement-->CallableStatement
存儲過程和plsql到底是什麽關系?
存儲過程是plsql的一個方面的應用;而plsql是存儲過程的基礎,即存儲過程必須用到plsql
存儲過程調用方式:
- 調用存儲過程方式一,exec 存儲過程
- 調用存儲過程方式二,PLSQL程
- 調用存儲過程方式三,Java程序
FUNCTION(存儲函數)
聲明:適合不是強行要你使用,只是優先考慮
什麽情況下【適合使用】存儲過程?什麽情況下【適合使用】存儲函數?
本質上沒區別。只是函數有如:只能返回一個變量的限制。而存儲過程可以返回多個。而函數是可以嵌入在sql中使用的,可以在select中調用,而存儲過程不行。執行的本質都一樣。 函數限制比較多,比如不能用臨時表,只能用表變量.還有一些函數都不可用等等.而存儲過程的限制相對就比較少
1. 一般來說,存儲過程實現的功能要復雜一點,而函數的實現的功能針對性比較強。
2. 對於存儲過程來說可以返回參數,而函數只能返回值或者表對象。
3. 存儲過程一般是作為一個獨立的部分來執行(EXEC執行),而函數可以作為查詢語句的一個部分來調用(SELECT調用),由於函數可以返回一個表對象,因此它可以在查詢語句中位於FROM關鍵字的後面。
4. 當存儲過程和函數被執行的時候,SQL Manager會到procedure cache中去取相應的查詢語句,如果在procedure cache裏沒有相應的查詢語句,SQL Manager就會對存儲過程和函數進行編譯。
什麽情況【適合使用】過程函數,什麽情況【適合使用】SQL?
【適合使用】過程函數:
》需要長期保存在數據庫中
》需要被多個用戶重復調用
》業務邏輯相同,只是參數不一樣
》批操作大量數據,例如:批量插入很多數據
【適合使用】SQL:
》凡是上述反面,都可使用SQL
》對表,視圖,序列,索引,等這些還是要用SQL
-------------------------------------------------------------------------------------觸發器
oracle常用命令:
hostcls 清屏
rollback 回滾 後必須執行 commit 提交
show recyclebin;查看回收站
flashback table emp to before drop;--閃回
drop table emp purge;--徹底刪除表
什麽是觸發器【Trigger】?
不同的DML(SELECT/UPDATE/DELETE/INSERT)操作,觸發器能夠進行一定的攔截,符合條件的操作,才能操作基表,
否則不能操作基表,類似於javaweb中的Filter,Struts2的Interceptor
為什麽要用觸發器?
如果沒有觸發器,那麽DML所有操作,均可無限制的操作基表
數據庫的優化
1)數據庫設計方面:
a. 對查詢進行優化,應盡量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引。
b. 應盡量避免在 where 子句中對字段進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃描,如: select id from t where num is null 可以在num上設置默認值0,確保表中num列沒有null值,然後這樣查詢: select id from t where num=0
c. 並不是所有索引對查詢都有效,SQL是根據表中數據來進行查詢優化的,當索引列有大量數據重復時,查詢可能不會去利用索引,如一表中有字段sex,male、female幾乎各一半,那麽即使在sex上建了索引也對查詢效率起不了作用。
d. 索引並不是越多越好,索引固然可以提高相應的 select 的效率,但同時也降低了 insert 及 update 的效率,因為 insert 或 update 時有可能會重建索引,所以怎樣建索引需要慎重考慮,視具體情況而定。一個表的索引數最好不要超過6個,若太多則應考慮一些不常使用到的列上建的索引是否有必要。
e. 應盡可能的避免更新索引數據列,因為索引數據列的順序就是表記錄的物理存儲順序,一旦該列值改變將導致整個表記錄的順序的調整,會耗費相當大的資源。若應用系統需要頻繁更新索引數據列,那麽需要考慮是否應將該索引建為索引。
f. 盡量使用數字型字段,若只含數值信息的字段盡量不要設計為字符型,這會降低查詢和連接的性能,並會增加存儲開銷。這是因為引擎在處理查詢和連接時會逐個比較字符串中每一個字符,而對於數字型而言只需要比較一次就夠了。
g. 盡可能的使用 varchar/nvarchar 代替 char/nchar ,因為首先變長字段存儲空間小,可以節省存儲空間,其次對於查詢來說,在一個相對較小的字段內搜索效率顯然要高些。
h. 盡量使用表變量來代替臨時表。如果表變量包含大量數據,請註意索引非常有限(只有主鍵索引)。
i. 避免頻繁創建和刪除臨時表,以減少系統表資源的消耗。
j. 臨時表並不是不可使用,適當地使用它們可以使某些例程更有效,例如,當需要重復引用大型表或常用表中的某個數據集時。但是,對於一次性事件,最好使用導出表。
k. 在新建臨時表時,如果一次性插入數據量很大,那麽可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果數據量不大,為了緩和系統表的資源,應先create table,然後insert。
l. 如果使用到了臨時表,在存儲過程的最後務必將所有的臨時表顯式刪除,先 truncate table ,然後 drop table ,這樣可以避免系統表的較長時間鎖定。
2)SQL語句方面:
a. 應盡量避免在 where 子句中使用!=或<>操作符,否則將引擎放棄使用索引而進行全表掃描。
b. 應盡量避免在 where 子句中使用 or 來連接條件,否則將導致引擎放棄使用索引而進行全表掃描,如: select id from t where num=10 or num=20 可以這樣查詢: select id from t where num=10 union all select id from t where num=20
c. in 和 not in 也要慎用,否則會導致全表掃描,如: select id from t where num in(1,2,3) 對於連續的數值,能用 between 就不要用 in 了: select id from t where num between 1 and 3
d. 下面的查詢也將導致全表掃描: select id from t where name like ‘%abc%’
e. 如果在 where 子句中使用參數,也會導致全表掃描。因為SQL只有在運行時才會解析局部變量,但優化程序不能將訪問計劃的選擇推遲到運行時;它必須在編譯時進行選擇。然而,如果在編譯時建立訪問計劃,變量的值還是未知的,因而無法作為索引選擇的輸入項。如下面語句將進行全表掃描: select id from t where [email protected] 可以改為強制查詢使用索引: select id from t with(index(索引名)) where [email protected]
f. 應盡量避免在 where 子句中對字段進行表達式操作,這將導致引擎放棄使用索引而進行全表掃描。如: select id from t where num/2=100 應改為: select id from t where num=100*2
g. 應盡量避免在where子句中對字段進行函數操作,這將導致引擎放棄使用索引而進行全表掃描。如: select id from t where substring(name,1,3)=’abc’–name以abc開頭的id select id from t where datediff(day,createdate,’2005-11-30′)=0–‘2005-11-30’生成的id 應改為: select id from t where name like ‘abc%’ select id from t where createdate>=’2005-11-30′ and createdate<’2005-12-1′
h. 不要在 where 子句中的“=”左邊進行函數、算術運算或其他表達式運算,否則系統將可能無法正確使用索引。
i. 不要寫一些沒有意義的查詢,如需要生成一個空表結構: select col1,col2 into #t from t where 1=0 這類代碼不會返回任何結果集,但是會消耗系統資源的,應改成這樣: create table #t(…)
j. 很多時候用 exists 代替 in 是一個好的選擇: select num from a where num in(select num from b) 用下面的語句替換: select num from a where exists(select 1 from b where num=a.num)
k. 任何地方都不要使用 select * from t ,用具體的字段列表代替“*”,不要返回用不到的任何字段。
l. 盡量避免使用遊標,因為遊標的效率較差,如果遊標操作的數據超過1萬行,那麽就應該考慮改寫。
m. 盡量避免向客戶端返回大數據量,若數據量過大,應該考慮相應需求是否合理。
n. 盡量避免大事務操作,提高系統並發能力。
3)java方面:重點內容
a.盡可能的少造對象。
b.合理擺正系統設計的位置。大量數據操作,和少量數據操作一定是分開的。大量的數據操作,肯定不是ORM框架搞定的。,
c.使用jDBC鏈接數據庫操作數據
d.控制好內存,讓數據流起來,而不是全部讀到內存再處理,而是邊讀取邊處理;
e.合理利用內存,有的數據要緩存
ORACLE高級部分內容