1. 程式人生 > >ORACLE高級部分內容

ORACLE高級部分內容

重復 區別 強行 struts2 設置 loop sel nag ret

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高級部分內容