熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Oracle >> 正文

Oracle FAQ 2003.02精華

2022-06-13   來源: Oracle 

  Q: 如何使用NID來更改數據庫名稱?
  A:
  在Oraclei二版以前要想更改數據庫名稱我們必須重建控制文件具體更改過程參見我網站上的文章
  在Oraclei二版中我們可以使用一個新的工具NID來完成這個任務值得一體的是這個工具同時還可以修改同一主機上低版本的數據庫名稱
  
  下面是將現有數據庫更名為gototop的詳細過程
  
   Shutdown database
   Startup mount
   $ nid target=/ dbname=gototop
   Shutdown database
   Change initora/spfile name ie: initgototopora
   Change db_name parameter in initora/spfile ie: db_name=gototop
   Change ORACLE_SID to point to new database name (如果沒有做這一步同樣可以不做)
   Startup mount
   Alter database open resetlogs
   Take a backup
  
  和很多情況類似對數據庫的修改都需要在EXCLUSIVELY模式下進行如果試運行在RAC環境中則會出現下面的錯誤提示
  NID: Database should be mounted exclusively
  
  解決方法也很簡單可以先注釋掉相關RAC的參數
  
  Q: 如何將數字轉換成大寫?
  A:
  SQL> select to_char(to_date(J)JSP) from dual;
  
  TO_CHAR(TO_DATE(J)JSP)
  
  ONE MILLION TWO HUNDRED THIRTYFOUR THOUSAND FIVE HUNDRED SIXTYSEVEN
  
  這是英文的大寫可以實現從之間數字的轉換中文大寫我們可以通過下面的兩個函數來實現
  
  CREATE OR REPLACE FUNCTION ZH(N NUMBER) RETURN CHAR AS
  T VARCHAR():=零壹貳三肆伍陸柒捌玖;
  BEGIN
  RETURN SUBSTR(TN+);
  END;
  /
  CREATE OR REPLACE FUNCTION DX(N NUMBER) RETURN VARCHAR AS
  B VARCHAR():=拾萬千百拾元角分;
  C VARCHAR();
  G VARCHAR();
  BEGIN
  C:=REPLACE(LPAD(LTRIM(TO_CHAR(N))));
  FOR I IN LOOP
  G:=G||ZH(SUBSTR(CI))||SUBSTR(BI);
  END LOOP;
  RETURN G;
  END;
  /
  
   Q:如何確定當前的Oracle版本?
  A:
  當一個系統中安裝有多個版本的ORACLE時可以按照下面的方法來確定當前的Oracle版本
  比較/etc/oratab與$ORACLE_HOME環境變量
  進入ORACLE數據庫中執行SELECT * FROM V$INSTANCE;
  
   Q:如何知道hidden參數的含義?
  A:
  在initora中有時會用到類似下面以_開頭的hidden參數
  _corrupted_rollback_segments=(rrrr)
  _allow_resetlogs_corruption=ture
  這些參數一般都是由oracle support建議才會使用的沒有公布這方面的文檔我們可以通過下面的語句看到一些解釋
  select * from X$KSPPI where KSPPINM=_corrupted_rollback_segments;
  select * from X$KSPPI where KSPPINM=_allow_resetlogs_corruption;
  
   Q:如何使用rownum進行分頁?
  A:
  下面是我們單位開發人員提出的分頁方法
  更為簡單清晰的ORACLE分頁SQL
  select * from t_xxx where rownum < minus select * from t_xxx where rownum < 101”
  下面是我的回復:
  
  這樣的SQL是令人擔憂的!
  
  原因基於兩點:
  1、我們知道rownum是oracle輸出結果中的虛行,即在實際的表中並沒有相應的存儲結構存在;
  2、minus運算是在兩次操作結果的基礎上進行的,因此在非不得不的情況下,我們一貫主張避免使用類似的操作;
  
  由此可以看出樓主提出的SQL:
  select * from t_xxx where rownum < 201 minus select * from t_xxx where rownum < 101;
  為了取出100條紀錄實際上執行了兩次SELECT共300條紀錄,舉個簡單的例子,如果共1000條紀錄,分頁為100條,那麼全部SELECT總數據量是
  100+(200+100)+(300+200)+。Tw.WInGwiT.CoM。。
  共是10000條,整整是10倍的數據量!如果是幾萬、幾十萬的數量級,再加上實際操作中的ORDER BY以及相關的WHERE條件,更不敢想象這樣SQL的效率。
  
  在實際中針對分頁比較典型的做法是:
  select * from
  ( select rownum rnm, a.* from
  ( select * from t where name=&myname order by name,dept) a
  where rownum <= &maxrnm )
  where rnm >= &minrnm ;
  
  這裡有三個變量:
  &myname where條件
  &maxrnm要查詢的最大行號
  &minrnm要查詢的最小行號
  
  使用這樣的SQL在8i以後ORACLE是使用專門的優化來處理的,它需要排序字段預先建有索引,由於索引是已排序好的結構,因此取TOP n的問題,就變為從索引中直接從頭提取n個索引關鍵字,然後再根據索引就可快速的找到記錄並返回給用戶。從而有效避免了檢索全部記錄的情況。
  
  按分頁計算,如果用戶很少浏覽後面頁面的數據使用上面的SQL效率是很好,否則到某一刻index range scan所有滿足條件記錄時帶來的高成本,CBO甚至認為它高於FULL TABLE SCAN而選擇FULL TABLE SCAN。為了避免這一情況,針對經常需要浏覽後面分頁數據的用戶,可以使用下面的SQL來處理:
  
  select * from t where rowid in
  ( select rid from
  ( select rownum rno,rowid rid from
  ( select rowid from t where name = &myname order by name,dept )
  where rownum <= &maxrnm )
  where rno >= &minrnm )
  ;
  
  在這一方法中,我們考慮到索引與表相比,數據量大大小於後者,因此我們試圖先在索引中搜索出某頁記錄的物理位置,然後根據這些物理位置(rowid)在表中直接取出相應的記錄,這將有利消除上述FULL TABLE SCAN的出現。
  
  當然二者之間的選擇要看我們的實際應用以及我們INDEX的情況,以便更好地提高效率。
  
  另外一種做法在ORACLE8.1.6之後可以使用row_number() over()函數來實現:
  
  select * from
  (SELECT owner,table_name,row_number() OVER(ORDER BY table_name) rownumber FROM dba_tables)
  where rownumber >= 100 and rownumber <= 200;
  
  5.Q: EXP with compress=y是不是總有好處?
  A:
  在使用EXP時,很多人不分情形,總喜歡使用COMPRESS=Y參數,其實這一種錯誤的做法。
  
  導出選項COMPRESS=Y 將生成創建初始EXTENT的代碼,該初始EXTENT大小等於當前分
  配給對象的所有EXTENT的總大小,如果對象上有很多已刪除的行或者如果上一個EXTENT有很多未使用的塊,這將不必要地分配給對象很多空間。
  
  另外在使用EXP還有以下幾點需要注意:
  1、可以將常用命令行選項寫在參數文件中;
  2、僅在小數據量的情況下使用CONSISTENT=Y參數;
  3、分配盡量大的BUFFER並使用DIRECT=Y參數。
  
  6.Q: ORACLE常用的數據類型有哪些?
  A:
  之所以把這個問題也放在這裡,是想為使用時提供一個參考:
  
  字段類型 中文說明 限制條件 其它說明
  CHAR 固定長度字符串 最大長度2000 bytes
  VARCHAR2 可變長度的字符串 最大長度4000 bytes 可做索引的最大長度749
  NCHAR 根據字符集而定的固定長度字符串 最大長度2000 bytes
  NVARCHAR2 根據字符集而定的可變長度字符串 最大長度4000 bytes
  DATE 日期(日-月-年) DD-MM-YY(HH-MI-SS) 經過嚴格測試,無千蟲問題
  LONG 超長字符串 最大長度2G(231-1) 足夠存儲大部頭著作
  RAW 固定長度的二進制數據 最大長度2000 bytes 可存放多媒體圖象聲音等
  LONG RAW 可變長度的二進制數據 最大長度2G 同上
  BLOB 二進制數據 最大長度4G
  CLOB 字符數據 最大長度4G
  NCLOB 根據字符集而定的字符數據 最大長度4G
  BFILE 存放在數據庫外的二進制數據 最大長度4G
  ROWID 數據表中記錄的唯一行號 10 bytes ********.****.****格式,*為0或1
  NROWID 二進制數據表中記錄的唯一行號 最大長度4000 bytes
  NUMBER(P,S) 數字類型 P為整數位,S為小數位
  DECIMAL(P,S) 數字類型 P為整數位,S為小數位
  INTEGER 整數類型 小的整數
  FLOAT 浮點數類型 NUMBER(38),雙精度
  REAL 實數類型 NUMBER(63),精度更高
  

From:http://tw.wingwit.com/Article/program/Oracle/201311/18103.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.