Oracle數(shù)據(jù)庫(kù)常見問(wèn)題答疑
2024-08-29 13:30:13
供稿:網(wǎng)友
oracle數(shù)據(jù)庫(kù)以其強(qiáng)大的功能和穩(wěn)定性而著稱,但同時(shí),在開發(fā)和管理方面也存在很多困難,筆者在此總結(jié)了一些oracle數(shù)據(jù)庫(kù)開發(fā)和管理的常見問(wèn)題,希望能對(duì)大家有所幫助。
問(wèn):如果發(fā)現(xiàn)表中有壞塊,如何檢索其它未壞的數(shù)據(jù)?
答:首先需要找到壞塊的id(可以運(yùn)行dbverify實(shí)現(xiàn)),假設(shè)為1234。運(yùn)行下面的查詢查找段名:
select segment_name, segment_type, block_id, blocks
from dba_extents
where (1234 between block_id and (block_id + blocks - 1));
一旦找到壞段名稱,若段是一個(gè)表,則最好建立一個(gè)臨時(shí)表,存放好的數(shù)據(jù)。若段是索引,則刪除它,再重建。
create table good_table
as
select from bad_table where rowid not in
( select /+index(bad_table, any_index)/ rowid
from bad_table where substr( rowid, 1, 8 ) = 1234)
問(wèn):如請(qǐng)問(wèn)如何關(guān)閉form調(diào)用report時(shí)的小窗口?
答:在利用oracle數(shù)據(jù)庫(kù)的develop 2000設(shè)計(jì)開發(fā)界面的過(guò)程中,當(dāng)form調(diào)用report時(shí),會(huì)顯示一個(gè)背景窗口report backgroud engine,等待form對(duì)report的調(diào)用,當(dāng)form調(diào)用其它report時(shí),也使用這個(gè)后臺(tái)服務(wù)器,不論調(diào)用多少個(gè)report,這個(gè)后臺(tái)服務(wù)器存在且只有一個(gè)。但當(dāng)form與report全部退出后,該窗口仍處于等待狀態(tài),不會(huì)關(guān)閉,這時(shí),我們需要手工將其關(guān)閉。
我們可以使用以下參數(shù)在form調(diào)用report時(shí)不顯示這個(gè)小窗口:
add_parameter( pl_id, 'oracle_shutdown',text_parameter, 'yes' );
需要注意的是,該參數(shù)必須加在所有參數(shù)的前面,即它必須為第一個(gè)參數(shù)。
問(wèn):請(qǐng)問(wèn)如何根據(jù)查詢條件在report中動(dòng)態(tài)顯示記錄?
答:1. 在report的“數(shù)據(jù)模型”下面的“用戶參數(shù)”中,創(chuàng)建用戶自定義參數(shù)w_clause,w_clause為從form傳遞過(guò)來(lái)的查詢條件,數(shù)據(jù)類型為字符型,缺省值為null。
2. 修改查詢q_1,將sql查詢語(yǔ)句修改為select from dept &&w_clause。
3. 在運(yùn)行報(bào)表時(shí),報(bào)表會(huì)自動(dòng)將符合&&w_clause的查詢條件記錄顯示出來(lái)。
如果從form傳遞過(guò)來(lái)的w_clause為where dept=1,本報(bào)表的sql查詢自動(dòng)轉(zhuǎn)換為select from dept where dept=1,并在報(bào)表運(yùn)行結(jié)果中顯示符合該查詢條件的記錄,如果從form傳遞過(guò)來(lái)的w_cluase為where to_char(年度,'yyyy.mm')='2000.03',則在報(bào)表運(yùn)行結(jié)果中自動(dòng)顯示2000年3月份的記錄。
問(wèn):在oracle中,我們?nèi)绾尾榭茨潮砩系募s束?
答:我們可以使用下面語(yǔ)句從all_constraints視圖中查看某表上的約束:
select constraint_name, table_name, r_owner, r_constraint_name
from all_constraints
where table_name = 'table_name' and owner = 'owner_name';
另一個(gè)視圖all_cons_columns也包括組成表上約束列的信息。
問(wèn):如何將數(shù)據(jù)庫(kù)從noarchivelog方式改變?yōu)閍rchivelog方式?
答:首先打開init.ora文件,確保存檔日志目標(biāo)指向一有效目錄。
然后啟動(dòng)server manager
svrmgrl〉 shutdown immediate
svrmgrl〉 startup mount
svrmgrl〉 alter database archivelog;
svrmgrl〉 alter database open;
svrmgrl〉 archive log list;
在init.ora中設(shè)置參數(shù)archive_log_start=true,它設(shè)置存檔日志為自動(dòng)啟動(dòng)。在oracle 8i中支持多個(gè)存檔日志的目標(biāo),因此參數(shù)修改為log_archive_dest[n],其中n為1到5。
問(wèn):在oracle數(shù)據(jù)庫(kù)中,我們?nèi)绾卧黾颖砜臻g的大小?
答: 在開發(fā)oracle數(shù)據(jù)庫(kù)中,我們有兩種方法增加表空間的大小:
1.增加額外的數(shù)據(jù)文件到表空間中
例如:alter tablespace users add datafile '/u01/oradata/orcl/users02.dbf' size 25m;
2.修改表空間當(dāng)前的數(shù)據(jù)文件
例如:alter database datafile
'/u01/oradata/orcl/users01.dbf' resize 50m;
問(wèn):請(qǐng)問(wèn)如何在report中設(shè)置動(dòng)態(tài)顯示域?
答:在report中設(shè)置動(dòng)態(tài)顯示域的方法如下:
1. 在report的“數(shù)據(jù)模型”下面的“用戶參數(shù)”中,創(chuàng)建用戶自定義參數(shù),如rq,rq是從form傳遞過(guò)來(lái)的顯示日期,數(shù)據(jù)類型為字符型。
2. 在布局模型中,創(chuàng)建一個(gè)顯示域f_1,在屬性選項(xiàng)板中修改該顯示域的源為用戶自定義參數(shù)rq,并且設(shè)為“不可見的”。
3. 在動(dòng)態(tài)預(yù)覽中,創(chuàng)建一個(gè)文本域d_1,調(diào)整該文本域的位置和寬度,在該域的內(nèi)容中輸入&&f_1,則該域會(huì)動(dòng)態(tài)顯示用戶定義參數(shù)rq的值。
問(wèn):有關(guān)口令
我在solaris系統(tǒng)上運(yùn)行 oracle8i 8.1.7企業(yè)版。我創(chuàng)建了兩個(gè)數(shù)據(jù)庫(kù):sugar和testdb。將兩者的remote_login_passwordfile都設(shè)置為 “獨(dú)占(exclusive)”。我試圖以sysdba身份連接到testdb,但未能成功。下面是我的做法:
$sqlplus /nolog
sql> conn sys/[email protected]
connected.(已連接)
sql> select * from v$pwfile_users;
username sysdb sysop
-----------------------------------------
internal true true
sys true true
sql> conn sys/[email protected] as
sysdba
error(錯(cuò)誤)
ora-01017: invalid username/password; logon
denied(無(wú)效的用戶名/口令,登錄被拒絕)
warning: you are on longer connected to
oracle(警告:你已經(jīng)與oracle斷開連接)
我為什么不能以sysdba身份連接到testdb?
答:通常oracle中的sys口令與internal口令是同步的,sys口令存儲(chǔ)于口令文件中。在上述情況下你建立了包含有一個(gè)口令的口令文件,而不是使用缺省的 “change_on_install,”這就是問(wèn)題之所在。
希望下面的方法對(duì)你有所幫助。首先,建立一個(gè)口令文件,其中包含一個(gè)口令,這個(gè)口令不要與系統(tǒng)口令匹配:
$ orapwd file=orapw password=foobar
entries=40
然后,進(jìn)入服務(wù)器,啟動(dòng)數(shù)據(jù)庫(kù):
$ svrmgr
svrmgr> connect internal
connected.(已連接)
svrmgr> startup
oracle instance started.(oracle 實(shí)例已啟動(dòng))
total system global area (系統(tǒng)全局區(qū)域大小)
193073136 bytes
fixed size (固定大小)
69616 bytes
variable size (可變大小)
141639680 bytes
database buffers (數(shù)據(jù)庫(kù)緩沖區(qū))
45056000 bytes
redo buffers (重做緩沖區(qū))
6307840 bytes
database mounted. (數(shù)據(jù)庫(kù)已加載)
database opened.數(shù)據(jù)庫(kù)已打開。
現(xiàn)在使用sys用戶的口令,以sys身份連接:
svrmgr> connect sys/[email protected]
connected.(已連接)
成功了。現(xiàn)在試著以sysdba身份連接:
svrmgr> connect sys/[email protected]
as sysdba;
ora-01017: invalid username/password; logon
denied(無(wú)效的用戶名/口令;登錄被拒絕)
這里出現(xiàn)了你所說(shuō)的錯(cuò)誤。你的sys口令為:change_on_install,但口令文件中的口令卻是foobar。sys用戶是專用的,以sysdba身份連接就像是以internal連接,你必須使用口令文件中的口令。試試這樣做:
svrmgr— connect sys/[email protected] as sysdba;
connected.(已連接)
并不是每個(gè)人都需要使用口令文件中的口令;用戶需要使用他們自己的口令。通過(guò)授權(quán)sysdba給scott,你就可以明白這一點(diǎn):
svrmgr> grant sysdba to scott;
statement processed.(已處理)
這個(gè)命令將scott以scott的憑證加入到口令文件中。如果你改變了scott的口令,口令文件也會(huì)自動(dòng)同步改變。現(xiàn)在,你可以試試以sysdba身份連接scott了:
svrmgr> connect scott/[email protected] as sysdba;
connected.(已連接)
一切正常。現(xiàn)在可以使用alter user 命令來(lái)改變sys用戶的口令。
svrmgr> alter user sys identified by
change_on_install;
statement processed.(已成功更改)
svrmgr> connect sys/[email protected]
as sysdba;
connected.(已連接)
你還可以用change_on_install,因?yàn)楦淖僺ys用戶口令將同時(shí)改變口令文件中的口令。當(dāng)你建立了口令文件后,oracle數(shù)據(jù)庫(kù)在其中放入兩個(gè)賬號(hào):sys和internal,并將你在命令行中提供的口令作為這兩個(gè)賬戶的口令。當(dāng)你改變數(shù)據(jù)庫(kù)中的sys用戶口令時(shí),數(shù)據(jù)庫(kù)將沖掉口令文件中的sys和internal口令。下面操作將顯示口令foobar已經(jīng)是無(wú)效的了:
svrmgr> connect sys/[email protected] as sysdba;
ora-01017: invalid username/password; logon
denied(無(wú)效的用戶名/口令,登錄被拒絕)
問(wèn):利用query選項(xiàng)輸出數(shù)據(jù)
我知道在oracle8i中,可以使用query有選擇地輸出表數(shù)據(jù)。我想用exp命令來(lái)實(shí)現(xiàn),但沒(méi)有成功。下面是我所寫的命令,以及得到的錯(cuò)誤信息:
exp ddd/ddd file=/dbf/u11/customer.dmp
tables=aasc.ast_customer_keep
query=/'where cua_trans_dts /<
add_months/(sysdate, -6/)/'
table_export[2]: cua_trans_dts: not found.(沒(méi)有找到)
答:操作系統(tǒng)不同,用來(lái)指定query=參數(shù)的方法也不同。where 語(yǔ)句里面往往有很多特殊的字符,如=.>.<和空格等等。而unix和windows操作系統(tǒng)中的外殼命令提示是不歡迎這些字符的,這些字符將被忽略。你應(yīng)該根據(jù)不同的操作系統(tǒng)采用不用的方法。我一般使用帶有query選項(xiàng)的參數(shù)文件(parfile),利用parfile,可以不考慮操作系統(tǒng)平臺(tái)而使用完全相同的方法。
下面給出一個(gè)例子。我用select * from all_objects建立了一個(gè)表t,我希望輸出所有object_id 小于5000的行。在windows中,必須這樣做:
c:/exp>exp userid=tkyte/tkyte tables=t
query="""where object_id < 5000"""
注意:在windows中,需要在where語(yǔ)句的兩端使用三個(gè)雙引號(hào)。在unix中,必須這樣做:
$ exp userid=/ tables=t query=/"where
object_id /< 5000/"
exp userid=/ tables=t parfile=exp.par
如果使用包含query="where object_id < 5000"的parfile文件,我可以在兩個(gè)系統(tǒng)中使用相同的一個(gè)命令:
exp userid=/ tables=t parfile=exp.par
在兩種操作系統(tǒng)中,完全相同。這相對(duì)于在不同的平臺(tái)中使用不同的query字符串容易多了。
問(wèn):dbms_random
您能否告訴我寫一個(gè)能產(chǎn)生大于0小于1的隨機(jī)數(shù)的隨機(jī)數(shù)產(chǎn)生器的最好方法?
答:oracle8 8.0版介紹了dbms_random包,oracle8i 8.1.6版介紹了dbms_random包的新功能,但oracle8i 文檔中沒(méi)有詳細(xì)全面介紹其功能。幸運(yùn)的是:有一個(gè)新的dbms_random包函數(shù)能夠返回0-1之間的隨機(jī)數(shù)。這個(gè)新函數(shù)是:
function value return number;
function value (low in number, high in
number) return number;
function normal return number;
function string (opt char, len number)
return varchar2;
value函數(shù)的第一種形式返回一個(gè)大于或等于0且小于1的隨機(jī)數(shù);第二種形式返回一個(gè)大于或等于low,小于high的隨機(jī)數(shù)。下面是其用法的一個(gè)示例:
sql> select dbms_random.value,
dbms_random.value(55,100)
2 from dual;
value dbms_random.value(55,100)
--------------- -----------------------------
.782821936 79.6367038
normal函數(shù)返回服從正態(tài)分布的一組數(shù)。此正態(tài)分布標(biāo)準(zhǔn)偏差為1,期望值為0。這個(gè)函數(shù)返回的數(shù)值中有68%是介于-1與+1之間,95%介于-2與+2之間,99%介于-3與+3之間。事實(shí)上,這就是你在清單1中所看到的。
最后,是string函數(shù)。它返回一個(gè)長(zhǎng)度達(dá)60個(gè)字符的隨機(jī)字符串。參數(shù)opt可以是清單2顯示的值中的任何一個(gè)單個(gè)字符。
關(guān)于這些函數(shù)及dbms_random包的文件都包含在sqlplus中:
select text
from all_source
where name = 'dbms_random'
and type = 'package' order by line;
問(wèn):連接次序與謂詞求值
在下面的查詢中,where 語(yǔ)句的哪一部分先執(zhí)行?
select field names from emp, dept
where emp.dept_num = dept.num and
emp.name like 's%' and dept.name='it';
答:執(zhí)行次序隨已有的索引、統(tǒng)計(jì)、和session/init.ora參數(shù)的不同而變化。
假定已有一個(gè)建立在dept(name)和emp(dept_num)上的索引。假定優(yōu)化器認(rèn)為dept是唯一的,它可能按下面的順序進(jìn)行操作:
利用建立在dept(name)上的索引查找dept列
利用建立在emp(dept_num)上的索引查找匹配的emp列(即連接emp.dept_num = dept.num)
依據(jù)建立在emp.ename like 's%'進(jìn)行過(guò)濾
現(xiàn)在,我們假定沒(méi)有建立在emp(dept_num)上的索引,也沒(méi)有建立在dept(name)上的索引,而存在建立在emp(name)和dept(num)上的索引。優(yōu)化器可能按下面的次序進(jìn)行操作:
利用建立在emp(name)上的索引找到帶有s的emps
利用建立在dept(num)上的索引找到匹配項(xiàng)
根據(jù)dept.name = 'it'過(guò)濾結(jié)果
謂詞求值的次序是不確定的,可以隨時(shí)間的改變而改變,并由優(yōu)化器決定。不要假定任何事情會(huì)按一定的次序發(fā)生。如果你那么做,隨著時(shí)間的推移,你的應(yīng)用程序可能會(huì)出現(xiàn)一些看起來(lái)非常奇怪的錯(cuò)誤。看以下的例子:建立一個(gè)表,輸入一些數(shù)據(jù)。當(dāng)x='a’時(shí),第二列的數(shù)據(jù)“y”是一個(gè)數(shù)值,當(dāng)x='b’時(shí),“y”不是數(shù)字。
sql> create table t ( x varchar2(1), y varchar2(1) );
table created.
sql> insert into t values ( 'a', '1' );
1 row created.
sql> insert into t values ( 'b', 'x' );
1 row created.
現(xiàn)在根據(jù)這個(gè)表運(yùn)行一個(gè)查詢:查找滿足x='a',y=1的行。
sql> select * from t where x = 'a' and
y = 1;
error:
ora-01722: invalid number
no rows selected(錯(cuò)誤,無(wú)效的數(shù)字,沒(méi)有選擇任何行)
呦,沒(méi)有成功。在這種情況下,數(shù)據(jù)庫(kù)首先執(zhí)行y=1,當(dāng)找到y(tǒng)='x'的行后,很顯然,它不能將'x'轉(zhuǎn)換為一個(gè)數(shù)字,所以失敗了。而下面的程序?qū)⒔o出不同的結(jié)果:
sql> analyze table t compute statistics;
table analyzed.(表已經(jīng)分析過(guò))
sql> select * from t where x = 'a' and
y = 1;
x y
- -
a 1
使用不同的優(yōu)化器模式,成功了!為什么??jī)?yōu)化器說(shuō):“嘿,檢查x= 'a'要比檢查y=1來(lái)得快,因?yàn)樵趛=1中有一個(gè)將y從字符變?yōu)閿?shù)字的轉(zhuǎn)換。所以,我先檢查x= 'a',然后再檢查y=1。”
這個(gè)例子說(shuō)明謂詞執(zhí)行的次序可能是不確定的,你不能指望有一種特定的執(zhí)行次序。也就是說(shuō),當(dāng)你依靠一個(gè)隱含的轉(zhuǎn)換時(shí),必須非常謹(jǐn)慎。
問(wèn):顯示sga--fixed size(固定大小)與variable size(可變大小)
當(dāng)在svrmgr提示符下運(yùn)行 “show sga”時(shí),fixed size和variable size是什么意思?
答:fixed size就是sga中固定組件(它在編譯oracle 數(shù)據(jù)庫(kù)本身時(shí)就固定于其中)的大小。它是固定大小的內(nèi)存,用來(lái)指向sga的其它部分。sga這一部分的大小是不能改變的。
variable size指分配的內(nèi)存塊大小可變。sga的可變塊,分為共享池、大池、java池、游標(biāo)區(qū)和其他結(jié)構(gòu)。