Oracle数据库常见问题答疑.docx
《Oracle数据库常见问题答疑.docx》由会员分享,可在线阅读,更多相关《Oracle数据库常见问题答疑.docx(13页珍藏版)》请在冰点文库上搜索。
Oracle数据库常见问题答疑
Oracle数据库常见问题答疑
Oracle数据库以其强大的功能和稳定性而著称,但同时,在开发和管理方面也存在很多困难,笔者在此总结了一些Oracle数据库开发和管理的常见问题,希望能对大家有所帮助。
问:
如果发现表中有坏块,如何检索其它未坏的数据?
答:
首先需要找到坏块的ID(可以运行dbverify实现),假设为1234。
运行下面的查询查找段名:
selectsegment_name,segment_type,block_id,blocks
fromdba_extents
where(1234betweenblock_idand(block_id+blocks-1));
一旦找到坏段名称,若段是一个表,则最好建立一个临时表,存放好的数据。
若段是索引,则删除它,再重建。
createtablegood_table
as
selectfrombad_tablewhererowidnotin
(select/+index(bad_table,any_index)/rowid
frombad_tablewheresubstr(rowid,1,8)=1234)
问:
如请问如何关闭FORM调用REPORT时的小窗口?
答:
在利用Oracle数据库的Develop2000设计开发界面的过程中,当FORM调用REPORT时,会显示一个背景窗口REPORTBACKGROUDENGINE,等待FORM对REPORT的调用,当FORM调用其它REPORT时,也使用这个后台服务器,不论调用多少个REPORT,这个后台服务器存在且只有一个。
但当FORM与REPORT全部退出后,该窗口仍处于等待状态,不会关闭,这时,我们需要手工将其关闭。
我们可以使用以下参数在FORM调用REPORT时不显示这个小窗口:
Add_Parameter(pl_id,'ORACLE_SHUTDOWN',TEXT_Parameter,'Yes');
需要注意的是,该参数必须加在所有参数的前面,即它必须为第一个参数。
问:
请问如何根据查询条件在REPORT中动态显示记录?
答:
1.在REPORT的“数据模型”下面的“用户参数”中,创建用户自定义参数W_CLAUSE,W_CLAUSE为从FORM传递过来的查询条件,数据类型为字符型,缺省值为NULL。
2.修改查询Q_1,将SQL查询语句修改为selectfromdept&&w_clause。
3.在运行报表时,报表会自动将符合&&w_clause的查询条件记录显示出来。
如果从FORM传递过来的w_clause为wheredept=1,本报表的SQL查询自动转换为selectfromdeptwheredept=1,并在报表运行结果中显示符合该查询条件的记录,如果从FORM传递过来的w_cluase为whereto_char(年度,'YYYY.MM')='2000.03',则在报表运行结果中自动显示2000年3月份的记录。
问:
在Oracle中,我们如何查看某表上的约束?
答:
我们可以使用下面语句从all_constraints视图中查看某表上的约束:
SELECTconstraint_name,table_name,r_owner,r_constraint_name
FROMall_constraints
WHEREtable_name='table_name'andowner='owner_name';
另一个视图ALL_CONS_COLUMNS也包括组成表上约束列的信息。
问:
如何将数据库从noarchivelog方式改变为archivelog方式?
答:
首先打开Init.ora文件,确保存档日志目标指向一有效目录。
然后启动ServerManager
svrmgrl〉shutdownimmediate
svrmgrl〉startupmount
svrmgrl〉alterdatabasearchivelog;
svrmgrl〉alterdatabaseopen;
svrmgrl〉archiveloglist;
在init.ora中设置参数archive_log_start=TRUE,它设置存档日志为自动启动。
在Oracle8i中支持多个存档日志的目标,因此参数修改为log_archive_dest[n],其中n为1到5。
问:
在Oracle数据库中,我们如何增加表空间的大小?
答:
在开发Oracle数据库中,我们有两种方法增加表空间的大小:
1.增加额外的数据文件到表空间中
例如:
altertablespaceusersadddatafile'/u01/oradata/orcl/users02.dbf'size25m;
2.修改表空间当前的数据文件
例如:
alterdatabasedatafile
'/u01/oradata/orcl/users01.dbf'resize50M;
问:
请问如何在REPORT中设置动态显示域?
答:
在REPORT中设置动态显示域的方法如下:
1.在REPORT的“数据模型”下面的“用户参数”中,创建用户自定义参数,如RQ,RQ是从FORM传递过来的显示日期,数据类型为字符型。
2.在布局模型中,创建一个显示域F_1,在属性选项板中修改该显示域的源为用户自定义参数RQ,并且设为“不可见的”。
3.在动态预览中,创建一个文本域D_1,调整该文本域的位置和宽度,在该域的内容中输入&&F_1,则该域会动态显示用户定义参数RQ的值。
问:
有关口令
我在Solaris系统上运行Oracle8i8.1.7企业版。
我创建了两个数据库:
SUGAR和TestDb。
将两者的remote_login_passwordfile都设置为“独占(exclusive)”。
我试图以SYSDBA身份连接到TestDb,但未能成功。
下面是我的做法:
$sqlplus/nolog
SQL>connsys/change_on_install@testdb
Connected.(已连接)
SQL>select*fromv$pwfile_users;
usernamesysdbsysop
-----------------------------------------
internaltruetrue
systruetrue
SQL>connsys/change_on_install@testdbas
sysdba
ERROR(错误)
ORA-01017:
invalidusername/password;logon
denied(无效的用户名/口令,登录被拒绝)
Warning:
Youareonlongerconnectedto
ORACLE(警告:
你已经与ORACLE断开连接)
我为什么不能以SYSDBA身份连接到TestDb?
答:
通常Oracle中的SYS口令与INTERNAL口令是同步的,SYS口令存储于口令文件中。
在上述情况下你建立了包含有一个口令的口令文件,而不是使用缺省的“change_on_install,”这就是问题之所在。
希望下面的方法对你有所帮助。
首先,建立一个口令文件,其中包含一个口令,这个口令不要与系统口令匹配:
$orapwdfile=orapwpassword=foobar
entries=40
然后,进入服务器,启动数据库:
$svrmgr
SVRMGR>connectinternal
Connected.(已连接)
SVRMGR>startup
ORACLEinstancestarted.(ORACLE实例已启动)
TotalSystemGlobalArea(系统全局区域大小)
193073136bytes
FixedSize(固定大小)
69616bytes
VariableSize(可变大小)
141639680bytes
DatabaseBuffers(数据库缓冲区)
45056000bytes
RedoBuffers(重做缓冲区)
6307840bytes
Databasemounted.(数据库已加载)
Databaseopened.数据库已打开。
现在使用SYS用户的口令,以SYS身份连接:
SVRMGR>connectsys/change_on_install@ora81
Connected.(已连接)
成功了。
现在试着以SYSDBA身份连接:
SVRMGR>connectsys/change_on_install@ora81
assysdba;
ORA-01017:
invalidusername/password;logon
denied(无效的用户名/口令;登录被拒绝)
这里出现了你所说的错误。
你的SYS口令为:
change_on_install,但口令文件中的口令却是foobar。
SYS用户是专用的,以SYSDBA身份连接就像是以INTERNAL连接,你必须使用口令文件中的口令。
试试这样做:
SVRMGR—connectsys/foobar@ora81assysdba;
Connected.(已连接)
并不是每个人都需要使用口令文件中的口令;用户需要使用他们自己的口令。
通过授权SYSDBA给SCOTT,你就可以明白这一点:
SVRMGR>grantsysdbatoscott;
Statementprocessed.(已处理)
这个命令将SCOTT以SCOTT的凭证加入到口令文件中。
如果你改变了SCOTT的口令,口令文件也会自动同步改变。
现在,你可以试试以SYSDBA身份连接SCOTT了:
SVRMGR>connectscott/tiger@ora81assysdba;
Connected.(已连接)
一切正常。
现在可以使用ALTERUSER命令来改变SYS用户的口令。
SVRMGR>alterusersysidentifiedby
change_on_install;
Statementprocessed.(已成功更改)
SVRMGR≫connectsys/change_on_install@ora81
assysdba;
Connected.(已连接)
你还可以用change_on_install,因为改变SYS用户口令将同时改变口令文件中的口令。
当你建立了口令文件后,Oracle数据库在其中放入两个账号:
SYS和INTERNAL,并将你在命令行中提供的口令作为这两个账户的口令。
当你改变数据库中的SYS用户口令时,数据库将冲掉口令文件中的SYS和INTERNAL口令。
下面操作将显示口令foobar已经是无效的了:
SVRMGR>connectsys/foobar@ora81assysdba;
ORA-01017:
invalidusername/password;logon
denied(无效的用户名/口令,登录被拒绝)
问:
利用QUERY选项输出数据
我知道在Oracle8i中,可以使用QUERY有选择地输出表数据。
我想用EXP命令来实现,但没有成功。
下面是我所写的命令,以及得到的错误信息:
expddd/dddfile=/dbf/u11/customer.dmp
tables=AASC.AST_CUSTOMER_KEEP
query=\'whereCUA_TRANS_DTS\<
add_months\(sysdate,-6\)\'
table_export[2]:
CUA_TRANS_DTS:
notfound.(没有找到)
答:
操作系统不同,用来指定QUERY=参数的方法也不同。
WHERE语句里面往往有很多特殊的字符,如=.>.<和空格等等。
而UNIX和Windows操作系统中的外壳命令提示是不欢迎这些字符的,这些字符将被忽略。
你应该根据不同的操作系统采用不用的方法。
我一般使用带有QUERY选项的参数文件(PARFILE),利用PARFILE,可以不考虑操作系统平台而使用完全相同的方法。
下面给出一个例子。
我用select*fromall_objects建立了一个表T,我希望输出所有object_id小于5000的行。
在Windows中,必须这样做:
C:
\exp>expuserid=tkyte/tkytetables=t
query="""whereobject_id<5000"""
注意:
在windows中,需要在WHERE语句的两端使用三个双引号。
在UNIX中,必须这样做:
$expuserid=/tables=tquery=\"where
object_id\<5000\"
expuserid=/tables=tparfile=exp.par
如果使用包含query="whereobject_id<5000"的PARFILE文件,我可以在两个系统中使用相同的一个命令:
expuserid=/tables=tparfile=exp.par
在两种操作系统中,完全相同。
这相对于在不同的平台中使用不同的QUERY字符串容易多了。
问:
DBMS_RANDOM
您能否告诉我写一个能产生大于0小于1的随机数的随机数产生器的最好方法?
答:
Oracle88.0版介绍了DBMS_RANDOM包,Oracle8i8.1.6版介绍了DBMS_RANDOM包的新功能,但Oracle8i文档中没有详细全面介绍其功能。
幸运的是:
有一个新的DBMS_RANDOM包函数能够返回0-1之间的随机数。
这个新函数是:
FUNCTIONvalueRETURNNUMBER;
FUNCTIONvalue(lowINNUMBER,highIN
NUMBER)RETURNNUMBER;
FUNCTIONnormalRETURNNUMBER;
FUNCTIONstring(optchar,lenNUMBER)
RETURNVARCHAR2;
VALUE函数的第一种形式返回一个大于或等于0且小于1的随机数;第二种形式返回一个大于或等于LOW,小于HIGH的随机数。
下面是其用法的一个示例:
SQL>selectdbms_random.value,
dbms_random.value(55,100)
2fromdual;
VALUEDBMS_RANDOM.VALUE(55,100)
--------------------------------------------
.78282193679.6367038
NORMAL函数返回服从正态分布的一组数。
此正态分布标准偏差为1,期望值为0。
这个函数返回的数值中有68%是介于-1与+1之间,95%介于-2与+2之间,99%介于-3与+3之间。
事实上,这就是你在清单1中所看到的。
最后,是STRING函数。
它返回一个长度达60个字符的随机字符串。
参数OPT可以是清单2显示的值中的任何一个单个字符。
关于这些函数及DBMS_RANDOM包的文件都包含在SQLPlus中:
selecttext
fromall_source
wherename='DBMS_RANDOM'
andtype='PACKAGE'orderbyline;
问:
连接次序与谓词求值
在下面的查询中,WHERE语句的哪一部分先执行?
Selectfieldnamesfromemp,dept
whereemp.dept_num=dept.numand
emp.nameLike'S%'anddept.name='IT';
答:
执行次序随已有的索引、统计、和session/init.ora参数的不同而变化。
假定已有一个建立在DEPT(name)和EMP(dept_num)上的索引。
假定优化器认为DEPT是唯一的,它可能按下面的顺序进行操作:
利用建立在DEPT(name)上的索引查找dept列
利用建立在EMP(dept_num)上的索引查找匹配的emp列(即连接emp.dept_num=dept.num)
依据建立在emp.enamelike'S%'进行过滤
现在,我们假定没有建立在EMP(dept_num)上的索引,也没有建立在DEPT(name)上的索引,而存在建立在EMP(name)和DEPT(num)上的索引。
优化器可能按下面的次序进行操作:
利用建立在EMP(name)上的索引找到带有S的EMPS
利用建立在DEPT(num)上的索引找到匹配项
根据dept.name='IT'过滤结果
谓词求值的次序是不确定的,可以随时间的改变而改变,并由优化器决定。
不要假定任何事情会按一定的次序发生。
如果你那么做,随着时间的推移,你的应用程序可能会出现一些看起来非常奇怪的错误。
看以下的例子:
建立一个表,输入一些数据。
当X='a’时,第二列的数据“Y”是一个数值,当X='b’时,“Y”不是数字。
SQL>createtablet(xvarchar2
(1),yvarchar2
(1));
Tablecreated.
SQL>insertintotvalues('a','1');
1rowcreated.
SQL>insertintotvalues('b','x');
1rowcreated.
现在根据这个表运行一个查询:
查找满足x='a',y=1的行。
SQL>select*fromtwherex='a'and
y=1;
ERROR:
ORA-01722:
invalidnumber
norowsselected(错误,无效的数字,没有选择任何行)
呦,没有成功。
在这种情况下,数据库首先执行Y=1,当找到Y='X'的行后,很显然,它不能将'X'转换为一个数字,所以失败了。
而下面的程序将给出不同的结果:
SQL>analyzetabletcomputestatistics;
Tableanalyzed.(表已经分析过)
SQL>select*fromtwherex='a'and
y=1;
XY
--
a1
使用不同的优化器模式,成功了!
为什么?
优化器说:
“嘿,检查x='a'要比检查y=1来得快,因为在y=1中有一个将y从字符变为数字的转换。
所以,我先检查x='a',然后再检查y=1。
”
这个例子说明谓词执行的次序可能是不确定的,你不能指望有一种特定的执行次序。
也就是说,当你依靠一个隐含的转换时,必须非常谨慎。
问:
显示SGA--fixedsize(固定大小)与variablesize(可变大小)
当在svrmgr提示符下运行“showSGA”时,fixedsize和variablesize是什么意思?
答:
fixedsize就是SGA中固定组件(它在编译oracle数据库本身时就固定于其中)的大小。
它是固定大小的内存,用来指向SGA的其它部分。
SGA这一部分的大小是不能改变的。
variablesize指分配的内存块大小可变。
SGA的可变块,分为共享池、大池、JAVA池、游标区和其他结构。