阅读:3326回复:3
Oracle数据库常见问题答疑
<P>Oracle数据库以其强大的功能和稳定性而著称,但同时,在开发和管理方面也存在很多困难,笔者在此总结了一些Oracle数据库开发和管理的常见问题,希望能对大家有所帮助。 </P>
<P>问:如果发现表中有坏块,如何检索其它未坏的数据? </P> <P>答:首先需要找到坏块的ID(可以运行dbverify实现),假设为1234。运行下面的查询查找段名: </P> <P>select segment_name, segment_type, block_id, blocks </P> <P>from dba_extents </P> <P>where (1234 between block_id and (block_id + blocks - 1)); </P> <P>一旦找到坏段名称,若段是一个表,则最好建立一个临时表,存放好的数据。若段是索引,则删除它,再重建。 </P> <P>create table good_table </P> <P>as </P> <P>select ? from bad_table where rowid not in </P> <P>( select /?+index(bad_table, any_index)?/ rowid </P> <P>from bad_table where substr( rowid, 1, 8 ) = 1234) </P> <P>问:如请问如何关闭FORM调用REPORT时的小窗口? </P> <P>答:在利用Oracle数据库的Develop 2000设计开发界面的过程中,当FORM调用REPORT时,会显示一个背景窗口REPORT BACKGROUD ENGINE,等待FORM对REPORT的调用,当FORM调用其它REPORT时,也使用这个后台服务器,不论调用多少个REPORT,这个后台服务器存在且只有一个。但当FORM与REPORT全部退出后,该窗口仍处于等待状态,不会关闭,这时,我们需要手工将其关闭。 </P> <P>我们可以使用以下参数在FORM调用REPORT时不显示这个小窗口: </P> <P>Add_Parameter( pl_id, 'ORACLE_SHUTDOWN',TEXT_Parameter, 'Yes' ); </P> <P>需要注意的是,该参数必须加在所有参数的前面,即它必须为第一个参数。 </P> <P>问:请问如何根据查询条件在REPORT中动态显示记录? </P> <P>答:1. 在REPORT的“数据模型”下面的“用户参数”中,创建用户自定义参数W_CLAUSE,W_CLAUSE为从FORM传递过来的查询条件,数据类型为字符型,缺省值为NULL。 </P> <P>2. 修改查询Q_1,将SQL查询语句修改为select ? from dept ;;w_clause。 </P> <P>3. 在运行报表时,报表会自动将符合;;w_clause的查询条件记录显示出来。 </P> <P>如果从FORM传递过来的w_clause为where dept=1,本报表的SQL查询自动转换为select ? from dept where dept=1,并在报表运行结果中显示符合该查询条件的记录,如果从FORM传递过来的w_cluase为where to_char(年度,'YYYY.MM')='2000.03',则在报表运行结果中自动显示2000年3月份的记录。 </P> <P>问:在Oracle中,我们如何查看某表上的约束? </P> <P>答:我们可以使用下面语句从all_constraints视图中查看某表上的约束: </P> <P>SELECT constraint_name, table_name, r_owner, r_constraint_name </P> <P>FROM all_constraints </P> <P>WHERE table_name = 'table_name' and owner = 'owner_name'; </P> <P>另一个视图ALL_CONS_COLUMNS也包括组成表上约束列的信息。 </P> <P>问:如何将数据库从noarchivelog方式改变为archivelog方式? </P> <P>答:首先打开Init.ora文件,确保存档日志目标指向一有效目录。 </P> <P>然后启动Server Manager </P> <P>svrmgrl〉 shutdown immediate </P> <P>svrmgrl〉 startup mount </P> <P>svrmgrl〉 alter database archivelog; </P> <P>svrmgrl〉 alter database open; </P> <P>svrmgrl〉 archive log list; </P> <P>在init.ora中设置参数archive_log_start=TRUE,它设置存档日志为自动启动。在Oracle 8i中支持多个存档日志的目标,因此参数修改为log_archive_dest[n],其中n为1到5。 </P> <P>问:在Oracle数据库中,我们如何增加表空间的大小? </P> <P>答: 在开发Oracle数据库中,我们有两种方法增加表空间的大小: </P> <P>1.增加额外的数据文件到表空间中 </P> <P>例如:alter tablespace users add datafile '/u01/oradata/orcl/users02.dbf' size 25m; </P> <P>2.修改表空间当前的数据文件 </P> <P>例如:alter database datafile </P> <P>'/u01/oradata/orcl/users01.dbf' resize 50M; </P> <P>问:请问如何在REPORT中设置动态显示域? </P> <P>答:在REPORT中设置动态显示域的方法如下: </P> <P>1. 在REPORT的“数据模型”下面的“用户参数”中,创建用户自定义参数,如RQ,RQ是从FORM传递过来的显示日期,数据类型为字符型。 </P> <P>2. 在布局模型中,创建一个显示域F_1,在属性选项板中修改该显示域的源为用户自定义参数RQ,并且设为“不可见的”。 </P> <P>3. 在动态预览中,创建一个文本域D_1,调整该文本域的位置和宽度,在该域的内容中输入;;F_1,则该域会动态显示用户定义参数RQ的值。 </P> <P>问:有关口令 </P> <P>我在Solaris系统上运行 Oracle8i 8.1.7企业版。我创建了两个数据库:SUGAR和TestDb。将两者的remote_login_passwordfile都设置为 “独占(exclusive)”。我试图以SYSDBA身份连接到TestDb,但未能</P> |
|
|
1楼#
发布于:2005-09-18 01:08
成功。下面是我的做法:
<br> <P>$sqlplus /nolog </P> <P>SQL> conn <a href="mailtsys/change_on_install@testdb" target="_blank" >sys/change_on_install@testdb</A> </P> <P>Connected.(已连接) </P> <P>SQL> select * from v$pwfile_users; </P> <P>username sysdb sysop </P> <P>----------------------------------------- </P> <P>internal true true </P> <P>sys true true </P> <P>SQL> conn <a href="mailtsys/change_on_install@testdb" target="_blank" >sys/change_on_install@testdb</A> as </P> <P>sysdba </P> <P>ERROR(错误) </P> <P>ORA-01017: invalid username/password; logon </P> <P>denied(无效的用户名/口令,登录被拒绝) </P> <P>Warning: You are on longer connected to </P> <P>ORACLE(警告:你已经与ORACLE断开连接) </P> <P>我为什么不能以SYSDBA身份连接到TestDb? </P> <P>答:通常Oracle中的SYS口令与INTERNAL口令是同步的,SYS口令存储于口令文件中。在上述情况下你建立了包含有一个口令的口令文件,而不是使用缺省的 “change_on_install,”这就是问题之所在。 </P> <P>希望下面的方法对你有所帮助。首先,建立一个口令文件,其中包含一个口令,这个口令不要与系统口令匹配: </P> <P>$ orapwd file=orapw password=foobar </P> <P>entries=40 </P> <P>然后,进入服务器,启动数据库: </P> <P>$ svrmgr </P> <P>SVRMGR> connect internal </P> <P>Connected.(已连接) </P> <P>SVRMGR> startup </P> <P>ORACLE instance started.(ORACLE 实例已启动) </P> <P>Total System Global Area (系统全局区域大小) </P> <P>193073136 bytes </P> <P>Fixed Size (固定大小) </P> <P>69616 bytes </P> <P>Variable Size (可变大小) </P> <P>141639680 bytes </P> <P>Database Buffers (数据库缓冲区) </P> <P>45056000 bytes </P> <P>Redo Buffers (重做缓冲区) </P> <P>6307840 bytes </P> <P>Database mounted. (数据库已加载) </P> <P>Database opened.数据库已打开。 </P> <P>现在使用SYS用户的口令,以SYS身份连接: </P> <P>SVRMGR> connect <a href="mailtsys/change_on_install@ora81" target="_blank" >sys/change_on_install@ora81</A> </P> <P>Connected.(已连接) </P> <P>成功了。现在试着以SYSDBA身份连接: </P> <P>SVRMGR> connect <a href="mailtsys/change_on_install@ora81" target="_blank" >sys/change_on_install@ora81</A> </P> <P>as sysdba; </P> <P>ORA-01017: invalid username/password; logon </P> <P>denied(无效的用户名/口令;登录被拒绝) </P> <P>这里出现了你所说的错误。你的SYS口令为:change_on_install,但口令文件中的口令却是foobar。SYS用户是专用的,以SYSDBA身份连接就像是以INTERNAL连接,你必须使用口令文件中的口令。试试这样做: </P> <P>SVRMGR— connect <a href="mailtsys/foobar@ora81" target="_blank" >sys/foobar@ora81</A> as sysdba; </P> <P>Connected.(已连接) </P> <P>并不是每个人都需要使用口令文件中的口令;用户需要使用他们自己的口令。通过授权SYSDBA给SCOTT,你就可以明白这一点: </P> <P>SVRMGR> grant sysdba to scott; </P> <P>Statement processed.(已处理) </P> <P>这个命令将SCOTT以SCOTT的凭证加入到口令文件中。如果你改变了SCOTT的口令,口令文件也会自动同步改变。现在,你可以试试以SYSDBA身份连接SCOTT了: </P> <P>SVRMGR> connect <a href="mailtscott/tiger@ora81" target="_blank" >scott/tiger@ora81</A> as sysdba; </P> <P>Connected.(已连接) </P> <P>一切正常。现在可以使用ALTER USER 命令来改变SYS用户的口令。 </P> <P>SVRMGR> alter user sys identified by </P> <P>change_on_install; </P> <P>Statement processed.(已成功更改) </P> <P>SVRMGR;Gt; connect <a href="mailtsys/change_on_install@ora81" target="_blank" >sys/change_on_install@ora81</A> </P> <P>as sysdba; </P> <P>Connected.(已连接) </P> <P>你还可以用change_on_install,因为改变SYS用户口令将同时改变口令文件中的口令。当你建立了口令文件后,Oracle数据库在其中放入两个账号:SYS和INTERNAL,并将你在命令行中提供的口令作为这两个账户的口令。当你改变数据库中的SYS用户口令时,数据库将冲掉口令文件中的SYS和INTERNAL口令。下面操作将显示口令foobar已经是无效的了: </P> <P>SVRMGR> connec</P> |
|
|
2楼#
发布于:2005-09-18 01:08
t <a href="mailtsys/foobar@ora81" target="_blank" >sys/foobar@ora81</A> as sysdba;
<br> <P>ORA-01017: invalid username/password; logon </P> <P>denied(无效的用户名/口令,登录被拒绝) </P> <P>问:利用QUERY选项输出数据 </P> <P>我知道在Oracle8i中,可以使用QUERY有选择地输出表数据。我想用EXP命令来实现,但没有成功。下面是我所写的命令,以及得到的错误信息: </P> <P>exp ddd/ddd file=/dbf/u11/customer.dmp </P> <P>tables=AASC.AST_CUSTOMER_KEEP </P> <P>query=\'where CUA_TRANS_DTS \< </P> <P>add_months\(sysdate, -6\)\' </P> <P>table_export[2]: CUA_TRANS_DTS: not found.(没有找到) </P> <P>答:操作系统不同,用来指定QUERY=参数的方法也不同。WHERE 语句里面往往有很多特殊的字符,如=.>.<和空格等等。而UNIX和Windows操作系统中的外壳命令提示是不欢迎这些字符的,这些字符将被忽略。你应该根据不同的操作系统采用不用的方法。我一般使用带有QUERY选项的参数文件(PARFILE),利用PARFILE,可以不考虑操作系统平台而使用完全相同的方法。 </P> <P>下面给出一个例子。我用select * from all_objects建立了一个表T,我希望输出所有object_id 小于5000的行。在Windows中,必须这样做: </P> <P>C:\exp>exp userid=tkyte/tkyte tables=t </P> <P>query="""where object_id < 5000""" </P> <P>注意:在windows中,需要在WHERE语句的两端使用三个双引号。在UNIX中,必须这样做: </P> <P>$ exp userid=/ tables=t query=\"where </P> <P>object_id \< 5000\" </P> <P>exp userid=/ tables=t parfile=exp.par </P> <P>如果使用包含query="where object_id < 5000"的PARFILE文件,我可以在两个系统中使用相同的一个命令: </P> <P>exp userid=/ tables=t parfile=exp.par </P> <P>在两种操作系统中,完全相同。这相对于在不同的平台中使用不同的QUERY字符串容易多了。 </P> <P>问:DBMS_RANDOM </P> <P>您能否告诉我写一个能产生大于0小于1的随机数的随机数产生器的最好方法? </P> <P>答:Oracle8 8.0版介绍了DBMS_RANDOM包,Oracle8i 8.1.6版介绍了DBMS_RANDOM包的新功能,但Oracle8i 文档中没有详细全面介绍其功能。幸运的是:有一个新的DBMS_RANDOM包函数能够返回0-1之间的随机数。这个新函数是: </P> <P>FUNCTION value RETURN NUMBER; </P> <P>FUNCTION value (low IN NUMBER, high IN </P> <P>NUMBER) RETURN NUMBER; </P> <P>FUNCTION normal RETURN NUMBER; </P> <P>FUNCTION string (opt char, len NUMBER) </P> <P>RETURN VARCHAR2; </P> <P>VALUE函数的第一种形式返回一个大于或等于0且小于1的随机数;第二种形式返回一个大于或等于LOW,小于HIGH的随机数。下面是其用法的一个示例: </P> <P>SQL> select dbms_random.value, </P> <P>dbms_random.value(55,100) </P> <P>2 from dual; </P> <P>VALUE DBMS_RANDOM.VALUE(55,100) </P> <P>--------------- ----------------------------- </P> <P>.782821936 79.6367038 </P> <P>NORMAL函数返回服从正态分布的一组数。此正态分布标准偏差为1,期望值为0。这个函数返回的数值中有68%是介于-1与+1之间,95%介于-2与+2之间,99%介于-3与+3之间。事实上,这就是你在清单1中所看到的。 </P> <P>最后,是STRING函数。它返回一个长度达60个字符的随机字符串。参数OPT可以是清单2显示的值中的任何一个单个字符。 </P> <P>关于这些函数及DBMS_RANDOM包的文件都包含在SQLPlus中: </P> <P>select text </P> <P>from all_source </P> <P>where name = 'DBMS_RANDOM' </P> <P>and type = 'PACKAGE' order by line; </P> <P>问:连接次序与谓词求值 </P> <P>在下面的查询中,WHERE 语句的哪一部分先执行? </P> <P>Select field names from emp, dept </P> <P>where emp.dept_num = dept.num and </P> <P>emp.name Like 'S%' and dept.name='IT'; </P> <P>答:执行次序随已有的索引、统计、和session/init.ora参数的不同而变化。 </P> <P>假定已有一个建立在DEPT(name)和EMP(dept_num)上的索引。假定优化器认为DEPT是唯一的,它可能按下面的顺序进行操作: </P> <P>利用建立在DEPT(name)上的索引查找dept列 </P> <P>利用建立在EMP(dept_num)上的索引查找匹配的emp列(即连接emp.dept_num = dept.num) </P> <P>依据建立在emp.ename like 'S%'进行过滤 </P> <P>现在,我们假定没有建立在EMP(dept_num)上的索引,也没有建立在DEPT(name)上的索引,而存在建立在EMP(name)和DEPT(num)上的索引。优化器可能按下面的次序进行操作: </P> <P>利用建立在EMP(name)上的索引找到带有S的EMPS </P> <P>利用建立在DEPT(num)上的索引找到匹配项 <</P> |
|
|
3楼#
发布于:2005-09-18 01:09
/P>
<P>根据dept.name = 'IT'过滤结果 </P> <P>谓词求值的次序是不确定的,可以随时间的改变而改变,并由优化器决定。不要假定任何事情会按一定的次序发生。如果你那么做,随着时间的推移,你的应用程序可能会出现一些看起来非常奇怪的错误。看以下的例子:建立一个表,输入一些数据。当X='a’时,第二列的数据“Y”是一个数值,当X='b’时,“Y”不是数字。 </P> <P>SQL> create table t ( x varchar2(1), y varchar2(1) ); </P> <P>Table created. </P> <P>SQL> insert into t values ( 'a', '1' ); </P> <P>1 row created. </P> <P>SQL> insert into t values ( 'b', 'x' ); </P> <P>1 row created. </P> <P>现在根据这个表运行一个查询:查找满足x='a',y=1的行。 </P> <P>SQL> select * from t where x = 'a' and </P> <P>y = 1; </P> <P>ERROR: </P> <P>ORA-01722: invalid number </P> <P>no rows selected(错误,无效的数字,没有选择任何行) </P> <P>呦,没有成功。在这种情况下,数据库首先执行Y=1,当找到Y='X'的行后,很显然,它不能将'X'转换为一个数字,所以失败了。而下面的程序将给出不同的结果: </P> <P>SQL> analyze table t compute statistics; </P> <P>Table analyzed.(表已经分析过) </P> <P>SQL> select * from t where x = 'a' and </P> <P>y = 1; </P> <P>X Y </P> <P>- - </P> <P>a 1 </P> <P>使用不同的优化器模式,成功了!为什么?优化器说:“嘿,检查x= 'a'要比检查y=1来得快,因为在y=1中有一个将y从字符变为数字的转换。所以,我先检查x= 'a',然后再检查y=1。” </P> <P>这个例子说明谓词执行的次序可能是不确定的,你不能指望有一种特定的执行次序。也就是说,当你依靠一个隐含的转换时,必须非常谨慎。 </P> <P>问:显示SGA--fixed size(固定大小)与variable size(可变大小) </P> <P>当在svrmgr提示符下运行 “show SGA”时,fixed size和variable size是什么意思? </P> <P>答:fixed size就是SGA中固定组件(它在编译oracle 数据库本身时就固定于其中)的大小。它是固定大小的内存,用来指向SGA的其它部分。SGA这一部分的大小是不能改变的。 </P> <P>variable size指分配的内存块大小可变。SGA的可变块,分为共享池、大池、JAVA池、游标区和其他结构。</P> <DIV align=center>作者:丁诚等 </DIV> |
|
|