Oracle FAQ 2003.02精華
2024-08-29 13:40:50
供稿:網友
1.Q: 如何使用NID來更改數據庫名稱?
A:
在Oracle9i二版以前,要想更改數據庫名稱,我們必須重建控制文件,具體更改過程參見我網站上的文章。
在Oracle9i二版中,我們可以使用一個新的工具"NID"來完成這個任務,值得一體的是這個工具同時還可以修改同一主機上低版本的數據庫名稱。
下面是將現有數據庫更名為"gototop"的具體過程:
1. Shutdown database
2. Startup mount
3. $ nid target=/ dbname=gototop
4. Shutdown database
5. Change init.ora/spfile name, i.e.: initgototop.ora
6. Change db_name parameter in init.ora/spfile, i.e.: db_name='gototop'
7. Change ORACLE_SID to point to new database name (假如5沒有做,這一步同樣可以不做)
8. Startup mount
9. Alter database open resetlogs
10. Take a backup
和很多情況類似,對數據庫的修改都需要在EXCLUSIVELY模式下進行,假如試運行在RAC環境中則會出現下面的錯誤提示:
NID-00120: Database should be mounted exclusively
解決方法也很簡單,可以先注釋掉相關RAC的參數。
2.Q: 如何將數字轉換成大寫?
A:
SQL> select to_char(to_date(1234567,'J'),'jsp') from dual;
TO_CHAR(TO_DATE(1234567,'J'),'JSP')
----------------------------------------------------------------------
ONE MILLION TWO HUNDRED THIRTY-FOUR THOUSAND FIVE HUNDRED SIXTY-SEVEN
這是英文的大寫,可以實現從1到5,373,484之間數字的轉換;中文大寫我們可以通過下面的兩個函數來實現:
CREATE OR REPLACE FUNCTION ZH(N NUMBER) RETURN CHAR AS
T VARCHAR(20):='零壹貳叁肆伍陸柒捌玖';
BEGIN
RETURN SUBSTR(T,N+1,1);
END;
/
CREATE OR REPLACE FUNCTION DX(N NUMBER) RETURN VARCHAR AS
B VARCHAR(16):='拾萬千百拾元角分';
C VARCHAR(8);
G VARCHAR(32);
BEGIN
C:=REPLACE(LPAD(LTRIM(TO_CHAR(N,'999999.99')),9,'0'),'.','');
FOR I IN 1..8 LOOP
G:=GZH(SUBSTR(C,I,1))SUBSTR(B,I,1);
END LOOP;
RETURN G;
END;
/
3. Q:如何確定當前的Oracle版本?
A:
當一個系統中安裝有多個版本的ORACLE時,可以按照下面的方法來確定當前的Oracle版本:
1、比較“/etc/oratab”與$ORACLE_HOME環境變量;
2、進入ORACLE數據庫中,執行SELECT * FROM V$INSTANCE;
4. Q:如何知道hidden參數的含義?
A:
在init.ora中有時會用到類似下面以"_"開頭的hidden參數:
_corrupted_rollback_segments=(r01,r02,r03,r04)
_allow_resetlogs_corruption=ture
這些參數一般都是由oracle support建議才會使用的,沒有公布這方面的文檔,我們可以通過下面的語句,看到一些解釋:
select * from X$KSPPI where KSPPINM='_corrupted_rollback_segments';
select * from X$KSPPI where KSPPINM='_allow_resetlogs_corruption';
4. Q:如何使用rownum進行分頁?
A:
下面是我們單位開發人員提出的分頁方法:
“更為簡單、清楚的ORACLE分頁SQL:
select * from t_xxx where rownum < 201 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)+。
。。
共是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),精度更高 >(出處:清風軟件下載學院)